somehow c++ support and stuff.
This commit is contained in:
parent
ddbfb0e1aa
commit
ec533526df
13 changed files with 212 additions and 43 deletions
24
Makefile
24
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ker
|
|||
}
|
||||
|
||||
bool contains(const Key &key) const
|
||||
{
|
||||
{
|
||||
for(const auto &pair : this->contents)
|
||||
{
|
||||
if(pair.first == key) {
|
||||
|
@ -51,7 +51,7 @@ namespace ker
|
|||
}
|
||||
|
||||
void add(const Key &key, const Value &value)
|
||||
{
|
||||
{
|
||||
if(this->contains(key)) {
|
||||
for(auto &&pair : this->contents)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -18,25 +18,52 @@ 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)
|
||||
{
|
||||
this->mLength = strlen(text);
|
||||
this->mText = (uint8_t*)malloc(this->mLength + 1);
|
||||
memcpy(this->mText, text, this->mLength);
|
||||
{
|
||||
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);
|
||||
memcpy(this->mText, bytes, length);
|
||||
this->mText[this->mLength] = 0; // last byte is always 0
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
free(this->mText);
|
||||
if(this->mText != nullptr) {
|
||||
free(this->mText);
|
||||
}
|
||||
}
|
||||
|
||||
size_t length() const
|
||||
|
|
|
@ -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) : {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <console.h>
|
||||
#include <inttypes.h>
|
||||
#include <ker/new.hpp>
|
||||
|
||||
void *operator new( size_t size )
|
||||
{
|
||||
return calloc( size );
|
||||
return calloc( size );
|
||||
}
|
||||
|
||||
void *operator new[]( size_t size )
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
20
src/init.c
20
src/init.c
|
@ -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() { }
|
||||
|
|
13
src/stdlib.c
13
src/stdlib.c
|
@ -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
52
src/vm.cpp
Normal 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");
|
||||
}
|
||||
}
|
|
@ -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 =
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue