Compile lambdas, no scoping yet

This commit is contained in:
2026-02-28 17:08:56 +11:00
parent e74c2ccd3e
commit 3a41b7a9cb
4 changed files with 105 additions and 7 deletions

View File

@@ -3,6 +3,7 @@
#include "SolsScope.h"
#include <groundvm.h>
#include <stdio.h>
#include "../parser/SolsNode.h"
#include "../include/estr.h"
@@ -11,6 +12,9 @@
// FIXME show multiple lines for the error
char* createCodegenError(SolsNode* node, char* what) {
if (node->line.content == NULL) {
return what;
}
Estr err = CREATE_ESTR(ESC_BOLD ESC_RED_FG "error: " ESC_RESET ESC_BOLD);
APPEND_ESTR(err, what);
APPEND_ESTR(err, "\n" ESC_RESET);
@@ -22,11 +26,7 @@ char* createCodegenError(SolsNode* node, char* what) {
APPEND_ESTR(err, line_buf);
APPEND_ESTR(err, "\n\n");
if (node->line.content == NULL) {
APPEND_ESTR(err, "(null line)");
} else {
APPEND_ESTR(err, node->line.content);
}
APPEND_ESTR(err, node->line.content);
APPEND_ESTR(err, "\n");
return err.str;
@@ -684,13 +684,54 @@ static inline ResultType(GroundProgram, charptr) generateIfNode(SolsNode* node,
return Success(GroundProgram, charptr, gp);
}
ResultType(GroundProgram, charptr) generateLambdaNode(SolsNode* node, SolsScope* scope) {
GroundProgram gp = groundCreateProgram();
// Generate function signature
GroundInstruction signature = groundCreateInstruction(FUN);
char* lambdaId = malloc(sizeof(char) * 64);
snprintf(lambdaId, 64, "__SOLS_LAMBDA_%zu", scope->tmpCounter++);
groundAddReferenceToInstruction(&signature, groundCreateReference(FNREF, lambdaId));
ResultType(GroundArg, charptr) arg = createGroundArgFromSolsType(node->as.type.returnType);
if (arg.error) {
return Error(GroundProgram, charptr, arg.as.error);
}
groundAddReferenceToInstruction(&signature, arg.as.success);
for (size_t i = 0; i < node->as.type.children.count; i++) {
// Add type
ResultType(GroundArg, charptr) arg = createGroundArgFromSolsType(&node->as.type.children.at[i].type);
if (arg.error) {
return Error(GroundProgram, charptr, arg.as.error);
}
groundAddReferenceToInstruction(&signature, arg.as.success);
// Add arg name
groundAddReferenceToInstruction(&signature, groundCreateReference(DIRREF, node->as.type.children.at[i].name));
}
groundAddInstructionToProgram(&gp, signature);
// Generate children and add then to this program
ResultType(GroundProgram, charptr) bodyCode = generateCode(&node->children.at[0], scope);
if (bodyCode.error) return bodyCode;
for (size_t i = 0; i < bodyCode.as.success.size; i++) {
groundAddInstructionToProgram(&gp, bodyCode.as.success.instructions[i]);
}
// End the function
groundAddInstructionToProgram(&gp, groundCreateInstruction(ENDFUN));
return Success(GroundProgram, charptr, gp);
}
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
GroundProgram program = groundCreateProgram();
SolsScope backupScope = {NULL, 0};
if (node->type != SNT_IF && node->type != SNT_WHILE) {
if (node->type != SNT_IF && node->type != SNT_WHILE && node->type != SNT_LAMBDA) {
if (node->type == SNT_CODE_BLOCK) {
backupScope = *scope;
SolsScope newScope = copySolsScope(scope);
@@ -730,6 +771,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
case SNT_CODE_BLOCK: generate(CodeBlock);
case SNT_IF: generate(If);
case SNT_WHILE: generate(While);
case SNT_LAMBDA: generate(Lambda);
}
return Success(GroundProgram, charptr, program);
}