Compile lambdas, no scoping yet
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include "SolsScope.h"
|
#include "SolsScope.h"
|
||||||
|
|
||||||
#include <groundvm.h>
|
#include <groundvm.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../parser/SolsNode.h"
|
#include "../parser/SolsNode.h"
|
||||||
#include "../include/estr.h"
|
#include "../include/estr.h"
|
||||||
@@ -11,6 +12,9 @@
|
|||||||
|
|
||||||
// FIXME show multiple lines for the error
|
// FIXME show multiple lines for the error
|
||||||
char* createCodegenError(SolsNode* node, char* what) {
|
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);
|
Estr err = CREATE_ESTR(ESC_BOLD ESC_RED_FG "error: " ESC_RESET ESC_BOLD);
|
||||||
APPEND_ESTR(err, what);
|
APPEND_ESTR(err, what);
|
||||||
APPEND_ESTR(err, "\n" ESC_RESET);
|
APPEND_ESTR(err, "\n" ESC_RESET);
|
||||||
@@ -22,11 +26,7 @@ char* createCodegenError(SolsNode* node, char* what) {
|
|||||||
APPEND_ESTR(err, line_buf);
|
APPEND_ESTR(err, line_buf);
|
||||||
APPEND_ESTR(err, "\n\n");
|
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");
|
APPEND_ESTR(err, "\n");
|
||||||
|
|
||||||
return err.str;
|
return err.str;
|
||||||
@@ -684,13 +684,54 @@ static inline ResultType(GroundProgram, charptr) generateIfNode(SolsNode* node,
|
|||||||
return Success(GroundProgram, charptr, gp);
|
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) {
|
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
|
||||||
|
|
||||||
GroundProgram program = groundCreateProgram();
|
GroundProgram program = groundCreateProgram();
|
||||||
|
|
||||||
SolsScope backupScope = {NULL, 0};
|
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) {
|
if (node->type == SNT_CODE_BLOCK) {
|
||||||
backupScope = *scope;
|
backupScope = *scope;
|
||||||
SolsScope newScope = copySolsScope(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_CODE_BLOCK: generate(CodeBlock);
|
||||||
case SNT_IF: generate(If);
|
case SNT_IF: generate(If);
|
||||||
case SNT_WHILE: generate(While);
|
case SNT_WHILE: generate(While);
|
||||||
|
case SNT_LAMBDA: generate(Lambda);
|
||||||
}
|
}
|
||||||
return Success(GroundProgram, charptr, program);
|
return Success(GroundProgram, charptr, program);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "../include/error.h"
|
#include "../include/error.h"
|
||||||
#include "../include/estr.h"
|
#include "../include/estr.h"
|
||||||
|
#include <groundvm.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
ResultType(SolsType, charptr) createSolsType(SolsTypeType in) {
|
ResultType(SolsType, charptr) createSolsType(SolsTypeType in) {
|
||||||
@@ -142,3 +143,34 @@ bool compareTypes(SolsType* left, SolsType* right) {
|
|||||||
default: return true;
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type) {
|
||||||
|
switch (type->type) {
|
||||||
|
case STT_INT: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "int"));
|
||||||
|
}
|
||||||
|
case STT_DOUBLE: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "double"));
|
||||||
|
}
|
||||||
|
case STT_STRING: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "string"));
|
||||||
|
}
|
||||||
|
case STT_BOOL: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "bool"));
|
||||||
|
}
|
||||||
|
case STT_CHAR: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "char"));
|
||||||
|
}
|
||||||
|
case STT_FUN: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "function"));
|
||||||
|
}
|
||||||
|
case STT_TEMPLATE: {
|
||||||
|
return Success(GroundArg, charptr, groundCreateReference(TYPEREF, "struct"));
|
||||||
|
}
|
||||||
|
case STT_OBJECT: {
|
||||||
|
// FIXME Do this later
|
||||||
|
return Error(GroundArg, charptr, "FIXME");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Error(GroundArg, charptr, "How did we get here?");
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SOLSTYPE_H
|
#define SOLSTYPE_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <groundvm.h>
|
||||||
|
|
||||||
#include "../include/error.h"
|
#include "../include/error.h"
|
||||||
#include "../include/nothing.h"
|
#include "../include/nothing.h"
|
||||||
@@ -90,6 +91,11 @@ ResultType(Nothing, charptr) addChildToSolsType(SolsType* type, SolsType child,
|
|||||||
// Makes a deep copy of a SolsType.
|
// Makes a deep copy of a SolsType.
|
||||||
ResultType(SolsType, charptr) copySolsType(SolsType* type);
|
ResultType(SolsType, charptr) copySolsType(SolsType* type);
|
||||||
|
|
||||||
|
Result(GroundArg, charptr);
|
||||||
|
|
||||||
|
// Represents a SolsType as a GroundArg (in typeref form)
|
||||||
|
ResultType(GroundArg, charptr) createGroundArgFromSolsType(SolsType* type);
|
||||||
|
|
||||||
// Frees a SolsType
|
// Frees a SolsType
|
||||||
void freeSolsType(SolsType* type);
|
void freeSolsType(SolsType* type);
|
||||||
|
|
||||||
|
|||||||
20
src/main.c
20
src/main.c
@@ -46,7 +46,20 @@ int main(int argc, char** argv) {
|
|||||||
printf("Usage: %s [file]\n", argv[0]);
|
printf("Usage: %s [file]\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
char* fileContents = getFileContents(argv[1]);
|
|
||||||
|
char* fileContents = NULL;
|
||||||
|
bool printProgram = false;
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "-p") == 0) {
|
||||||
|
if (argc < 3) {
|
||||||
|
printf("Usage: %s -p [file]\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printProgram = true;
|
||||||
|
fileContents = getFileContents(argv[2]);
|
||||||
|
} else {
|
||||||
|
fileContents = getFileContents(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
// Lex file
|
// Lex file
|
||||||
ResultType(SolsLexer, charptr) lexer = createLexer(fileContents);
|
ResultType(SolsLexer, charptr) lexer = createLexer(fileContents);
|
||||||
@@ -84,6 +97,11 @@ int main(int argc, char** argv) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (printProgram) {
|
||||||
|
groundPrintProgram(&codegen.as.success);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Run program on GroundVM
|
// Run program on GroundVM
|
||||||
GroundValue retval = groundRunProgram(&codegen.as.success);
|
GroundValue retval = groundRunProgram(&codegen.as.success);
|
||||||
if (retval.type == INT) {
|
if (retval.type == INT) {
|
||||||
|
|||||||
Reference in New Issue
Block a user