diff --git a/src/interpreter.c b/src/interpreter.c index 272a66b..f613259 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -246,6 +246,41 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio addVariable(scope->variables, name, createFunctionGroundValue(gf)); } +GroundFunction* parseFunction(GroundProgram* in, size_t errorOffset) { + GroundFunction* function = createGroundFunction(); + for (size_t i = 0; i < in->size; i++) { + if (in->instructions[i].args.length < 2) { + function->returnType = NONE; + } else { + if (in->instructions[i].args.args[1].type != TYPEREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], errorOffset + i); + } + GroundArg* args = in->instructions[i].args.args; + function->returnType = stringToValueType(args[1].value.refName); + size_t length = in->instructions[i].args.length; + for (size_t j = 2; j < length; j += 2) { + if (args[j].type != TYPEREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef", &in->instructions[i], errorOffset + i); + } + if (j + 1 >= length) { + runtimeError(TOO_FEW_ARGS, "Expecting a DirectRef after a TypeRef", &in->instructions[i], errorOffset + i); + } + if (args[j + 1].type != DIRREF) { + runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef after a TypeRef", &in->instructions[i], errorOffset + i); + } + addArgsToGroundFunction(function, stringToValueType(args[j].value.refName), args[j + 1].value.refName); + } + } + i++; + while (in->instructions[i].type != ENDFUN) { + addInstructionToProgram(&function->program, in->instructions[i]); + i++; + } + break; + } + return function; +} + GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset) { GroundStruct gstruct = createStruct(); for (size_t i = 0; i < in->size; i++) { @@ -385,6 +420,32 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { 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++; + } + + GroundValue gv = createFunctionGroundValue(parseFunction(&gp, errorOffset)); + + addVariable(scope.variables, name, gv); + /* char* functionName = in->instructions[i].args.args[0].value.refName; if (in->instructions[i].args.length < 2) { function->returnType = NONE; @@ -414,6 +475,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { i++; } addVariable(scope.variables, functionName, createFunctionGroundValue(function)); + */ } if (in->instructions[i].type == STRUCT) { if (in->instructions[i].args.length < 1) { @@ -1816,7 +1878,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop GroundValue gv; - switch (stringToValueType(in->args.args[0].value.refName)) { + switch (stringToValueType(in->args.args[1].value.refName)) { case INT: { gv = createIntGroundValue(0); break; diff --git a/src/interpreter.h b/src/interpreter.h index 72354d0..a2df833 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -37,6 +37,7 @@ typedef struct GroundDebugInstruction { } GroundDebugInstruction; GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset); +GroundFunction* parseFunction(GroundProgram* in, size_t errorOffset); GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope); GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);