compiler: can now implement functions
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
(define x 1)
|
||||
|
||||
(display (sum x 1))
|
||||
(define inc (lambda (n) (sum n 1)))
|
||||
|
||||
(display (inc x))
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user