From 1c03f20af8c51a88669ebe95db9ccafde30d8161 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sun, 23 Nov 2025 19:59:22 +1100 Subject: [PATCH] Bug fixes --- src/interpreter.c | 49 +++++++++++++++++++++++++++++++---------------- src/interpreter.h | 13 ++++++++++++- src/main.c | 1 + 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 46fcd1f..00e5a0a 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -6,8 +6,6 @@ int currentInstruction = 0; -GroundLabel* labels = NULL; - void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) { printf("Ground runtime error:\n ErrorType: "); switch (error) { @@ -61,29 +59,45 @@ void deleteLabel(GroundLabel** head, GroundLabel *item) { free(item); } -void delete_all(GroundLabel **head) { - GroundLabel *current, *tmp; - HASH_ITER(hh, *head, current, tmp) { - HASH_DEL(*head, current); - free(current); - } +void addVariable(GroundVariable **head, const char *id, GroundValue data) { + GroundVariable* item = malloc(sizeof(GroundVariable)); + snprintf(item->id, MAX_ID_LEN, "%s", id); + item->value = data; + HASH_ADD_STR(*head, id, item); +} + +GroundVariable* findVariable(GroundVariable* head, const char *id) { + GroundVariable *item; + HASH_FIND_STR(head, id, item); + return item; +} + +void deleteVariable(GroundVariable** head, GroundVariable *item) { + HASH_DEL(*head, item); + free(item); } void interpretGroundProgram(GroundProgram* in) { + GroundLabel* labels = NULL; + GroundVariable* variables = NULL; + + GroundScope scope; + scope.labels = &labels; + scope.variables = &variables; // Preprocess all labels for (int i = 0; i < in->size; i++) { if (in->instructions[i].type == CREATELABEL) { - addLabel(&labels, in->instructions[i].args.args[0].value.refName, i); + addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i); } } while (currentInstruction < in->size) { - interpretGroundInstruction(&in->instructions[currentInstruction]); + interpretGroundInstruction(&in->instructions[currentInstruction], &scope); currentInstruction++; } } -void interpretGroundInstruction(GroundInstruction* in) { +void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope) { switch (in->type) { // We can safely ignore any CREATELABEL instructions, these have been preprocessed case CREATELABEL: { @@ -96,21 +110,22 @@ void interpretGroundInstruction(GroundInstruction* in) { if (in->args.length > 2) { runtimeError(TOO_MANY_ARGS, "Expecting 2 arguments", in, currentInstruction); } - if (in->args.args[0].type != VALUE && in->args.args[0].value.value.type != BOOL) { + if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != BOOL) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a bool for arg 0", in, currentInstruction); } - if (in->args.args[0].type != LINEREF) { + if (in->args.args[1].type != LINEREF) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction); } if (in->args.args[0].value.value.data.boolVal) { - GroundLabel* label = findLabel(labels, in->args.args[1].value.refName); + GroundLabel* label = findLabel(*scope->labels, in->args.args[1].value.refName); if (label) { currentInstruction = label->lineNum; } else { runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction); } } + break; } case JUMP: { if (in->args.length < 1) { @@ -123,17 +138,19 @@ void interpretGroundInstruction(GroundInstruction* in) { runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 1", in, currentInstruction); } - GroundLabel* label = findLabel(labels, in->args.args[0].value.refName); + GroundLabel* label = findLabel(*scope->labels, in->args.args[0].value.refName); if (label) { currentInstruction = label->lineNum; } else { runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction); } + break; } case END: { - if (in->args.length < 1) { + if (in->args.length < 1 || in->args.args[0].type != VALUE || in->args.args[0].value.value.type != INT) { exit(0); } else { + exit(in->args.args[0].value.value.data.intVal); } break; } diff --git a/src/interpreter.h b/src/interpreter.h index 9d4522b..36a8026 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -16,6 +16,17 @@ typedef struct GroundLabel { UT_hash_handle hh; } GroundLabel; +typedef struct GroundVariable { + char id[MAX_ID_LEN]; + GroundValue value; + UT_hash_handle hh; +} GroundVariable; + +typedef struct GroundScope { + GroundLabel** labels; + GroundVariable** variables; +} GroundScope; + void interpretGroundProgram(GroundProgram* in); -void interpretGroundInstruction(GroundInstruction* in); +void interpretGroundInstruction(GroundInstruction* in, GroundScope* scope); #endif diff --git a/src/main.c b/src/main.c index 4ceadb3..27a9912 100644 --- a/src/main.c +++ b/src/main.c @@ -45,5 +45,6 @@ int main(int argc, char** argv) { } char* file = getFileContents(argv[1]); GroundProgram program = parseFile(file); + free(file); interpretGroundProgram(&program); }