Closures in Ground

This commit is contained in:
2026-03-02 10:09:10 +11:00
parent d011d2beb4
commit 5577679ded
7 changed files with 152 additions and 62 deletions

View File

@@ -449,6 +449,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
GroundFunction* function = parseFunction(&gp, errorOffset);
function->startLine = i;
function->closure = copyGroundScope(scope);
GroundValue gv = createFunctionGroundValue(function);
addFieldToStruct(&gstruct, name, gv);
break;
@@ -484,42 +485,6 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
if (in->instructions[i].type == CREATELABEL) {
addLabel(scope.labels, in->instructions[i].args.args[0].value.refName, i);
}
if (in->instructions[i].type == 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++;
}
i--;
GroundFunction* function = parseFunction(&gp, errorOffset);
function->startLine = i;
GroundValue gv = createFunctionGroundValue(function);
addVariable(scope.variables, name, gv);
}
if (in->instructions[i].type == STRUCT) {
if (in->instructions[i].args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", &in->instructions[i], i);
@@ -562,6 +527,44 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
}
}
for (size_t i = 0; i < in->size; i++) {
if (in->instructions[i].type == 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++;
}
i--;
GroundFunction* function = parseFunction(&gp, errorOffset);
function->startLine = i;
function->closure = copyGroundScope(inScope);
GroundValue gv = createFunctionGroundValue(function);
addVariable(scope.variables, name, gv);
}
/*
if (in->instructions[i].type == FUN) {
int count = 1;
while (count > 0) {
@@ -577,6 +580,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
}
}
}
*/
if (in->instructions[i].type == STRUCT) {
int count = 1;
while (count > 0) {
@@ -1789,11 +1793,6 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
if (in->args.args[in->args.length - 1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef as the last arg", in, currentInstruction);
}
GroundVariable* variables = NULL;
GroundLabel* labels = NULL;
GroundScope newScope;
newScope.variables = &variables;
newScope.labels = &labels;
GroundVariable* var = findVariable(*scope->variables, in->args.args[0].value.refName);
if (var == NULL) {
runtimeError(UNKNOWN_VARIABLE, "Function not found", in, currentInstruction);
@@ -1841,6 +1840,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
}
free(argsList.values);
} else {
GroundScope newScope = copyGroundScope(&function->closure);
for (size_t i = 0; i < function->argSize; i++) {
if (in->args.args[i + 1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);