Refactor function parsing
This commit is contained in:
@@ -246,6 +246,41 @@ void groundAddNativeFunction(GroundScope* scope, char* name, NativeGroundFunctio
|
|||||||
addVariable(scope->variables, name, createFunctionGroundValue(gf));
|
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 parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset) {
|
||||||
GroundStruct gstruct = createStruct();
|
GroundStruct gstruct = createStruct();
|
||||||
for (size_t i = 0; i < in->size; i++) {
|
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) {
|
if (in->instructions[i].args.args[0].type != FNREF) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", &in->instructions[i], i);
|
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;
|
char* functionName = in->instructions[i].args.args[0].value.refName;
|
||||||
if (in->instructions[i].args.length < 2) {
|
if (in->instructions[i].args.length < 2) {
|
||||||
function->returnType = NONE;
|
function->returnType = NONE;
|
||||||
@@ -414,6 +475,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
addVariable(scope.variables, functionName, createFunctionGroundValue(function));
|
addVariable(scope.variables, functionName, createFunctionGroundValue(function));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
if (in->instructions[i].type == STRUCT) {
|
if (in->instructions[i].type == STRUCT) {
|
||||||
if (in->instructions[i].args.length < 1) {
|
if (in->instructions[i].args.length < 1) {
|
||||||
@@ -1816,7 +1878,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
|
|
||||||
GroundValue gv;
|
GroundValue gv;
|
||||||
|
|
||||||
switch (stringToValueType(in->args.args[0].value.refName)) {
|
switch (stringToValueType(in->args.args[1].value.refName)) {
|
||||||
case INT: {
|
case INT: {
|
||||||
gv = createIntGroundValue(0);
|
gv = createIntGroundValue(0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ typedef struct GroundDebugInstruction {
|
|||||||
} GroundDebugInstruction;
|
} GroundDebugInstruction;
|
||||||
|
|
||||||
GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset);
|
GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffset);
|
||||||
|
GroundFunction* parseFunction(GroundProgram* in, size_t errorOffset);
|
||||||
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope);
|
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope);
|
||||||
GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);
|
GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user