From 1c5300d27e76c46b97ccb3368c377b5e436f8245 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 17 Jan 2026 20:04:18 +1100 Subject: [PATCH] Struct init --- src/interpreter.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++- src/interpreter.h | 2 +- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index be2b232..bd89520 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -246,7 +246,7 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio addVariable(scope->variables, name, createFunctionGroundValue(gf)); } -GroundStruct parseStruct(GroundProgram* in, size_t errorOffset) { +GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset) { GroundStruct gstruct = createStruct(); for (size_t i = 0; i < in->size; i++) { switch (in->instructions[i].type) { @@ -267,6 +267,81 @@ GroundStruct parseStruct(GroundProgram* in, size_t errorOffset) { break; } case INIT: { + if (in->instructions[i].args.length < 2) { + runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &in->instructions[i], currentInstruction); + } + if (in->instructions[i].args.length > 2) { + runtimeError(TOO_MANY_ARGS, "Expecting 2 args", &in->instructions[i], currentInstruction); + } + if (in->instructions[i].args.args[0].type != DIRREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", &in->instructions[i], currentInstruction); + } + if (in->instructions[i].args.args[1].type != TYPEREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], currentInstruction); + } + + GroundValue gv; + + switch (stringToValueType(in->instructions[i].args.args[0].value.refName)) { + case INT: { + gv = createIntGroundValue(0); + break; + } + case DOUBLE: { + gv = createDoubleGroundValue(0); + break; + } + case STRING: { + gv = createStringGroundValue(""); + break; + } + case CHAR: { + gv = createCharGroundValue('\0'); + break; + } + case BOOL: { + gv = createBoolGroundValue(false); + break; + } + case LIST: { + gv = createListGroundValue(createList()); + break; + } + case FUNCTION: { + gv = createFunctionGroundValue(createGroundFunction()); + break; + } + case STRUCTVAL: { + gv.type = STRUCTVAL; + gv.data.structVal = malloc(sizeof(GroundStruct)); + *gv.data.structVal = createStruct(); + break; + } + case CUSTOM: { + GroundVariable* var = findVariable(*scope->variables, in->instructions[i].args.args[1].value.refName); + if (var == NULL) { + runtimeError(UNKNOWN_VARIABLE, "Couldn't find the specified type", &in->instructions[i], currentInstruction); + } + if (var->value.type != STRUCTVAL) { + runtimeError(ARG_TYPE_MISMATCH, "TypeRef does not reference a struct", &in->instructions[i], currentInstruction); + } + GroundStruct* gstruct = var->value.data.structVal; + gv.type = CUSTOM; + gv.data.customVal = malloc(sizeof(GroundObject)); + *gv.data.customVal = createObject(*gstruct); + break; + } + case NONE: { + gv.type = NONE; + break; + } + default: { + runtimeError(FIXME, "Reached should-be-impossible state", &in->instructions[i], currentInstruction); + break; + } + } + addFieldToStruct(&gstruct, in->instructions[i].args.args[0].value.refName, gv); + break; } case FUN: { @@ -1799,6 +1874,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop break; } } + addVariable(scope->variables, in->args.args[0].value.refName, gv); break; } diff --git a/src/interpreter.h b/src/interpreter.h index 83ce97e..72354d0 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -36,7 +36,7 @@ typedef struct GroundDebugInstruction { char* arg; } GroundDebugInstruction; -GroundStruct parseStruct(GroundProgram* in, size_t errorOffset); +GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset); GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope); GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);