forked from solstice/solstice
Start work on WASM compatibility, lambda fix
This commit is contained in:
@@ -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
|
||||
|
||||
50
src/main.c
50
src/main.c
@@ -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
81
src/wasm_main.c
Normal 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;
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user