compiler: can now implement functions
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
(define x 1)
|
(define x 1)
|
||||||
|
|
||||||
(display (sum x 1))
|
(define inc (lambda (n) (sum n 1)))
|
||||||
|
|
||||||
|
(display (inc x))
|
||||||
|
@@ -1,5 +1,13 @@
|
|||||||
#include "compiler.h"
|
#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* get_prelude() {
|
||||||
char* str;
|
char* str;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -25,7 +33,25 @@ char* get_prelude() {
|
|||||||
|
|
||||||
char* compile_expr(sc_ast* ast);
|
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) {
|
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* rhs = compile_expr(ast->children[2]);
|
||||||
char* name = ast->children[1]->value;
|
char* name = ast->children[1]->value;
|
||||||
char* res = malloc(strlen(rhs)+strlen(name)+10);
|
char* res = malloc(strlen(rhs)+strlen(name)+10);
|
||||||
@@ -60,6 +86,33 @@ char* compile_list(sc_ast* ast) {
|
|||||||
return res;
|
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) {
|
char* compile(sc_ast* ast) {
|
||||||
int i;
|
int i;
|
||||||
char* tmp;
|
char* tmp;
|
||||||
@@ -70,15 +123,23 @@ char* compile(sc_ast* ast) {
|
|||||||
int reslen = strlen(res)+1;
|
int reslen = strlen(res)+1;
|
||||||
|
|
||||||
for (i = 0; i < ast->n_children; i++) {
|
for (i = 0; i < ast->n_children; i++) {
|
||||||
tmp = compile_expr(ast->children[i]);
|
tmp = compile_expr(ast->children[i]);
|
||||||
if (!tmp) continue;
|
if (!tmp) continue;
|
||||||
mainlen += strlen(tmp)+1;
|
mainlen += strlen(tmp)+1;
|
||||||
main = realloc(main, mainlen);
|
main = realloc(main, mainlen);
|
||||||
snprintf(main, mainlen, "%s;%s", main, tmp);
|
snprintf(main, mainlen, "%s;%s", main, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = realloc(res, reslen+mainlen+2);
|
for (i = 0; i < n_globals; i++) {
|
||||||
snprintf(res, reslen+mainlen+2, "%s;%s;}", res, main);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user