Start work on WASM compatibility, lambda fix

This commit is contained in:
2026-03-06 09:24:16 +11:00
parent 00ef8a7d56
commit 41a2fa53c6
4 changed files with 122 additions and 25 deletions

View File

@@ -735,6 +735,8 @@ ResultType(GroundProgram, charptr) generateLambdaNode(SolsNode* node, SolsScope*
// Create a scope for lambda arguments
SolsScope lambdaScope = copySolsScope(scope);
// Set the scope's return type
lambdaScope.returnType = *node->as.type.returnType;
for (size_t i = 0; i < node->as.type.children.count; i++) {
addVariableToScope(&lambdaScope, node->as.type.children.at[i].name, node->as.type.children.at[i].type);
@@ -924,13 +926,13 @@ ResultType(GroundProgram, charptr) generateUseNode(SolsNode* node, SolsScope* sc
if (lexer.error) {
printf("While lexing file %s:\n", filePath.str);
printf("Error while creating lexer: %s", lexer.as.error);
exit(1);
return Error(GroundProgram, charptr, "Error with use");
}
ResultType(Nothing, charptr) lexed = lex(&lexer.as.success);
if (lexed.error) {
printf("While lexing file %s:\n", filePath.str);
printf("%s\n", lexed.as.error);
exit(1);
return Error(GroundProgram, charptr, "Error with use");
}
// Parse file
@@ -938,13 +940,13 @@ ResultType(GroundProgram, charptr) generateUseNode(SolsNode* node, SolsScope* sc
if (parser.error) {
printf("While parsing file %s:\n", filePath.str);
printf("Error while creating parser: %s\n", parser.as.error);
exit(1);
return Error(GroundProgram, charptr, "Error with use");
}
ResultType(Nothing, charptr) parsed = parse(&parser.as.success);
if (parsed.error) {
printf("While parsing file %s:\n", filePath.str);
printf("%s\n", parsed.as.error);
exit(1);
return Error(GroundProgram, charptr, "Error with use");
}
SolsScope newScope = {
@@ -958,7 +960,7 @@ ResultType(GroundProgram, charptr) generateUseNode(SolsNode* node, SolsScope* sc
if (codegen.error) {
printf("While generating code for file %s:\n", filePath.str);
printf("%s\n", codegen.as.error);
exit(1);
return Error(GroundProgram, charptr, "Error with use");
}
// Insert all the stuff into our scope

View File

@@ -15,7 +15,7 @@
#include <groundvm.h>
typedef enum SolsAction {
SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE
SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE, SA_EXIT, SA_EXITOK
} SolsAction;
typedef struct Args {
@@ -41,7 +41,8 @@ Args parseArgs(int argc, char** argv) {
printf(" -b <file> or --bytecode <file>: Generates Ground bytecode (.grbc) and saves it to the provided filename\n");
printf(" -c <file> or --compile <file>: Compiles Ground to Linux x86_64 assembly, outputs a binary to the provided filename (experimental)\n");
printf(" If no extra arguments are provided, the generated Ground bytecode will be executed.\n");
exit(0);
args.action = SA_EXIT;
return args;
}
else if (strcmp("-p", argv[i]) == 0 || strcmp("--print", argv[i]) == 0) {
args.action = SA_PRINT;
@@ -49,12 +50,14 @@ Args parseArgs(int argc, char** argv) {
else if (strcmp("-b", argv[i]) == 0 || strcmp("--bytecode", argv[i]) == 0) {
if (args.action != SA_EXEC) {
printf("Expecting only one action\n");
exit(1);
args.action = SA_EXIT;
return args;
}
args.action = SA_BYTECODE;
if (i + 1 >= argc) {
printf("Expecting file name after %s\n", argv[i]);
exit(1);
args.action = SA_EXIT;
return args;
}
i++;
args.outputFile = argv[i];
@@ -62,12 +65,14 @@ Args parseArgs(int argc, char** argv) {
else if (strcmp("-c", argv[i]) == 0 || strcmp("--compile", argv[i]) == 0) {
if (args.action != SA_EXEC) {
printf("Expecting only one action\n");
exit(1);
args.action = SA_EXIT;
return args;
}
args.action = SA_COMPILE;
if (i + 1 >= argc) {
printf("Expecting file name after %s\n", argv[i]);
exit(1);
args.action = SA_EXIT;
return args;
}
i++;
args.outputFile = argv[i];
@@ -79,7 +84,8 @@ Args parseArgs(int argc, char** argv) {
if (args.inputFile == NULL) {
printf("Usage: %s <file> [-h] [--help] [-p] [--print] [-b <file>] [--bytecode <file>] [-c <file>] [--compile <file>]\n", argv[0]);
exit(1);
args.action = SA_EXIT;
return args;
}
return args;
@@ -94,7 +100,7 @@ char* getFileContents(const char* filename) {
fp = fopen(filename, "rb");
if (!fp) {
perror(filename);
exit(1);
return NULL;
}
fseek(fp, 0L, SEEK_END);
@@ -121,42 +127,50 @@ char* getFileContents(const char* filename) {
int main(int argc, char** argv) {
Args args = parseArgs(argc, argv);
if (args.action == SA_EXIT) {
return 1;
}
if (args.action == SA_EXITOK) {
return 0;
}
char* fileContents = getFileContents(args.inputFile);
if (fileContents == NULL) {
printf("Couldn't read that file :(\n");
exit(1);
return 1;
}
// Lex file
ResultType(SolsLexer, charptr) lexer = createLexer(fileContents);
if (lexer.error) {
printf("Error while creating lexer: %s", lexer.as.error);
exit(1);
return 1;
}
ResultType(Nothing, charptr) lexed = lex(&lexer.as.success);
if (lexed.error) {
printf("%s\n", lexed.as.error);
exit(1);
return 1;
}
// Detect and parse types
ResultType(SolsTokens, charptr) typed = addTypeInfo(&lexer.as.success.output);
if (typed.error) {
printf("%s\n", typed.as.error);
exit(1);
return 1;
}
// Parse file
ResultType(SolsParser, charptr) parser = createSolsParser(&typed.as.success);
if (parser.error) {
printf("Error while creating parser: %s\n", parser.as.error);
exit(1);
return 1;
}
ResultType(Nothing, charptr) parsed = parse(&parser.as.success);
if (parsed.error) {
printf("%s\n", parsed.as.error);
exit(1);
return 1;
}
SolsScope scope = {
@@ -169,7 +183,7 @@ int main(int argc, char** argv) {
ResultType(GroundProgram, charptr) codegen = generateCode(&parser.as.success.output, &scope);
if (codegen.error) {
printf("%s\n", codegen.as.error);
exit(1);
return 1;
}
switch (args.action) {
@@ -204,7 +218,7 @@ int main(int argc, char** argv) {
#endif
if (dirstatus != 0) {
printf("Couldn't create temporary work directory\n");
exit(1);
return 1;
}
// Write generated asm to .s
@@ -227,7 +241,7 @@ int main(int argc, char** argv) {
int nasmstatus = system(nasmcmd.str);
if (nasmstatus != 0) {
printf("command \"%s\" exited with code %d\n", nasmcmd.str, nasmstatus);
exit(1);
return 1;
}
// Link with ld
@@ -240,7 +254,7 @@ int main(int argc, char** argv) {
int ldstatus = system(ldcmd.str);
if (ldstatus != 0) {
printf("command \"%s\" exited with code %d\n", ldcmd.str, ldstatus);
exit(1);
return 1;
}
// Yay we compiled it

81
src/wasm_main.c Normal file
View File

@@ -0,0 +1,81 @@
#include <emscripten.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "lexer/lexer.h"
#include "typeparser/typeparser.h"
#include "parser/parser.h"
#include "codegen/codegen.h"
#include <groundvm.h>
static char out_buf[65536];
static int out_pos = 0;
// Defined by Ground
void wasm_print(const char* str);
EMSCRIPTEN_KEEPALIVE
const char* solstice_run(char* source) {
out_pos = 0;
out_buf[0] = '\0';
// 1. Lex
ResultType(SolsLexer, charptr) lexer = createLexer(source);
if (lexer.error) {
snprintf(out_buf, sizeof(out_buf),
"[lex error] %s", lexer.as.error);
return out_buf;
}
ResultType(Nothing, charptr) lexed = lex(&lexer.as.success);
if (lexed.error) {
snprintf(out_buf, sizeof(out_buf), "%s", lexed.as.error);
return out_buf;
}
// 2. Type parse
ResultType(SolsTokens, charptr) typed = addTypeInfo(&lexer.as.success.output);
if (typed.error) {
snprintf(out_buf, sizeof(out_buf), "%s", typed.as.error);
return out_buf;
}
// 3. Parse
ResultType(SolsParser, charptr) parser = createSolsParser(&typed.as.success);
if (parser.error) {
snprintf(out_buf, sizeof(out_buf),
"[parse error] %s", parser.as.error);
return out_buf;
}
ResultType(Nothing, charptr) parsed = parse(&parser.as.success);
if (parsed.error) {
snprintf(out_buf, sizeof(out_buf), "%s", parsed.as.error);
return out_buf;
}
// 4. Codegen
SolsScope scope = {
.variables = NULL,
.tmpCounter = 0,
.returnType = createSolsType(STT_INT).as.success
};
ResultType(GroundProgram, charptr) codegen =
generateCode(&parser.as.success.output, &scope);
if (codegen.error) {
snprintf(out_buf, sizeof(out_buf), "%s", codegen.as.error);
return out_buf;
}
// 5. Run
GroundValue retval = groundRunProgram(&codegen.as.success);
if (out_pos == 0) {
// Program produced no output — report exit code
snprintf(out_buf, sizeof(out_buf),
"[exited with code %d]",
retval.type == INT ? retval.data.intVal : 0);
}
return out_buf;
}

View File

@@ -1,9 +1,9 @@
def createClosure(int x) fun(int) int {
return lambda(int y) int {
x + y
return x + y
}
}
myVar = createClosure(5)
puts myVar(3)
puts myVar(3)