From: Michael D. Lowis Date: Tue, 14 Oct 2014 02:10:31 +0000 (-0400) Subject: implemented code generation for expressions X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=9c7c7beb631b4990ac56b7b7dfa48e450affca55;p=proto%2Fsclpl.git implemented code generation for expressions --- diff --git a/source/sclpl/codegen.c b/source/sclpl/codegen.c index a1575cd..800a366 100644 --- a/source/sclpl/codegen.c +++ b/source/sclpl/codegen.c @@ -44,6 +44,11 @@ static bool is_formtype(tree_t* p_tree, const char* val) { /*****************************************************************************/ +static void print_indent(int depth) { + for(int i = 0; i < (4 * depth); i++) + printf("%c", ' '); +} + static void emit_header(void) { puts("#include \n"); } @@ -58,23 +63,77 @@ static void emit_fn_signature(char* name, tree_t* fnval) { } printf(")"); } + static void emit_def_placeholders(vec_t* prgrm) { for (size_t idx = 0; idx < vec_size(prgrm); idx++) { tree_t* p_tree = (tree_t*)vec_at(prgrm, idx); if (is_formtype(p_tree, "def")) { - char* name = (char*)get_child_val(p_tree,1); - tree_t* value = get_child(p_tree, 2); - if (is_formtype(value, "fn")) { - emit_fn_signature(name, value); - puts(";"); - } else { - printf("val %s;\n", (char*)get_child_val(p_tree,1)); - } + printf("val %s;\n", (char*)get_child_val(p_tree,1)); } } puts(""); } +static void emit_expression(tree_t* p_tree, int depth) { + if (p_tree->tag == ATOM) { + lex_tok_t* tok = p_tree->ptr.tok; + switch (tok->type) { + case T_STRING: printf("'%s'", ((char*)tok->value)); break; + case T_CHAR: printf("\\%c", ((char)(int)tok->value)); break; + case T_INT: printf("%ld", *((long int*)tok->value)); break; + case T_FLOAT: printf("%f", *((double*)tok->value)); break; + case T_BOOL: printf("%s", ((int)tok->value)?"true":"false"); break; + case T_VAR: printf("%s", ((char*)tok->value)); break; + } + } else if (is_formtype(p_tree, "if")) { + printf("IF("); + emit_expression(get_child(p_tree, 1), depth); + printf(")\n"); + print_indent(depth+1); + emit_expression(get_child(p_tree, 2), depth+1); + + if (vec_size(p_tree->ptr.vec) > 3) { + printf("\n"); + print_indent(depth); + printf("ELSE\n"); + print_indent(depth+1); + emit_expression(get_child(p_tree, 4), depth+1); + } + + } else if (is_formtype(p_tree, "fn")) { + printf(""); + } else { + vec_t* vec = p_tree->ptr.vec; + printf("%s(", (char*)get_val(vec_at(vec,0))); + for (size_t idx = 1; idx < vec_size(vec); idx++) { + emit_expression((tree_t*)vec_at(vec,idx), depth); + if (idx+1 < vec_size(vec)) + printf(", "); + } + printf(")"); + } +} + +static void emit_toplevel(vec_t* prgrm) { + puts("void toplevel(void) {"); + for (size_t idx = 0; idx < vec_size(prgrm); idx++) { + tree_t* p_tree = (tree_t*)vec_at(prgrm, idx); + if (is_formtype(p_tree, "require")) { + printf(" extern void %s_toplevel(void);\n", (char*)get_child_val(p_tree,1)); + printf(" %s_toplevel();\n", (char*)get_child_val(p_tree,1)); + } else if (is_formtype(p_tree, "def")) { + printf(" %s = ", (char*)get_child_val(p_tree,1)); + emit_expression(get_child(p_tree, 2), 0); + printf(";\n"); + } else { + printf(" "); + emit_expression(p_tree, 1); + printf(";\n"); + } + } + puts("}"); +} + static void emit_footer(void) { } @@ -82,5 +141,6 @@ static void emit_footer(void) { void codegen_csource(FILE* file, vec_t* program) { emit_header(); emit_def_placeholders(program); + emit_toplevel(program); emit_footer(); }