Start work on function calling
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user