compiler: can now implement functions

This commit is contained in:
2017-09-06 16:17:33 +02:00
parent e055cfe88f
commit a37ec816e6
2 changed files with 71 additions and 8 deletions

View File

@@ -1,3 +1,5 @@
(define x 1)
(display (sum x 1))
(define inc (lambda (n) (sum n 1)))
(display (inc x))

View File

@@ -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;
@@ -77,8 +130,16 @@ char* compile(sc_ast* ast) {
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;
}