From e9ab6f3f967f850fc8e559d7bee35db205e13c6d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 13 Aug 2022 21:27:39 +0100 Subject: [PATCH] Variables now persist between statements --- source/interpreter.c | 25 +++++++++++++++++++------ source/interpreter.h | 6 +++--- source/parser.c | 4 ++++ source/repl_main.c | 9 ++++----- source/scope.c | 8 ++++---- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/source/interpreter.c b/source/interpreter.c index ce4232a..e517e9c 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -18,11 +18,11 @@ static void stderrWrapper(const char* output) { fprintf(stderr, "\n"); //default new line } -void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) { +void initInterpreter(Interpreter* interpreter) { initLiteralArray(&interpreter->literalCache); interpreter->scope = pushScope(NULL); - interpreter->bytecode = bytecode; - interpreter->length = length; + interpreter->bytecode = NULL; + interpreter->length = 0; interpreter->count = 0; initLiteralArray(&interpreter->stack); @@ -286,6 +286,9 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) { Literal type = interpreter->literalCache.literals[typeIndex]; if (!declareScopeVariable(interpreter->scope, identifier, type)) { + printf("Can't redefine the variable \"");; + printLiteral(identifier); + printf("\"\n"); return false; } @@ -353,7 +356,7 @@ static void execInterpreter(Interpreter* interpreter) { interpreter->scope = popScope(interpreter->scope); break; - //TODO: type declarations + //TODO: custom type declarations case OP_VAR_DECL: case OP_VAR_DECL_LONG: @@ -372,12 +375,22 @@ static void execInterpreter(Interpreter* interpreter) { } } -void runInterpreter(Interpreter* interpreter) { +void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) { + //prep the bytecode + interpreter->bytecode = bytecode; + interpreter->length = length; + interpreter->count = 0; + if (!interpreter->bytecode) { printf(ERROR "Error: No valid bytecode given\n" RESET); return; } + //prep the literal cache + if (interpreter->literalCache.count > 0) { + freeLiteralArray(&interpreter->literalCache); //automatically inits + } + //header section const unsigned char major = readByte(interpreter->bytecode, &interpreter->count); const unsigned char minor = readByte(interpreter->bytecode, &interpreter->count); @@ -515,7 +528,7 @@ void runInterpreter(Interpreter* interpreter) { pushLiteralArray(&interpreter->literalCache, identifier); if (command.verbose) { - printf("(identifier %s (%d))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash); + printf("(identifier %s (hash: %x))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash); } } break; diff --git a/source/interpreter.h b/source/interpreter.h index b1782cc..5bbfeda 100644 --- a/source/interpreter.h +++ b/source/interpreter.h @@ -21,16 +21,16 @@ typedef struct Interpreter { LiteralArray stack; //output - // LiteralDictionary exports; //read-write - interface with Toy from C + // LiteralDictionary exports; //TODO: read-write - interface with Toy from C PrintFn printOutput; PrintFn assertOutput; } Interpreter; -void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); +void initInterpreter(Interpreter* interpreter); void freeInterpreter(Interpreter* interpreter); //utilities for the host program void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput); void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput); -void runInterpreter(Interpreter* interpreter); +void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); diff --git a/source/parser.c b/source/parser.c index 9cc6b2b..fe7dd94 100644 --- a/source/parser.c +++ b/source/parser.c @@ -821,6 +821,10 @@ static void varDecl(Parser* parser, Node** nodeHandle) { if (match(parser, TOKEN_ASSIGN)) { expression(parser, &expressionNode); } + else { + //values are null by default + emitNodeLiteral(&expressionNode, TO_NULL_LITERAL); + } //TODO: static type checking? diff --git a/source/repl_main.c b/source/repl_main.c index e187860..29b9a06 100644 --- a/source/repl_main.c +++ b/source/repl_main.c @@ -103,8 +103,8 @@ unsigned char* compileString(char* source, size_t* size) { void runBinary(unsigned char* tb, size_t size) { Interpreter interpreter; - initInterpreter(&interpreter, tb, size); - runInterpreter(&interpreter); + initInterpreter(&interpreter); + runInterpreter(&interpreter, tb, size); freeInterpreter(&interpreter); } @@ -143,6 +143,7 @@ void repl() { memset(input, 0, size); Interpreter interpreter; //persist the interpreter for the scopes + initInterpreter(&interpreter); for(;;) { printf("> "); @@ -178,9 +179,7 @@ void repl() { unsigned char* tb = collateCompiler(&compiler, &size); //run the bytecode - initInterpreter(&interpreter, tb, size); - runInterpreter(&interpreter); - freeInterpreter(&interpreter); //TODO: option to retain the scopes + runInterpreter(&interpreter, tb, size); } //clean up this iteration diff --git a/source/scope.c b/source/scope.c index 20ca8fb..9f5a455 100644 --- a/source/scope.c +++ b/source/scope.c @@ -44,17 +44,17 @@ Scope* popScope(Scope* scope) { return ret; } - +#include //returns false if error bool declareScopeVariable(Scope* scope, Literal key, Literal type) { - //store the type, for later checking on assignment - setLiteralDictionary(&scope->types, key, type); - //don't redefine a variable within this scope if (existsLiteralDictionary(&scope->variables, key)) { return false; } + //store the type, for later checking on assignment + setLiteralDictionary(&scope->types, key, type); + setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL); return true; }