Call functions

This commit is contained in:
2025-12-06 14:35:13 +11:00
parent 9553934db5
commit 166a547a74
5 changed files with 74 additions and 11 deletions

View File

@@ -163,13 +163,14 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
scope.labels = &labels;
scope.variables = &variables;
}
// Preprocess all labels
// Preprocess all labels and functions
for (int i = 0; i < in->size; i++) {
if (in->instructions[i].type == CREATELABEL) {
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);
}
@@ -203,18 +204,36 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
addInstructionToProgram(&function->program, in->instructions[i]);
i++;
}
if (&function->program.size == 0) {
addInstructionToProgram(&function->program, createGroundInstruction(PRINT));
}
addVariable(scope.variables, functionName, createFunctionGroundValue(function));
}
}
while (currentInstruction < in->size) {
interpretGroundInstruction(in->instructions[currentInstruction], &scope);
for (int i = 0; i < in->size; i++) {
if (in->instructions[i].type == FUN) {
int count = 1;
while (count > 0) {
i++;
if (i >= in->size) {
return createNoneGroundValue();
}
if (in->instructions[i].type == FUN) {
count++;
}
if (in->instructions[i].type == ENDFUN) {
count--;
}
}
}
int ci = currentInstruction;
GroundValue gv = interpretGroundInstruction(in->instructions[i], &scope);
if (gv.type != NONE) {
return gv;
}
if (ci != currentInstruction) {
i = currentInstruction;
}
currentInstruction++;
}
return createIntGroundValue(0);
return createNoneGroundValue();
}
GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
@@ -1124,7 +1143,16 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
* fun, return, endfun, pusharg, call
*/
case RETURN: {
break;
if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);
}
if (in->args.length > 1) {
runtimeError(TOO_MANY_ARGS, "Expecting 1 arg", in, currentInstruction);
}
if (in->args.args[0].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 1", in, currentInstruction);
}
return in->args.args[0].value.value;
}
case CALL: {
if (in->args.length < 2) {
@@ -1153,13 +1181,18 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
runtimeError(UNKNOWN_VARIABLE, "Provided reference does not reference a function", in, currentInstruction);
}
GroundFunction* function = value->data.fnVal;
size_t currentCurrentInstruction = currentInstruction;
currentInstruction = function->startLine;
GroundValue returnValue = interpretGroundProgram(&function->program, &newScope);
if (returnValue.type != function->returnType) {
runtimeError(RETURN_TYPE_MISMATCH, "Unexpected return value type from function", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[1].value.refName, returnValue);
currentInstruction = currentCurrentInstruction;
break;
}
}
freeGroundInstruction(in);
return createIntGroundValue(0);
return createNoneGroundValue();
}

View File

@@ -51,6 +51,12 @@ GroundValue createFunctionGroundValue(GroundFunction* in) {
return gv;
}
GroundValue createNoneGroundValue() {
GroundValue gv;
gv.type = NONE;
return gv;
}
GroundValue copyGroundValue(const GroundValue* gv) {
GroundValue newGv;
newGv.type = gv->type;

View File

@@ -118,6 +118,7 @@ typedef struct GroundFunction {
size_t argSize;
GroundValueType returnType;
GroundProgram program;
size_t startLine;
} GroundFunction;
@@ -142,6 +143,9 @@ GroundValue createListGroundValue(List in);
// Creates a GroundValue conatining (in), with type FUNCTION.
GroundValue createFunctionGroundValue(GroundFunction* in);
// Creates a Groundvalue with type NONE.
GroundValue createNoneGroundValue();
// Creates a deep copy of a GroundValue
GroundValue copyGroundValue(const GroundValue* gv);

19
tests/fib.grnd Normal file
View File

@@ -0,0 +1,19 @@
set &a 0
set &b 1
set &n 92
set &i 0
@loop
equal $i $n &done
if $done %end
add $a $b &temp
set &a $b
set &b $temp
add $i 1 &i
jump %loop
@end
println "Fibonacci result:" $a
end

View File

@@ -1,5 +1,6 @@
fun !dingus -string -int &x
return "dinglefart"
endfun
call !dingus &e
println $e