Refactors type system: Types now provide operators instead of prebuilt ones. Known bug: Second parameter gets lost.
This commit is contained in:
parent
996bef56a6
commit
2e858d8d91
11 changed files with 306 additions and 206 deletions
5
Depfile
5
Depfile
|
@ -2,7 +2,9 @@
|
||||||
Artifact=kernel
|
Artifact=kernel
|
||||||
TempDir=obj
|
TempDir=obj
|
||||||
SourceDir=asm src
|
SourceDir=asm src
|
||||||
Files=trainscript/trainscript.y trainscript/trainscript.l trainscript/tsvm.cpp trainscript/variable.cpp
|
Files=trainscript/trainscript.y trainscript/trainscript.l
|
||||||
|
Files=trainscript/tsvm.cpp trainscript/variable.cpp trainscript/type.cpp
|
||||||
|
Files=trainscript/type-operators.cpp.tt
|
||||||
AdditionalObjects=obj/main.o
|
AdditionalObjects=obj/main.o
|
||||||
|
|
||||||
LexUseCpp
|
LexUseCpp
|
||||||
|
@ -15,6 +17,7 @@ CXX=g++
|
||||||
LD=g++
|
LD=g++
|
||||||
LEX=flex
|
LEX=flex
|
||||||
YACC=bison
|
YACC=bison
|
||||||
|
TEMPLE=mono /home/felix/projects/temple/bin/Debug/temple.exe
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
FLAGS=-m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
FLAGS=-m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
||||||
|
|
31
Makefile
31
Makefile
|
@ -8,12 +8,13 @@ CXX = g++
|
||||||
LD = g++
|
LD = g++
|
||||||
LEX = flex
|
LEX = flex
|
||||||
YACC = bison
|
YACC = bison
|
||||||
|
TEMPLE = mono /home/felix/projects/temple/bin/Debug/temple.exe
|
||||||
|
|
||||||
# File Lists
|
# File Lists
|
||||||
SRCS_AS = asm/dynamic.S asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
SRCS_AS = asm/dynamic.S asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
||||||
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/serial.c src/stdlib.c src/timer.c src/vmm.c
|
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/serial.c src/stdlib.c src/timer.c src/vmm.c
|
||||||
SRCS_CXX = trainscript/tsvm.cpp trainscript/variable.cpp src/cplusplus.cpp src/vm.cpp obj/trainscript.yy.cpp obj/trainscript.tab.cpp
|
SRCS_CXX = trainscript/tsvm.cpp trainscript/variable.cpp trainscript/type.cpp src/cplusplus.cpp src/vm.cpp obj/trainscript.yy.cpp obj/trainscript.tab.cpp obj/type-operators.cpp
|
||||||
OBJS = obj/tsvm.o obj/variable.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
OBJS = obj/tsvm.o obj/variable.o obj/type.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/type-operators.o obj/main.o
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
FLAGS = -m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
FLAGS = -m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
||||||
|
@ -27,10 +28,10 @@ all: kernel
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) obj/trainscript.yy.cpp obj/trainscript.tab.cpp obj/tsvm.o obj/variable.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
$(RM) obj/trainscript.yy.cpp obj/trainscript.tab.cpp obj/type-operators.cpp obj/tsvm.o obj/variable.o obj/type.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/type-operators.o obj/main.o
|
||||||
|
|
||||||
kernel: obj/tsvm.o obj/variable.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
kernel: obj/tsvm.o obj/variable.o obj/type.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/type-operators.o obj/main.o
|
||||||
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/tsvm.o obj/variable.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/tsvm.o obj/variable.o obj/type.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/type-operators.o obj/main.o
|
||||||
|
|
||||||
# src/console.c
|
# src/console.c
|
||||||
obj/console.o: src/console.c include/console.h include/stdlib.h \
|
obj/console.o: src/console.c include/console.h include/stdlib.h \
|
||||||
|
@ -97,12 +98,19 @@ obj/tsvm.o: trainscript/tsvm.cpp include/stdlib.h include/varargs.h \
|
||||||
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/tsvm.cpp
|
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/tsvm.cpp
|
||||||
|
|
||||||
# trainscript/variable.cpp
|
# trainscript/variable.cpp
|
||||||
obj/variable.o: trainscript/variable.cpp include/kernel.h \
|
obj/variable.o: trainscript/variable.cpp include/kernel.h include/console.h \
|
||||||
trainscript/variable.hpp trainscript/type.hpp trainscript/types.hpp \
|
trainscript/variable.hpp trainscript/type.hpp trainscript/types.hpp \
|
||||||
include/ker/string.hpp include/stdlib.h include/varargs.h \
|
include/ker/string.hpp include/stdlib.h include/varargs.h \
|
||||||
include/config.h include/malloc.h trainscript/typeid.hpp
|
include/config.h include/malloc.h trainscript/typeid.hpp
|
||||||
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/variable.cpp
|
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/variable.cpp
|
||||||
|
|
||||||
|
# trainscript/type.cpp
|
||||||
|
obj/type.o: trainscript/type.cpp include/kernel.h include/console.h \
|
||||||
|
trainscript/type.hpp trainscript/types.hpp include/ker/string.hpp \
|
||||||
|
include/stdlib.h include/varargs.h include/config.h include/malloc.h \
|
||||||
|
trainscript/typeid.hpp trainscript/variable.hpp
|
||||||
|
$(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/type.cpp
|
||||||
|
|
||||||
# src/cplusplus.cpp
|
# src/cplusplus.cpp
|
||||||
obj/cplusplus.o: src/cplusplus.cpp include/stdlib.h include/varargs.h \
|
obj/cplusplus.o: src/cplusplus.cpp include/stdlib.h include/varargs.h \
|
||||||
include/config.h include/malloc.h include/console.h include/ker/new.hpp
|
include/config.h include/malloc.h include/console.h include/ker/new.hpp
|
||||||
|
@ -149,6 +157,14 @@ obj/trainscript.tab.o: obj/trainscript.tab.cpp include/stdlib.h \
|
||||||
trainscript/trainscript.l.h include/string.h
|
trainscript/trainscript.l.h include/string.h
|
||||||
$(CXX) -iquotetrainscript -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.tab.cpp
|
$(CXX) -iquotetrainscript -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.tab.cpp
|
||||||
|
|
||||||
|
# obj/type-operators.cpp
|
||||||
|
obj/type-operators.o: obj/type-operators.cpp include/kernel.h \
|
||||||
|
include/console.h trainscript/type.hpp trainscript/types.hpp \
|
||||||
|
include/ker/string.hpp include/stdlib.h include/varargs.h \
|
||||||
|
include/config.h include/malloc.h trainscript/typeid.hpp \
|
||||||
|
trainscript/variable.hpp
|
||||||
|
$(CXX) -iquotetrainscript -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c obj/type-operators.cpp
|
||||||
|
|
||||||
# asm/dynamic.S
|
# asm/dynamic.S
|
||||||
obj/dynamic.o: asm/dynamic.S
|
obj/dynamic.o: asm/dynamic.S
|
||||||
$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c asm/dynamic.S
|
$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c asm/dynamic.S
|
||||||
|
@ -171,6 +187,9 @@ obj/trainscript.yy.cpp: trainscript/trainscript.l
|
||||||
obj/trainscript.tab.cpp: trainscript/trainscript.y
|
obj/trainscript.tab.cpp: trainscript/trainscript.y
|
||||||
$(YACC) -o obj/trainscript.tab.cpp -d trainscript/trainscript.y
|
$(YACC) -o obj/trainscript.tab.cpp -d trainscript/trainscript.y
|
||||||
|
|
||||||
|
obj/type-operators.cpp: trainscript/type-operators.cpp.tt
|
||||||
|
$(TEMPLE) trainscript/type-operators.cpp.tt obj/type-operators.cpp
|
||||||
|
|
||||||
# Custom Targets
|
# Custom Targets
|
||||||
obj/main.o: scripts/main.ts
|
obj/main.o: scripts/main.ts
|
||||||
objcopy -B i386 -I binary -O elf32-i386 \
|
objcopy -B i386 -I binary -O elf32-i386 \
|
||||||
|
|
|
@ -17,7 +17,8 @@ SOURCES += \
|
||||||
src/cplusplus.cpp \
|
src/cplusplus.cpp \
|
||||||
src/vm.cpp \
|
src/vm.cpp \
|
||||||
src/serial.c \
|
src/serial.c \
|
||||||
trainscript/variable.cpp
|
trainscript/variable.cpp \
|
||||||
|
trainscript/type.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
include/console.h \
|
include/console.h \
|
||||||
|
@ -72,7 +73,8 @@ DISTFILES += \
|
||||||
Makefile.new \
|
Makefile.new \
|
||||||
scripts/main.ts \
|
scripts/main.ts \
|
||||||
asm/dynamic.S \
|
asm/dynamic.S \
|
||||||
README.md
|
README.md \
|
||||||
|
trainscript/type-operators.cpp.tt
|
||||||
|
|
||||||
QMAKE_INCDIR =
|
QMAKE_INCDIR =
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace trainscript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Variable value;
|
Variable value;
|
||||||
ConstantExpression(Variable value) : value(value) { }
|
ConstantExpression(const Variable &value) : value(value) { }
|
||||||
|
|
||||||
Variable execute(ExecutionContext &) const override {
|
Variable execute(ExecutionContext &) const override {
|
||||||
return this->value;
|
return this->value;
|
||||||
|
@ -179,7 +179,7 @@ namespace trainscript
|
||||||
ker::Vector<Variable> vars(this->parameters.length());
|
ker::Vector<Variable> vars(this->parameters.length());
|
||||||
vars.resize(this->parameters.length());
|
vars.resize(this->parameters.length());
|
||||||
for(size_t i = 0; i < vars.length(); i++) {
|
for(size_t i = 0; i < vars.length(); i++) {
|
||||||
vars[i] = this->parameters.at(i)->execute(context);
|
vars[i].replace(this->parameters.at(i)->execute(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
return method->invoke(vars);
|
return method->invoke(vars);
|
||||||
|
@ -218,14 +218,15 @@ namespace trainscript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Variable (*OP)(Variable, Variable)>
|
|
||||||
class ArithmeticExpression :
|
class ArithmeticExpression :
|
||||||
public Instruction
|
public Instruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Operation op;
|
||||||
Instruction *lhs, *rhs;
|
Instruction *lhs, *rhs;
|
||||||
|
|
||||||
ArithmeticExpression(Instruction *lhs, Instruction *rhs) :
|
ArithmeticExpression(Instruction *lhs, Instruction *rhs, Operation op) :
|
||||||
|
op(op),
|
||||||
lhs(lhs),
|
lhs(lhs),
|
||||||
rhs(rhs)
|
rhs(rhs)
|
||||||
{
|
{
|
||||||
|
@ -247,7 +248,11 @@ namespace trainscript
|
||||||
die("ArithmeticExpression.TypeMismatch");
|
die("ArithmeticExpression.TypeMismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable result = OP(left, right);
|
if(left.type().hasOperator(this->op) == false) {
|
||||||
|
die_extra("ArithmeticExpression.InvalidOperator", "The operator was not defined for this type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable result = left.type().apply(left, this->op, right);
|
||||||
|
|
||||||
if(result.type().usable() == false) {
|
if(result.type().usable() == false) {
|
||||||
die_extra("ArithmeticExpression.InvalidResult", result.type().name());
|
die_extra("ArithmeticExpression.InvalidResult", result.type().name());
|
||||||
|
@ -280,6 +285,11 @@ namespace trainscript
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(lhsType.hasOperator(this->op) == false) {
|
||||||
|
errorCode = "The operator is not defined for this type.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(this->lhs->validate(context, errorCode) == false)
|
if(this->lhs->validate(context, errorCode) == false)
|
||||||
return false;
|
return false;
|
||||||
if(this->rhs->validate(context, errorCode) == false)
|
if(this->rhs->validate(context, errorCode) == false)
|
||||||
|
|
|
@ -9,23 +9,6 @@
|
||||||
|
|
||||||
using namespace trainscript;
|
using namespace trainscript;
|
||||||
|
|
||||||
namespace trainscript {
|
|
||||||
namespace ops {
|
|
||||||
Variable add(Variable lhs, Variable rhs);
|
|
||||||
Variable subtract(Variable lhs, Variable rhs);
|
|
||||||
Variable multiply(Variable lhs, Variable rhs);
|
|
||||||
Variable divide(Variable lhs, Variable rhs);
|
|
||||||
Variable modulo(Variable lhs, Variable rhs);
|
|
||||||
|
|
||||||
Variable equals(Variable lhs, Variable rhs);
|
|
||||||
Variable inequals(Variable lhs, Variable rhs);
|
|
||||||
Variable less(Variable lhs, Variable rhs);
|
|
||||||
Variable lessEqual(Variable lhs, Variable rhs);
|
|
||||||
Variable greater(Variable lhs, Variable rhs);
|
|
||||||
Variable greaterEqual(Variable lhs, Variable rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
|
||||||
// stuff from flex that bison needs to know about:
|
// stuff from flex that bison needs to know about:
|
||||||
|
@ -162,12 +145,16 @@ input:
|
||||||
LocalVariable *local = $2.header.locals;
|
LocalVariable *local = $2.header.locals;
|
||||||
while(local) {
|
while(local) {
|
||||||
method->mLocals.add( local->name, local->type );
|
method->mLocals.add( local->name, local->type );
|
||||||
|
LocalVariable *tmp = local;
|
||||||
local = local->next;
|
local = local->next;
|
||||||
|
delete tmp;
|
||||||
}
|
}
|
||||||
LocalVariable *arg = $2.header.arguments;
|
LocalVariable *arg = $2.header.arguments;
|
||||||
while(arg) {
|
while(arg) {
|
||||||
method->mArguments.append( { arg->name, arg->type} );
|
method->mArguments.append( { arg->name, arg->type} );
|
||||||
|
LocalVariable *tmp = local;
|
||||||
arg = arg->next;
|
arg = arg->next;
|
||||||
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->module->methods.add( $2.header.name, method );
|
context->module->methods.add( $2.header.name, method );
|
||||||
|
@ -189,7 +176,9 @@ block:
|
||||||
if(mb->instruction != nullptr) {
|
if(mb->instruction != nullptr) {
|
||||||
block->instructions.append(mb->instruction);
|
block->instructions.append(mb->instruction);
|
||||||
}
|
}
|
||||||
|
MethodBody *tmp = mb;
|
||||||
mb = mb->next;
|
mb = mb->next;
|
||||||
|
delete mb;
|
||||||
}
|
}
|
||||||
$$ = block;
|
$$ = block;
|
||||||
}
|
}
|
||||||
|
@ -342,17 +331,17 @@ expression:
|
||||||
$$ = call;
|
$$ = call;
|
||||||
}
|
}
|
||||||
| LBRACKET expression RBRACKET { $$ = $2; }
|
| LBRACKET expression RBRACKET { $$ = $2; }
|
||||||
| expression PLUS expression { $$ = new ArithmeticExpression<trainscript::ops::add>($1, $3); }
|
| expression PLUS expression { $$ = new ArithmeticExpression($1, $3, Operation::Add); }
|
||||||
| expression MINUS expression { $$ = new ArithmeticExpression<trainscript::ops::subtract>($1, $3); }
|
| expression MINUS expression { $$ = new ArithmeticExpression($1, $3, Operation::Subtract); }
|
||||||
| expression MULTIPLY expression { $$ = new ArithmeticExpression<trainscript::ops::multiply>($1, $3); }
|
| expression MULTIPLY expression { $$ = new ArithmeticExpression($1, $3, Operation::Multiply); }
|
||||||
| expression DIVIDE expression { $$ = new ArithmeticExpression<trainscript::ops::divide>($1, $3); }
|
| expression DIVIDE expression { $$ = new ArithmeticExpression($1, $3, Operation::Divide); }
|
||||||
| expression MODULO expression { $$ = new ArithmeticExpression<trainscript::ops::modulo>($1, $3); }
|
| expression MODULO expression { $$ = new ArithmeticExpression($1, $3, Operation::Modulo); }
|
||||||
| expression OP_LT expression { $$ = new ArithmeticExpression<trainscript::ops::less>($1, $3); }
|
| expression OP_LT expression { $$ = new ArithmeticExpression($1, $3, Operation::Less); }
|
||||||
| expression OP_LE expression { $$ = new ArithmeticExpression<trainscript::ops::lessEqual>($1, $3); }
|
| expression OP_LE expression { $$ = new ArithmeticExpression($1, $3, Operation::LessEquals); }
|
||||||
| expression OP_GT expression { $$ = new ArithmeticExpression<trainscript::ops::greater>($1, $3); }
|
| expression OP_GT expression { $$ = new ArithmeticExpression($1, $3, Operation::Greater); }
|
||||||
| expression OP_GE expression { $$ = new ArithmeticExpression<trainscript::ops::greaterEqual>($1, $3); }
|
| expression OP_GE expression { $$ = new ArithmeticExpression($1, $3, Operation::GreaterEquals); }
|
||||||
| expression OP_EQ expression { $$ = new ArithmeticExpression<trainscript::ops::equals>($1, $3); }
|
| expression OP_EQ expression { $$ = new ArithmeticExpression($1, $3, Operation::Equals); }
|
||||||
| expression OP_NEQ expression { $$ = new ArithmeticExpression<trainscript::ops::inequals>($1, $3); }
|
| expression OP_NEQ expression { $$ = new ArithmeticExpression($1, $3, Operation::Inequals); }
|
||||||
| expression RARROW IDENTIFIER { $$ = new VariableAssignmentExpression($3, $1); }
|
| expression RARROW IDENTIFIER { $$ = new VariableAssignmentExpression($3, $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -384,12 +373,12 @@ variableDeclaration:
|
||||||
;
|
;
|
||||||
|
|
||||||
typeName:
|
typeName:
|
||||||
KW_VOID { $$.id = TypeID::Void; $$.pointer = 0; }
|
KW_VOID { $$ = Type::Void; }
|
||||||
| KW_INT { $$.id = TypeID::Int; $$.pointer = 0; }
|
| KW_INT { $$ = Type::Int; }
|
||||||
| KW_REAL { $$.id = TypeID::Real; $$.pointer = 0; }
|
| KW_REAL { $$ = Type::Real; }
|
||||||
| KW_TEXT { $$.id = TypeID::Text; $$.pointer = 0; }
|
| KW_TEXT { $$ = Type::Text; }
|
||||||
| KW_BOOL { $$.id = TypeID::Bool; $$.pointer = 0; }
|
| KW_BOOL { $$ = Type::Bool; }
|
||||||
| KW_PTR LBRACKET typeName RBRACKET { $$ = $3; $$.pointer++; }
|
| KW_PTR LBRACKET typeName RBRACKET { $$ = $3.reference(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -10,20 +10,6 @@
|
||||||
|
|
||||||
namespace trainscript
|
namespace trainscript
|
||||||
{
|
{
|
||||||
const Type Type::Invalid = { TypeID::Invalid, 0 };
|
|
||||||
const Type Type::Void = { TypeID::Void, 0 };
|
|
||||||
const Type Type::Int = { TypeID::Int, 0 };
|
|
||||||
const Type Type::Real = { TypeID::Real, 0 };
|
|
||||||
const Type Type::Text = { TypeID::Text, 0 };
|
|
||||||
const Type Type::Bool = { TypeID::Bool, 0 };
|
|
||||||
|
|
||||||
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::Bool = { Type::Bool, 0 };
|
|
||||||
|
|
||||||
bool Module::validate(ker::String &errorCode) const
|
bool Module::validate(ker::String &errorCode) const
|
||||||
{
|
{
|
||||||
errorCode = "";
|
errorCode = "";
|
||||||
|
@ -177,124 +163,4 @@ namespace trainscript
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ops
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Variable add(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int:return mkvar(lhs.integer + rhs.integer);
|
|
||||||
case TypeID::Real: return mkvar(lhs.real + rhs.real);
|
|
||||||
default: kprintf("addition not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable subtract(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkvar(lhs.integer - rhs.integer);
|
|
||||||
case TypeID::Real:return mkvar(lhs.real - rhs.real);
|
|
||||||
default: kprintf("subtraction not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable multiply(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkvar(lhs.integer * rhs.integer);
|
|
||||||
case TypeID::Real: return mkvar(lhs.real * rhs.real);
|
|
||||||
default: kprintf("multiplication not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable divide(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkvar(lhs.integer / rhs.integer);
|
|
||||||
case TypeID::Real: return mkvar(lhs.real / rhs.real);
|
|
||||||
default: kprintf("division not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable modulo(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkvar(lhs.integer % rhs.integer);
|
|
||||||
// case TypeID::Real: mkvar(lhs.real % rhs.real);
|
|
||||||
default: kprintf("modulo not supported for %s.\n", lhs.type.name()); return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable equals(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer == rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real == rhs.real);
|
|
||||||
case TypeID::Bool: return mkbool(lhs.boolean == rhs.boolean);
|
|
||||||
default:
|
|
||||||
kprintf("equals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable inequals(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer != rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real != rhs.real);
|
|
||||||
case TypeID::Bool: return mkbool(lhs.boolean != rhs.boolean);
|
|
||||||
default:
|
|
||||||
kprintf("inequals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Variable less(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer < rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real < rhs.real);
|
|
||||||
default:
|
|
||||||
kprintf("equals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable lessEqual(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer <= rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real <= rhs.real);
|
|
||||||
default:
|
|
||||||
kprintf("equals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable greater(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer > rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real > rhs.real);
|
|
||||||
default:
|
|
||||||
kprintf("equals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable greaterEqual(Variable lhs, Variable rhs)
|
|
||||||
{
|
|
||||||
switch(lhs.type.id) {
|
|
||||||
case TypeID::Int: return mkbool(lhs.integer >= rhs.integer);
|
|
||||||
case TypeID::Real: return mkbool(lhs.real >= rhs.real);
|
|
||||||
default:
|
|
||||||
kprintf("equals not supported for %s.\n", lhs.type.name());
|
|
||||||
return Variable::Invalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
89
trainscript/type-operators.cpp.tt
Normal file
89
trainscript/type-operators.cpp.tt
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include "type.hpp"
|
||||||
|
#include "variable.hpp"<?
|
||||||
|
ops = {
|
||||||
|
{ "add" },
|
||||||
|
{ "subtract" },
|
||||||
|
{ "multiply" },
|
||||||
|
{ "divide" },
|
||||||
|
{ "modulo" },
|
||||||
|
{ "lt", "Bool" },
|
||||||
|
{ "le", "Bool" },
|
||||||
|
{ "gt", "Bool" },
|
||||||
|
{ "ge", "Bool" },
|
||||||
|
{ "eq", "Bool" },
|
||||||
|
{ "ieq", "Bool" },
|
||||||
|
}
|
||||||
|
types = {
|
||||||
|
Invalid = { }, -- no operators at all, all nil
|
||||||
|
Int = {
|
||||||
|
add = "+",
|
||||||
|
subtract = "-",
|
||||||
|
multiply = "*",
|
||||||
|
divide = "/",
|
||||||
|
modulo = "%",
|
||||||
|
lt = "<",
|
||||||
|
le = "<=",
|
||||||
|
gt = ">",
|
||||||
|
ge = ">=",
|
||||||
|
eq = "==",
|
||||||
|
ieq = "!="
|
||||||
|
},
|
||||||
|
Real = {
|
||||||
|
add = "+",
|
||||||
|
subtract = "-",
|
||||||
|
multiply = "*",
|
||||||
|
divide = "/",
|
||||||
|
lt = "<",
|
||||||
|
le = "<=",
|
||||||
|
gt = ">",
|
||||||
|
ge = ">=",
|
||||||
|
eq = "==",
|
||||||
|
ieq = "!="
|
||||||
|
},
|
||||||
|
Bool = {
|
||||||
|
add = "||",
|
||||||
|
multiply = "&&",
|
||||||
|
eq = "==",
|
||||||
|
ieq = "!="
|
||||||
|
},
|
||||||
|
Text = {
|
||||||
|
add = "+",
|
||||||
|
eq = "==",
|
||||||
|
ieq = "!="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
namespace trainscript
|
||||||
|
{
|
||||||
|
<? for type,desc in pairs(types) do
|
||||||
|
for _, _op in ipairs(ops) do
|
||||||
|
local op = _op[1]
|
||||||
|
local rt = _op[2] or type
|
||||||
|
if desc[op] then
|
||||||
|
local name = type .. "_" .. op;
|
||||||
|
local sign = desc[op];
|
||||||
|
?>static Variable <[name]>(const Variable &lhs, const Variable &rhs)
|
||||||
|
{
|
||||||
|
return Variable::from<[rt]>(lhs.value<<[type]>>() <[sign]> rhs.value<<[type]>>());
|
||||||
|
}
|
||||||
|
<? end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for type,desc in pairs(types) do ?>
|
||||||
|
TypeOps <[type]>Operators = {<?
|
||||||
|
for _, _op in ipairs(ops) do
|
||||||
|
local op = _op[1] ?>
|
||||||
|
<?
|
||||||
|
if desc[op] == nil then
|
||||||
|
?>nullptr,<?
|
||||||
|
else
|
||||||
|
?><[type]>_<[op]>,<?
|
||||||
|
end
|
||||||
|
end ?>
|
||||||
|
};<? end ?>
|
||||||
|
}
|
||||||
|
|
41
trainscript/type.cpp
Normal file
41
trainscript/type.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include "type.hpp"
|
||||||
|
#include "variable.hpp"
|
||||||
|
|
||||||
|
namespace trainscript
|
||||||
|
{
|
||||||
|
extern TypeOps InvalidOperators;
|
||||||
|
extern TypeOps IntOperators;
|
||||||
|
extern TypeOps RealOperators;
|
||||||
|
extern TypeOps TextOperators;
|
||||||
|
extern TypeOps BoolOperators;
|
||||||
|
|
||||||
|
const Type Type::Invalid = { TypeID::Invalid, 0, &InvalidOperators };
|
||||||
|
const Type Type::Void = { TypeID::Void, 0, &InvalidOperators };
|
||||||
|
const Type Type::Int = { TypeID::Int, 0, &IntOperators };
|
||||||
|
const Type Type::Real = { TypeID::Real, 0, &RealOperators };
|
||||||
|
const Type Type::Text = { TypeID::Text, 0, &TextOperators };
|
||||||
|
const Type Type::Bool = { TypeID::Bool, 0, &BoolOperators };
|
||||||
|
|
||||||
|
bool Type::hasOperator(Operation op) const
|
||||||
|
{
|
||||||
|
return this->operators->ops[(int)op] != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable Type::apply(const Variable &lhs, Operation op, const Variable &rhs) const
|
||||||
|
{
|
||||||
|
if(this->hasOperator(op) == false) {
|
||||||
|
kprintf("[invalid op: apply %d to %s]", (int)op, this->name());
|
||||||
|
return Variable::Invalid;
|
||||||
|
}
|
||||||
|
return this->operators->ops[(int)op](lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable Type::createInstance() const
|
||||||
|
{
|
||||||
|
Variable v;
|
||||||
|
v.setType(*this);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,17 +8,40 @@ namespace trainscript
|
||||||
{
|
{
|
||||||
class Variable;
|
class Variable;
|
||||||
|
|
||||||
|
using Operator = Variable (*)(const Variable & rhs, const Variable &lhs);
|
||||||
|
|
||||||
|
enum class Operation
|
||||||
|
{
|
||||||
|
Add = 0,
|
||||||
|
Subtract,
|
||||||
|
Multiply,
|
||||||
|
Divide,
|
||||||
|
Modulo,
|
||||||
|
Less,
|
||||||
|
LessEquals,
|
||||||
|
Greater,
|
||||||
|
GreaterEquals,
|
||||||
|
Equals,
|
||||||
|
Inequals,
|
||||||
|
LIMIT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeOps {
|
||||||
|
Operator ops[(int)Operation::LIMIT];
|
||||||
|
};
|
||||||
|
|
||||||
struct Type
|
struct Type
|
||||||
{
|
{
|
||||||
TypeID id;
|
TypeID id;
|
||||||
int pointer;
|
int pointer;
|
||||||
|
const TypeOps *operators;
|
||||||
|
|
||||||
Type reference() const {
|
Type reference() const {
|
||||||
return { id, pointer + 1 };
|
return Type { id, pointer + 1, operators };
|
||||||
}
|
}
|
||||||
|
|
||||||
Type dereference() const {
|
Type dereference() const {
|
||||||
return { id, pointer - 1 };
|
return Type { id, pointer - 1, operators };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usable() const {
|
bool usable() const {
|
||||||
|
@ -73,8 +96,28 @@ namespace trainscript
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates an instance of this type.
|
||||||
|
* @return Variable with a value of this type.
|
||||||
|
*/
|
||||||
Variable createInstance() const;
|
Variable createInstance() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the type has the operation defined.
|
||||||
|
* @param op Operation that should be checked
|
||||||
|
* @return True if the operation is defined, else false
|
||||||
|
*/
|
||||||
|
bool hasOperator(Operation op) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Applies the operation to the operands.
|
||||||
|
* @param lhs Left hand side
|
||||||
|
* @param op Operation
|
||||||
|
* @param rhs Right hand side
|
||||||
|
* @return Result of the operation or Variable::Invalid if operation is not defined.
|
||||||
|
*/
|
||||||
|
Variable apply(const Variable &lhs, Operation op, const Variable &rhs) const;
|
||||||
|
|
||||||
static const Type Invalid;
|
static const Type Invalid;
|
||||||
static const Type Void;
|
static const Type Void;
|
||||||
static const Type Int;
|
static const Type Int;
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#include <console.h>
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
|
#include "type.hpp"
|
||||||
|
|
||||||
namespace trainscript
|
namespace trainscript
|
||||||
{
|
{
|
||||||
|
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::Bool = { Type::Bool, 0 };
|
||||||
|
|
||||||
Variable::~Variable()
|
Variable::~Variable()
|
||||||
{
|
{
|
||||||
// Only free non-pointer types.
|
// Only free non-pointer types.
|
||||||
|
@ -20,11 +29,51 @@ namespace trainscript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Variable::replace(const Variable &other)
|
||||||
|
{
|
||||||
|
this->setType(other.mType);
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Variable::setType(const Type &type)
|
||||||
|
{
|
||||||
|
this->mType = type;
|
||||||
|
this->mValue = nullptr;
|
||||||
|
if(mType.pointer == 0) {
|
||||||
|
switch(mType.id) {
|
||||||
|
#define CREATE(type, initial) case TypeID::type: \
|
||||||
|
this->mValue = new trainscript::type(initial); \
|
||||||
|
break
|
||||||
|
CREATE(Bool, false);
|
||||||
|
CREATE(Int, 0);
|
||||||
|
CREATE(Real, 0.0);
|
||||||
|
CREATE(Text, "");
|
||||||
|
#undef CREATE
|
||||||
|
case TypeID::Invalid:
|
||||||
|
case TypeID::Void:
|
||||||
|
// Ignore INVALID or VOID type.
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die_extra("Variable::setType.InvalidTypeID", mType.name());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Variable &Variable::operator =(const Variable &other)
|
Variable &Variable::operator =(const Variable &other)
|
||||||
{
|
{
|
||||||
if(this->mType != other.mType) {
|
if(this->mType != other.mType) {
|
||||||
|
kprintf("[%s -> %s]", other.mType.name(), this->mType.name());
|
||||||
die_extra("Variable.operator=", "Type mismatch.");
|
die_extra("Variable.operator=", "Type mismatch.");
|
||||||
}
|
}
|
||||||
|
if(this->mType == Type::Void) {
|
||||||
|
// Just don't do anything when assigning void.
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if(this->mValue == nullptr) {
|
||||||
|
kprintf("[Variable.type: %s]", this->mType.name());
|
||||||
|
die_extra("Variable.operator=", "Invalid variable: value == nullptr");
|
||||||
|
}
|
||||||
if(this->mType.pointer == 0) {
|
if(this->mType.pointer == 0) {
|
||||||
switch(this->mType.id) {
|
switch(this->mType.id) {
|
||||||
#define COPY(type) case TypeID::type: \
|
#define COPY(type) case TypeID::type: \
|
||||||
|
@ -42,26 +91,6 @@ namespace trainscript
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable Type::createInstance() const
|
|
||||||
{
|
|
||||||
void *value = nullptr;
|
|
||||||
if(this->pointer > 0) {
|
|
||||||
switch(this->id) {
|
|
||||||
#define CREATE(type, initial) case TypeID::type: \
|
|
||||||
value = new trainscript::type(initial); \
|
|
||||||
break
|
|
||||||
CREATE(Bool, false);
|
|
||||||
CREATE(Int, 0);
|
|
||||||
CREATE(Real, 0.0);
|
|
||||||
CREATE(Text, "");
|
|
||||||
default:
|
|
||||||
die("Type::createInstance.InvalidTypeID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Variable(*this, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define fromType(type) Variable Variable::from##type(trainscript::type i) \
|
#define fromType(type) Variable Variable::from##type(trainscript::type i) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -28,9 +28,10 @@ namespace trainscript
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable(const Variable &other) :
|
Variable(const Variable &other) :
|
||||||
mType(other.mType),
|
mType(),
|
||||||
mValue(nullptr)
|
mValue()
|
||||||
{
|
{
|
||||||
|
this->setType(other.mType);
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +46,14 @@ namespace trainscript
|
||||||
|
|
||||||
Variable &operator =(const Variable &other);
|
Variable &operator =(const Variable &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces the value and type of this variable.
|
||||||
|
* @param other The reference variable to copy.
|
||||||
|
*/
|
||||||
|
void replace(const Variable &other);
|
||||||
|
|
||||||
|
void setType(const Type &type);
|
||||||
|
|
||||||
void *data() const
|
void *data() const
|
||||||
{
|
{
|
||||||
return this->mValue;
|
return this->mValue;
|
||||||
|
|
Loading…
Reference in a new issue