diff --git a/src/interpreter.c b/src/interpreter.c index e8def73..9b04845 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -380,6 +380,38 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs break; } case FUN: { + if (in->instructions[i].args.length < 1) { + runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", &in->instructions[i], i); + } + if (in->instructions[i].args.args[0].type != FNREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", &in->instructions[i], i); + } + char* name = malloc(strlen(in->instructions[i].args.args[0].value.refName) + 1); + strcpy(name, in->instructions[i].args.args[0].value.refName); + + size_t counter = 1; + GroundProgram gp = createGroundProgram(); + addInstructionToProgram(&gp, in->instructions[i]); + size_t errorOffset = i; + i++; + while (counter > 0) { + if (i >= in->size) { + runtimeError(PREMATURE_EOF, "Reached end of scope before function definition ended", &in->instructions[i - 1], i - 1); + } + if (in->instructions[i].type == FUN) { + counter++; + } + if (in->instructions[i].type == ENDFUN) { + counter--; + } + addInstructionToProgram(&gp, in->instructions[i]); + i++; + } + + GroundFunction* function = parseFunction(&gp, errorOffset); + function->startLine = i; + GroundValue gv = createFunctionGroundValue(function); + addFieldToStruct(&gstruct, name, gv); break; } case ENDSTRUCT: { @@ -412,8 +444,6 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i); } if (in->instructions[i].type == FUN) { - GroundFunction* function = createGroundFunction(); - function->startLine = i; if (in->instructions[i].args.length < 1) { runtimeError(TOO_FEW_ARGS, "Expecting 1 or more args", &in->instructions[i], i); } @@ -442,7 +472,9 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { i++; } - GroundValue gv = createFunctionGroundValue(parseFunction(&gp, errorOffset)); + GroundFunction* function = parseFunction(&gp, errorOffset); + function->startLine = i; + GroundValue gv = createFunctionGroundValue(function); addVariable(scope.variables, name, gv); } @@ -502,6 +534,21 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { } } } + if (in->instructions[i].type == STRUCT) { + int count = 1; + while (count > 0) { + i++; + if (i >= in->size) { + return createNoneGroundValue(); + } + if (in->instructions[i].type == STRUCT) { + count++; + } + if (in->instructions[i].type == ENDSTRUCT) { + count--; + } + } + } if (in->instructions[i].type == PAUSE || instructionsToPause == 0) { printf("Paused execution\n"); printf("Previous instruction: "); @@ -1873,7 +1920,9 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop break; } case FUNCTION: { - gv = createFunctionGroundValue(createGroundFunction()); + GroundFunction* gf = createGroundFunction(); + gf->returnType = NONE; + gv = createFunctionGroundValue(gf); break; } case STRUCTVAL: {