Variables now persist between statements

This commit is contained in:
2022-08-13 21:27:39 +01:00
parent 633df5f376
commit e9ab6f3f96
5 changed files with 34 additions and 18 deletions

View File

@@ -18,11 +18,11 @@ static void stderrWrapper(const char* output) {
fprintf(stderr, "\n"); //default new line fprintf(stderr, "\n"); //default new line
} }
void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) { void initInterpreter(Interpreter* interpreter) {
initLiteralArray(&interpreter->literalCache); initLiteralArray(&interpreter->literalCache);
interpreter->scope = pushScope(NULL); interpreter->scope = pushScope(NULL);
interpreter->bytecode = bytecode; interpreter->bytecode = NULL;
interpreter->length = length; interpreter->length = 0;
interpreter->count = 0; interpreter->count = 0;
initLiteralArray(&interpreter->stack); initLiteralArray(&interpreter->stack);
@@ -286,6 +286,9 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) {
Literal type = interpreter->literalCache.literals[typeIndex]; Literal type = interpreter->literalCache.literals[typeIndex];
if (!declareScopeVariable(interpreter->scope, identifier, type)) { if (!declareScopeVariable(interpreter->scope, identifier, type)) {
printf("Can't redefine the variable \"");;
printLiteral(identifier);
printf("\"\n");
return false; return false;
} }
@@ -353,7 +356,7 @@ static void execInterpreter(Interpreter* interpreter) {
interpreter->scope = popScope(interpreter->scope); interpreter->scope = popScope(interpreter->scope);
break; break;
//TODO: type declarations //TODO: custom type declarations
case OP_VAR_DECL: case OP_VAR_DECL:
case OP_VAR_DECL_LONG: 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) { if (!interpreter->bytecode) {
printf(ERROR "Error: No valid bytecode given\n" RESET); printf(ERROR "Error: No valid bytecode given\n" RESET);
return; return;
} }
//prep the literal cache
if (interpreter->literalCache.count > 0) {
freeLiteralArray(&interpreter->literalCache); //automatically inits
}
//header section //header section
const unsigned char major = readByte(interpreter->bytecode, &interpreter->count); const unsigned char major = readByte(interpreter->bytecode, &interpreter->count);
const unsigned char minor = 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); pushLiteralArray(&interpreter->literalCache, identifier);
if (command.verbose) { 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; break;

View File

@@ -21,16 +21,16 @@ typedef struct Interpreter {
LiteralArray stack; LiteralArray stack;
//output //output
// LiteralDictionary exports; //read-write - interface with Toy from C // LiteralDictionary exports; //TODO: read-write - interface with Toy from C
PrintFn printOutput; PrintFn printOutput;
PrintFn assertOutput; PrintFn assertOutput;
} Interpreter; } Interpreter;
void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); void initInterpreter(Interpreter* interpreter);
void freeInterpreter(Interpreter* interpreter); void freeInterpreter(Interpreter* interpreter);
//utilities for the host program //utilities for the host program
void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput); void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput);
void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput); void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput);
void runInterpreter(Interpreter* interpreter); void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length);

View File

@@ -821,6 +821,10 @@ static void varDecl(Parser* parser, Node** nodeHandle) {
if (match(parser, TOKEN_ASSIGN)) { if (match(parser, TOKEN_ASSIGN)) {
expression(parser, &expressionNode); expression(parser, &expressionNode);
} }
else {
//values are null by default
emitNodeLiteral(&expressionNode, TO_NULL_LITERAL);
}
//TODO: static type checking? //TODO: static type checking?

View File

@@ -103,8 +103,8 @@ unsigned char* compileString(char* source, size_t* size) {
void runBinary(unsigned char* tb, size_t size) { void runBinary(unsigned char* tb, size_t size) {
Interpreter interpreter; Interpreter interpreter;
initInterpreter(&interpreter, tb, size); initInterpreter(&interpreter);
runInterpreter(&interpreter); runInterpreter(&interpreter, tb, size);
freeInterpreter(&interpreter); freeInterpreter(&interpreter);
} }
@@ -143,6 +143,7 @@ void repl() {
memset(input, 0, size); memset(input, 0, size);
Interpreter interpreter; //persist the interpreter for the scopes Interpreter interpreter; //persist the interpreter for the scopes
initInterpreter(&interpreter);
for(;;) { for(;;) {
printf("> "); printf("> ");
@@ -178,9 +179,7 @@ void repl() {
unsigned char* tb = collateCompiler(&compiler, &size); unsigned char* tb = collateCompiler(&compiler, &size);
//run the bytecode //run the bytecode
initInterpreter(&interpreter, tb, size); runInterpreter(&interpreter, tb, size);
runInterpreter(&interpreter);
freeInterpreter(&interpreter); //TODO: option to retain the scopes
} }
//clean up this iteration //clean up this iteration

View File

@@ -44,17 +44,17 @@ Scope* popScope(Scope* scope) {
return ret; return ret;
} }
#include <stdio.h>
//returns false if error //returns false if error
bool declareScopeVariable(Scope* scope, Literal key, Literal type) { 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 //don't redefine a variable within this scope
if (existsLiteralDictionary(&scope->variables, key)) { if (existsLiteralDictionary(&scope->variables, key)) {
return false; return false;
} }
//store the type, for later checking on assignment
setLiteralDictionary(&scope->types, key, type);
setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL); setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL);
return true; return true;
} }