diff --git a/README.md b/README.md index 8e8afb3..f79ae21 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ Also it leaks memory. A lot of memory. - Fixing Memory Leaks - Adding support for Modules - Adding support for Pointer Types -- Adding support for String Type ## Guidlines - Calls to `die` or `die_extra` should follow the following scheme: `ContextName.ErrorName` diff --git a/scripts/main.ts b/scripts/main.ts index e1e58e4..4220b29 100644 --- a/scripts/main.ts +++ b/scripts/main.ts @@ -4,9 +4,11 @@ VAR global : INT; # OBJ heap : "/sys/malloc"; # OBJ interrupts : "/sys/interrupt"; -PUB main() | i : INT +PUB main() | i : INT, str : TEXT BEGIN 0 -> i; + "Hello " -> str; + printStr(str + "World!"); WHILE ((i + 1) -> i) <= fun() DO BEGIN hlp(i, fun() - i); diff --git a/src/vm.cpp b/src/vm.cpp index b8ff669..1d19b62 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -85,7 +85,12 @@ Variable NativeMethod::invoke(Vector arguments) if(arguments[i].type() != this->parameters[i]) { die_extra("NativeMethod.InvalidArgumentType", arguments[i].type().name()); } - stackSize += arguments[i].type().size(); + // Special case TEXT: Copy const char * instead of object + if(arguments[i].type() == Type::Text) { + stackSize += sizeof(const char *); + } else { + stackSize += arguments[i].type().size(); + } } uint8_t *stack = (uint8_t*)malloc(stackSize); @@ -95,9 +100,18 @@ Variable NativeMethod::invoke(Vector arguments) size_t size = arguments[i].type().size(); void *data = arguments[i].data(); - if(size > 0) { - memcpy(stackPtr, data, size); - stackPtr += size; + if(arguments[i].type() == Type::Text) { + // Copy const char * + const char *text = arguments[i].value(); + + memcpy(stackPtr, &text, sizeof(const char *)); + stackPtr += sizeof(const char *); + } + else { + if(size > 0) { + memcpy(stackPtr, data, size); + stackPtr += size; + } } } @@ -116,6 +130,10 @@ extern "C" void __cdecl print2Int(int a, int b) { kprintf("{%d;%d}\n", a, b); } +extern "C" void __cdecl printStr(const char *text) { + kprintf("{%s}", text); +} + struct NativeModuleDef { const char *name; @@ -128,6 +146,7 @@ NativeModuleDef methods[] = { { "timer_get", "", (void*)timer_get }, { "timer_set", "i", (void*)timer_set }, { "printInt", "i", (void*)printInt }, + { "printStr", "t", (void*)printStr }, { "print2Int", "ii", (void*)print2Int }, { nullptr, nullptr, 0 } }; diff --git a/trainscript/trainscript.l b/trainscript/trainscript.l index 7ea6c57..e341ef8 100644 --- a/trainscript/trainscript.l +++ b/trainscript/trainscript.l @@ -9,6 +9,9 @@ %option reentrant %option bison-bridge %option yylineno + +%x strparse + %% \#[^\n]* ; // Eat all the comments! [ \t]+ ; // Eat all the whitespace! @@ -56,6 +59,11 @@ TO { return KW_TO; } UNTIL { return KW_UNTIL; } WHILE { return KW_WHILE; } DO { return KW_DO; } + +"\"" BEGIN(strparse); +[^\"]* { yylval->text = yyextra->strdup(yytext); return TEXT; } +"\"" BEGIN(INITIAL); + [0-9]+\.[0-9]* { yylval->fval = atof(yytext); return REAL; } [0-9]+ { yylval->ival = atoi(yytext); return INT; } [a-zA-Z0-9'_]+ { yylval->text = yyextra->strdup(yytext); return IDENTIFIER; } diff --git a/trainscript/trainscript.y b/trainscript/trainscript.y index 6cc273c..6c3e293 100644 --- a/trainscript/trainscript.y +++ b/trainscript/trainscript.y @@ -66,6 +66,7 @@ void yyerror(void *scanner, const char *s); %token REAL %token INT %token IDENTIFIER +%token TEXT %token KW_PUB %token KW_PRI @@ -319,7 +320,7 @@ elseIfLoop: expression: INT { $$ = new ConstantExpression(Variable::fromInt($1)); } | REAL { $$ = new ConstantExpression(Variable::fromReal($1)); } -// | TEXT { $$ = new ConstantExpression(Variable::fromText($1)); } +| TEXT { $$ = new ConstantExpression(Variable::fromText($1)); } | IDENTIFIER { $$ = new VariableExpression($1); } | IDENTIFIER LBRACKET expressionList RBRACKET { auto *call = new MethodInvokeExpression($1);