somehow c++ support and stuff.

This commit is contained in:
Felix Queißner 2015-08-13 17:23:11 +02:00
parent ddbfb0e1aa
commit ec533526df
13 changed files with 212 additions and 43 deletions

View file

@ -3,7 +3,7 @@ OBJS = $(addsuffix .o,$(basename $(SRCS)))
CC = gcc
CXX = g++
LD = ld
LD = g++
LEX=flex
YACC=bison
@ -11,10 +11,12 @@ YACC=bison
CFLAGS = -m32 -Dnullptr=0
ASFLAGS =
CCFLAGS = -g -std=c11 -Wall -g -fno-stack-protector -ffreestanding -Iinclude
CXXFLAGS = -g -std=c++11 -Wall -g -fno-stack-protector -fno-exceptions -ffreestanding -Wno-unused-function -Iinclude
LDFLAGS = -g -melf_i386 -Tkernel.ld
CXXFLAGS = -g -std=c++11 -Wall -g -fno-stack-protector -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -Wall -Wextra -ffreestanding -Wno-unused-function -Iinclude
LDFLAGS = -g -m32 -Tkernel.ld
kernel: $(OBJS) obj/tsvm.o obj/lex.yy.o obj/trainscript.tab.o
all: clean kernel
kernel: $(OBJS) obj/tsvm.o obj/lex.yy.o obj/trainscript.tab.o obj/vm.o
$(LD) $(LDFLAGS) -o $@ $(addprefix obj/, $(notdir $^))
%.o: %.c
@ -26,13 +28,16 @@ kernel: $(OBJS) obj/tsvm.o obj/lex.yy.o obj/trainscript.tab.o
%.o: %.cpp
$(CXX) $(CFLAGS) $(CXXFLAGS) -c -o $(addprefix obj/, $(notdir $@)) $^
obj/tsvm.o: trainscript/tsvm.cpp trainscript/tsvm.hpp trainscript/common.h
obj/vm.o: src/vm.cpp trainscript/tsvm.hpp
g++ $(CFLAGS) $(CXXFLAGS) -c src/vm.cpp -o obj/vm.o
obj/tsvm.o: trainscript/tsvm.cpp trainscript/tsvm.hpp
g++ $(CFLAGS) $(CXXFLAGS) -c trainscript/tsvm.cpp -o obj/tsvm.o
obj/lex.yy.o: trainscript/lex.yy.cpp trainscript/tsvm.hpp trainscript/common.h trainscript/trainscript.tab.cpp
obj/lex.yy.o: trainscript/lex.yy.cpp trainscript/tsvm.hpp
g++ $(CFLAGS) $(CXXFLAGS) -c trainscript/lex.yy.cpp -o obj/lex.yy.o
trainscript.tab.o: trainscript/lex.yy.cpp trainscript/trainscript.tab.cpp trainscript/tsvm.hpp trainscript/common.h
obj/trainscript.tab.o: trainscript/trainscript.tab.cpp trainscript/tsvm.hpp
g++ $(CFLAGS) $(CXXFLAGS) -c trainscript/trainscript.tab.cpp -o obj/trainscript.tab.o
trainscript/lex.yy.cpp: trainscript/trainscript.l
@ -41,8 +46,11 @@ trainscript/lex.yy.cpp: trainscript/trainscript.l
trainscript/trainscript.tab.cpp: trainscript/trainscript.y
$(YACC) -o trainscript/trainscript.tab.cpp -d trainscript/trainscript.y
obj/file01.o:
objcopy -I binary -O elf32-i386 --redefine-sym _binary_trainscript_file01_ts_start=file01_start --redefine-sym _binary_trainscript_file01_ts_end=file01_end --redefine-sym _binary_trainscript_file01_ts_size=file01_size trainscript/file01.ts obj/file01.o
clean:
rm $(addprefix obj/, $(notdir $(OBJS)))
rm obj/*.o
run:
qemu-system-i386 -kernel kernel

View file

@ -4,8 +4,8 @@
.extern init
// .global für Sichtbarkeit im Linker (invers zu static aus C)
.global _start
_start:
.global _trainOS_start
_trainOS_start:
// Init stack
mov $kernel_stack, %esp

View file

@ -2,12 +2,12 @@
#include <inttypes.h>
inline void* operator new(size_t size, void* __p)
inline void* operator new(size_t, void* __p)
{
return __p;
}
inline void* operator new[](size_t size, void* __p)
inline void* operator new[](size_t, void* __p)
{
return __p;
}

View file

@ -18,6 +18,29 @@ namespace ker
}
String(const String &other) :
String(other.mText, other.mLength)
{
}
String(String &&other) :
mText(other.mText),
mLength(other.mLength)
{
other.mText = nullptr;
other.mLength = 0;
}
String & operator = (const String &other)
{
free(this->mText);
this->mLength = other.mLength;
this->mText = (uint8_t*)malloc(this->mLength + 1);
memcpy(this->mText, other.mText, this->mLength + 1);
}
String(const char *text) :
mText(nullptr),
mLength(0)
@ -25,18 +48,22 @@ namespace ker
this->mLength = strlen(text);
this->mText = (uint8_t*)malloc(this->mLength + 1);
memcpy(this->mText, text, this->mLength);
this->mText[this->mLength] = 0;
}
String(const uint8_t *bytes, size_t length) :
mText((uint8_t*)malloc(length)),
mText((uint8_t*)malloc(length + 1)),
mLength(length)
{
memcpy(this->mText, bytes, length);
this->mText[this->mLength] = 0; // last byte is always 0
}
~String()
{
if(this->mText != nullptr) {
free(this->mText);
}
}
size_t length() const

View file

@ -1,5 +1,7 @@
/* Bei _start soll die Ausfuehrung losgehen */
ENTRY(_start)
ENTRY(_trainOS_start)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
/*
* Hier wird festgelegt, in welcher Reihenfolge welche Sektionen in die Binary
@ -24,6 +26,11 @@ SECTIONS
*(.text)
}
.data ALIGN(4096) : {
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.rodata ALIGN(4096) : {

View file

@ -1,5 +1,6 @@
#include <stdlib.h>
#include <console.h>
#include <inttypes.h>
#include <ker/new.hpp>
@ -22,3 +23,47 @@ void operator delete[]( void *obj )
{
free( obj );
}
extern "C" void __cxa_pure_virtual()
{
kprintf("Pure virtual function call.\n");
}
extern "C" int *__errno_location()
{
static int errno;
return &errno;
}
extern "C" int fprintf ( void * , const char * , ... )
{
kprintf("[some fprintf :P]");
return 0;
}
extern "C"
{
void *stdin, *stdout, *stderr;
}
// Lizenz: public domain
typedef void (*constructor)();
// Im Linkerskript definiert
extern "C" constructor start_ctors;
extern "C" constructor end_ctors;
extern "C" void initialiseConstructors();
// Ruft die Konstruktoren für globale/statische Objekte auf
void initialiseConstructors()
{
for (constructor* i = &start_ctors;i != &end_ctors;++i)
(*i)();
}
extern "C" void cpp_init()
{
initialiseConstructors();
}

View file

@ -94,10 +94,7 @@ static void dumpMB(const MultibootStructure *mbHeader)
// TODO: MB_APS_TABLE
}
void cpp_init()
{
}
void cpp_init();
void putsuccess()
{
@ -106,6 +103,8 @@ void putsuccess()
kputs("[success]");
}
extern void vm_start();
void init(const MultibootStructure *mbHeader)
{
(void)debug_test;
@ -151,9 +150,22 @@ void init(const MultibootStructure *mbHeader)
cpp_init();
putsuccess();
vm_start();
while(1)
{
kputs("x");
sleep(1);
}
}
int main(int argc, char **argv)
{
while(1) {
kputs("x");
}
return 0;
}
void __init_array_start() { }
void __init_array_end() { }

View file

@ -85,6 +85,19 @@ int atoi(const char *str)
return res;
}
float atof(const char *str)
{
// HACK: Implement
return 42.0f;
}
double atod(const char *str)
{
// HACK: Implement
return 42.0;
}
void *memmove( void *destination, const void *source, size_t num)
{
// TODO: Implement memmove

52
src/vm.cpp Normal file
View file

@ -0,0 +1,52 @@
#include <stdlib.h>
#include "../trainscript/tsvm.hpp"
using namespace ker;
using namespace trainscript;
extern "C" {
// extern const char file01_start;
// extern const char file01_end;
// extern size_t file01_size;
}
char file01[] = "VAR global : INT;\0";
String fn()
{
return String("keks");
}
extern "C" void vm_start()
{
kprintf("Testing ker::String:\n");
{
String a("hello");
String b(a);
String c;
String d(fn());
String e;
c = a;
e = fn();
kprintf("'%s' '%s' '%s' '%s' '%s'\n", a.str(), b.str(), c.str(), d.str(), e.str());
}
kprintf("Parse kernel module:");
Module *module = VM::load(file01, sizeof(file01));
if(module == nullptr) {
kprintf("Could not load module :(\n");
return;
}
kprintf("Module successfully loaded :)\n");
for(const auto &var : module->variables)
{
kprintf("Variable: '%s' => '");
var.second->printval();
kprintf("\n");
}
}

View file

@ -14,7 +14,8 @@ SOURCES += \
trainscript/tsvm.cpp \
trainscript/main.cpp \
src/timer.c \
src/cplusplus.cpp
src/cplusplus.cpp \
src/vm.cpp
HEADERS += \
include/console.h \
@ -49,7 +50,8 @@ DISTFILES += \
trainscript/file01.ts \
trainscript/Makefile \
trainscript/trainscript.y \
trainscript/file02.ts
trainscript/file02.ts \
kernel.ld
QMAKE_INCDIR =

View file

@ -144,7 +144,8 @@ void yyerror(void *scanner, const char *s);
input:
%empty
| input variableDeclaration SEMICOLON {
context->module->variables.insert( { $2.name, new Variable($2.variable) } );
auto *var = new Variable($2.variable);
context->module->variables.add( ker::String($2.name), var );
}
| input method {
using namespace trainscript;
@ -153,22 +154,22 @@ input:
Method *method = new Method(mod, $2.body);
method->isPublic = $2.header.isPublic;
if($2.header.returnValue) {
method->returnValue = std::pair<std::string, Variable>(
method->returnValue = ker::Pair<ker::String, Variable>(
$2.header.returnValue->name,
$2.header.returnValue->variable);
}
LocalVariable *local = $2.header.locals;
while(local) {
method->locals.insert( { local->name, local->variable } );
method->locals.add( local->name, local->variable );
local = local->next;
}
LocalVariable *arg = $2.header.arguments;
while(arg) {
method->arguments.push_back( { arg->name, arg->variable } );
method->arguments.append( { arg->name, arg->variable } );
arg = arg->next;
}
context->module->methods.insert( { $2.header.name, method } );
context->module->methods.add( $2.header.name, method );
}
;
@ -185,7 +186,7 @@ block:
MethodBody *mb = $2;
while(mb) {
if(mb->instruction != nullptr) {
block->instructions.push_back(mb->instruction);
block->instructions.append(mb->instruction);
}
mb = mb->next;
}
@ -335,7 +336,7 @@ expression:
auto *call = new MethodInvokeExpression($1);
auto *list = $3;
while(list) {
call->parameters.push_back(list->instruction);
call->parameters.append(list->instruction);
list = list->next;
}
$$ = call;

View file

@ -21,12 +21,12 @@ namespace trainscript
const Type Type::Text = { TypeID::Text, 0 };
const Type Type::Boolean = { TypeID::Bool, 0 };
const Variable Variable::Invalid = { Type::Invalid };
const Variable Variable::Void = { Type::Void };
const Variable Variable::Int = { Type::Int };
const Variable Variable::Real = { Type::Real };
const Variable Variable::Text = { Type::Text };
const Variable Variable::Boolean = { Type::Boolean };
const Variable Variable::Invalid = { Type::Invalid, 0 };
const Variable Variable::Void = { Type::Void, 0 };
const Variable Variable::Int = { Type::Int, 0 };
const Variable Variable::Real = { Type::Real, 0 };
const Variable Variable::Text = { Type::Text, 0 };
const Variable Variable::Boolean = { Type::Boolean, 0 };
Module *VM::load(const void *buffer, size_t length)
{
@ -42,7 +42,9 @@ namespace trainscript
data.module = module;
yylex_init_extra(&data, &data.scanner);
bool valid = yyparse(&data) == 0;
int error = yyparse(&data);
kprintf("[E:%d]", error);
bool valid = error == 0;
yylex_destroy(data.scanner);
free(internalStorage);