Start work on function calling

This commit is contained in:
2026-02-28 21:58:33 +11:00
parent 955927e021
commit dc09883e46
3 changed files with 175 additions and 1 deletions

View File

@@ -3,6 +3,7 @@
#include "SolsScope.h"
#include <groundvm.h>
#include <stdbool.h>
#include <stdio.h>
#include "../parser/SolsNode.h"
@@ -207,6 +208,20 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
case SNT_LAMBDA: {
return Success(SolsType, charptr, node->as.type);
}
case SNT_FUNCTION_CALL: {
SolsVariable* var = findSolsVariable(scope, node->as.idName);
if (var == NULL) {
Estr estr = CREATE_ESTR("Unable to find function ");
APPEND_ESTR(estr, node->as.idName);
return Error(SolsType, charptr, estr.str);
}
if (var->typeinfo.type != STT_FUN) {
Estr estr = CREATE_ESTR(node->as.idName);
APPEND_ESTR(estr, " is not a callable function");
return Error(SolsType, charptr, estr.str);
}
return Success(SolsType, charptr, *var->typeinfo.returnType);
}
}
return Error(SolsType, charptr, "Not yet implemented");
}
@@ -786,6 +801,59 @@ ResultType(GroundProgram, charptr) generateDefNode(SolsNode* node, SolsScope* sc
return Success(GroundProgram, charptr, gp);
}
ResultType(GroundProgram, charptr) generateFunctionCallNode(SolsNode* node, SolsScope* scope) {
// Check whether the function exists and is callable
ResultType(SolsType, charptr) type = getNodeType(node, scope);
if (type.error) {
return Error(GroundProgram, charptr, type.as.error);
}
SolsVariable* var = findSolsVariable(scope, node->as.idName);
if (var == NULL) {
return Error(GroundProgram, charptr, "Could not find variable");
}
// Ensure the argument types match the function types
if (node->children.count != var->typeinfo.children.count) {
return Error(GroundProgram, charptr, "Incorrect amount of arguments for function");
}
for (size_t i = 0; i < node->children.count; i++) {
ResultType(SolsType, charptr) type = getNodeType(&node->children.at[i], scope);
if (type.error) {
return Error(GroundProgram, charptr, type.as.error);
}
if (compareTypes(&type.as.success, &var->typeinfo.children.at[i].type) == false) {
return Error(GroundProgram, charptr, "Types incorrect for function call");
}
}
// Now that everything seems to be fine, call the function
GroundInstruction gi = groundCreateInstruction(CALL);
groundAddReferenceToInstruction(&gi, groundCreateReference(FNREF, node->as.idName));
for (size_t i = 0; i < node->children.count; i++) {
groundAddReferenceToInstruction(&gi, node->children.at[i].accessArg);
}
char* returnStr = malloc(sizeof(char) * 64);
if (returnStr == NULL) {
return Error(GroundProgram, charptr, "Failed to allocate memory for tmp identifier");
}
snprintf(returnStr, 64, "__SOLS_TMP_CALL_%zu", scope->tmpCounter++);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, returnStr));
GroundProgram program = groundCreateProgram();
groundAddInstructionToProgram(&program, gi);
node->accessArg = groundCreateReference(VALREF, returnStr);
return Success(GroundProgram, charptr, program);
}
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
GroundProgram program = groundCreateProgram();
@@ -834,6 +902,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
case SNT_WHILE: generate(While);
case SNT_LAMBDA: generate(Lambda);
case SNT_DEF: generate(Def);
case SNT_FUNCTION_CALL: generate(FunctionCall);
}
return Success(GroundProgram, charptr, program);
}