diff --git a/examples/test.lisp b/examples/test.lisp index 1b9f966..b2f783b 100644 --- a/examples/test.lisp +++ b/examples/test.lisp @@ -1,3 +1,5 @@ (define x 1) -(display (sum x 1)) +(define inc (lambda (n) (sum n 1))) + +(display (inc x)) diff --git a/src/compiler.c b/src/compiler.c index a64f1e0..18ac00b 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1,5 +1,13 @@ #include "compiler.h" +typedef struct sc_global { + sc_ast* ast; + char* name; +} sc_global; + +int n_globals = 0; +sc_global** globals = NULL; + char* get_prelude() { char* str; size_t size; @@ -25,7 +33,25 @@ char* get_prelude() { char* compile_expr(sc_ast* ast); +void add_global(char* name, sc_ast* ast) { + globals = realloc(globals, ++n_globals*sizeof(sc_global*)); + sc_global* g = malloc(sizeof(sc_global)); + g->name = name; + g->ast = ast; + globals[n_globals-1] = g; +} + +char* compile_lambda(sc_ast* ast) { + char* name = ast->children[1]->value; + add_global(name, ast->children[2]); + return NULL; +} + char* compile_define(sc_ast* ast) { + if (ast->children[2]->tag == LIST && + !(strcmp(ast->children[2]->children[0]->value, "lambda"))) { + return compile_lambda(ast); + } char* rhs = compile_expr(ast->children[2]); char* name = ast->children[1]->value; char* res = malloc(strlen(rhs)+strlen(name)+10); @@ -60,6 +86,33 @@ char* compile_list(sc_ast* ast) { return res; } +char* compile_global(sc_global* global) { + int i; + char* tmp; + char* res = malloc(strlen(global->name)+18); + sprintf(res, "Value %s(", global->name); + int reslen = strlen(res)+1; + + sc_ast* args = global->ast->children[1]; + for (i = 0; i < args->n_children; i++) { + if (i > 0) { + reslen += strlen(args->children[i]->value)+8; + res = realloc(res, reslen); + snprintf(res, reslen, "%s, Value %s", res, args->children[i]->value); + } else { + reslen += strlen(args->children[i]->value)+6; + res = realloc(res, reslen); + snprintf(res, reslen, "%sValue %s", res, args->children[i]->value); + } + } + tmp = compile_expr(global->ast->children[2]); + reslen += strlen(tmp)+14; + res = realloc(res, reslen); + snprintf(res, reslen, "%s) { return %s; }", res, tmp); + + return res; +} + char* compile(sc_ast* ast) { int i; char* tmp; @@ -70,15 +123,23 @@ char* compile(sc_ast* ast) { int reslen = strlen(res)+1; for (i = 0; i < ast->n_children; i++) { - tmp = compile_expr(ast->children[i]); - if (!tmp) continue; - mainlen += strlen(tmp)+1; - main = realloc(main, mainlen); - snprintf(main, mainlen, "%s;%s", main, tmp); + tmp = compile_expr(ast->children[i]); + if (!tmp) continue; + mainlen += strlen(tmp)+1; + main = realloc(main, mainlen); + snprintf(main, mainlen, "%s;%s", main, tmp); } - res = realloc(res, reslen+mainlen+2); - snprintf(res, reslen+mainlen+2, "%s;%s;}", res, main); + for (i = 0; i < n_globals; i++) { + tmp = compile_global(globals[i]); + if (!tmp) continue; + reslen += strlen(tmp); + res = realloc(res, reslen); + snprintf(res, reslen, "%s%s", res, tmp); + } + + res = realloc(res, reslen+mainlen+1); + snprintf(res, reslen+mainlen+1, "%s%s;}", res, main); return res; }