From: Michael D. Lowis Date: Sat, 19 May 2018 01:14:31 +0000 (-0400) Subject: removed anf and C code generation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4d1c6a64f76d921e4ba1692b9492822726725bc2;p=proto%2Fsclpl.git removed anf and C code generation --- diff --git a/Makefile b/Makefile index 8136bc9..c48689d 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,7 @@ OBJS = source/main.o \ source/pprint.o \ source/parser.o \ source/lexer.o \ - source/ast.o \ - source/anf.o \ - source/codegen.o + source/ast.o TESTBIN = testsclpl TESTOBJS = tests/atf.o \ diff --git a/source/anf.c b/source/anf.c deleted file mode 100644 index 0ded73a..0000000 --- a/source/anf.c +++ /dev/null @@ -1,132 +0,0 @@ -#include - -static bool isatomic(AST* tree) -{ - switch (tree->type) { - case AST_STRING: - case AST_SYMBOL: - case AST_IDENT: - case AST_CHAR: - case AST_INT: - case AST_FLOAT: - case AST_BOOL: - case AST_FUNC: - case AST_TEMP: - return true; - default: - return false; - } -} - -static bool isconst(AST* tree) { - bool ret = isatomic(tree); - if (!ret && tree->type == AST_FNAPP) { - ret = isatomic(fnapp_fn(tree)); - for (int i = 0; i < vec_size(fnapp_args(tree)); i++) { - ret = ret && isatomic(vec_at(fnapp_args(tree), i)); - } - } - return ret; -} - -static AST* normalize_def(AST* tree) -{ - Tok name = { .value.text = def_name(tree) }; - return Def(&name, normalize(def_value(tree))); -} - -static AST* normalize_fnapp(AST* tree) -{ - AST* normalized = tree; - AST* fn = fnapp_fn(tree); - /* Normalize the function */ - if (!isatomic(fn)) { - AST* temp = TempVar(); - fnapp_set_fn(tree, temp); - normalized = Let(temp, fn, tree); - } - /* Normalize the function arguments */ - vec_t temps; - vec_init(&temps); - vec_t* args = fnapp_args(tree); - for (int i = 0; i < vec_size(args); i++) { - AST* arg = (AST*)vec_at(args, i); - if (!isatomic(arg)) { - AST* temp = TempVar(); - vec_push_back(&temps, Let(temp, arg, NULL)); - vec_set(args, i, temp); - } - } - /* Nest all the scopes and return the new form */ - for (int i = vec_size(&temps); i > 0; i--) { - AST* let = (AST*)vec_at(&temps,i-1); - let_set_body(let, normalized); - normalized = let; - } - vec_deinit(&temps); - return normalized; -} - -static AST* normalize_if(AST* tree) -{ - AST* cond = normalize(ifexpr_cond(tree)); - AST* thenbr = normalize(ifexpr_then(tree)); - AST* elsebr = normalize(ifexpr_else(tree)); - if (!isatomic(cond)) { - AST* temp = TempVar(); - AST* body = IfExpr(); - ifexpr_set_cond(body, temp); - ifexpr_set_then(body, thenbr); - ifexpr_set_else(body, elsebr); - tree = Let(temp, cond, body); - } else { - tree = IfExpr(); - ifexpr_set_cond(tree, cond); - ifexpr_set_then(tree, thenbr); - ifexpr_set_else(tree, elsebr); - } - return tree; -} - -static AST* normalize_func(AST* tree) -{ - func_set_body(tree, normalize(func_body(tree))); - return tree; -} - -static AST* normalize_let(AST* tree) -{ - AST* var = let_var(tree); - AST* val = normalize(let_val(tree)); - AST* body = normalize(let_body(tree)); - /* Find the inner most let block */ - if (val->type == AST_IF && isatomic(body)) { - tree = val; - } else if (!isconst(val)) { - AST* let = val; - while (let->type == AST_LET && let_body(let)->type == AST_LET) - let = let_body(let); - let_set_body(let, Let(var, let_body(let), body)); - tree = let; - } else { - tree = Let(var, val, body); - } - return tree; -} - -AST* normalize(AST* tree) -{ - if (NULL == tree) - return tree; - switch (tree->type) - { - case AST_DEF: tree = normalize_def(tree); break; - case AST_FNAPP: tree = normalize_fnapp(tree); break; - case AST_IF: tree = normalize_if(tree); break; - case AST_FUNC: tree = normalize_func(tree); break; - case AST_LET: tree = normalize_let(tree); break; - default: break; - } - return tree; -} - diff --git a/source/codegen.c b/source/codegen.c deleted file mode 100644 index 32b6f0d..0000000 --- a/source/codegen.c +++ /dev/null @@ -1,107 +0,0 @@ -#include - -void codegen(FILE* file, AST* tree) -{ - switch(tree->type) { - case AST_STRING: - fprintf(file, "\"%s\"", string_value(tree)); - break; - - case AST_SYMBOL: - //fprintf(file, "__symbol(\"%s\")", symbol_value(tree)); - break; - - case AST_CHAR: - //fprintf(file, "'%s'", char_value(tree)); - break; - - case AST_INT: - fprintf(file, "%ld", integer_value(tree)); - break; - - case AST_FLOAT: - fprintf(file, "%f", float_value(tree)); - break; - - case AST_BOOL: - fprintf(file, "%s", bool_value(tree) ? "true" : "false"); - break; - - case AST_IDENT: - fprintf(file, "%s", ident_value(tree)); - break; - - case AST_TEMP: - fprintf(file, "_t%lu", temp_value(tree)); - break; - - case AST_DEF: - if (def_value(tree)->type == AST_FUNC) { - fprintf(file, "val %s", def_name(tree)); - codegen(file, def_value(tree)); - } else { - fprintf(file, "val %s", def_name(tree)); - fprintf(file, " = "); - codegen(file, def_value(tree)); - fprintf(file, ";"); - } - break; - - case AST_IF: - fprintf(file," if ("); - codegen(file, ifexpr_cond(tree)); - fprintf(file,")\n"); - codegen(file, ifexpr_then(tree)); - if (ifexpr_else(tree)) { - fprintf(file,"\n else\n"); - codegen(file, ifexpr_else(tree)); - } else { - fprintf(file," {return nil;}"); - } - break; - - case AST_FUNC: - fprintf(file,"("); - for (size_t i = 0; i < vec_size(func_args(tree)); i++) { - fprintf(file,"val "); - codegen(file, vec_at(func_args(tree), i)); - if (i+1 < vec_size(func_args(tree))) - fprintf(file,", "); - } - fprintf(file,") {\n"); - codegen(file, func_body(tree)); - fprintf(file,"\n}\n"); - break; - - case AST_FNAPP: - codegen(file, fnapp_fn(tree)); - fprintf(file,"("); - for (size_t i = 0; i < vec_size(fnapp_args(tree)); i++) { - codegen(file, vec_at(fnapp_args(tree), i)); - if (i+1 < vec_size(fnapp_args(tree))) - fprintf(file,","); - } - fprintf(file,")"); - break; - - case AST_LET: - fprintf(file," {val "); - codegen(file, let_var(tree)); - fprintf(file," = "); - codegen(file, let_val(tree)); - fprintf(file,";\n"); - if (let_body(tree)->type != AST_LET && let_body(tree)->type != AST_IF) { - fprintf(file," return "); - codegen(file, let_body(tree)); - fprintf(file,";"); - } else { - codegen(file, let_body(tree)); - } - fprintf(file,"}"); - break; - - case AST_REQ: - default: - break; - } -} diff --git a/source/main.c b/source/main.c index ffc00b7..eac36db 100644 --- a/source/main.c +++ b/source/main.c @@ -22,31 +22,7 @@ static int emit_ast(void) { return 0; } -static int emit_anf(void) { - AST* tree = NULL; - Parser* ctx = parser_new(NULL, stdin); - while(NULL != (tree = toplevel(ctx))) - pprint_tree(stdout, normalize(tree), 0); - return 0; -} - -static int emit_csource(void) { - AST* tree = NULL; - Parser* ctx = parser_new(NULL, stdin); - while(NULL != (tree = normalize(toplevel(ctx)))) - codegen(stdout, tree); - return 0; -} - -static int emit_object(void) { - return 0; -} - -static int emit_staticlib(void) { - return 0; -} - -static int emit_program(void) { +static int emit_binary(void) { return 0; } @@ -75,14 +51,8 @@ int user_main(int argc, char **argv) { return emit_tokens(); } else if (0 == strcmp("ast", Artifact)) { return emit_ast(); - } else if (0 == strcmp("anf", Artifact)) { - return emit_anf(); - } else if (0 == strcmp("src", Artifact)) { - return emit_csource(); } else if (0 == strcmp("bin", Artifact)) { - return emit_program(); - } else if (0 == strcmp("lib", Artifact)) { - return emit_staticlib(); + return emit_binary(); } else { fprintf(stderr, "Unknonwn artifact type: '%s'\n\n", Artifact); usage(); diff --git a/spec/anf_spec.rb b/spec/anf_spec.rb deleted file mode 100644 index ad132a7..0000000 --- a/spec/anf_spec.rb +++ /dev/null @@ -1,200 +0,0 @@ -require 'open3' - -describe "sclpl a-normal form" do - context "literals" do - it "strings should remain untouched" do - expect(anf('"foo"')).to eq(['T_STRING:"foo"']) - end - - it "characters should remain untouched" do - expect(anf('\\c')).to eq(['T_CHAR:c']) - end - - it "integers should remain untouched" do - expect(anf('123')).to eq(['T_INT:123']) - end - - it "floats should remain untouched" do - expect(anf('123.0')).to eq(['T_FLOAT:123.000000']) - end - - it "booleans should remain untouched" do - expect(anf('true')).to eq(['T_BOOL:true']) - end - - it "ids should remain untouched" do - expect(anf('foo')).to eq(['T_ID:foo']) - end - end - - context "definitions" do - it "should leave atomic defintions alone" do - expect(anf('def foo 123;')).to eq([ - ["def", "foo", "T_INT:123"] - ]) - end - - it "should leave normalize complex defintions" do - expect(anf('def foo bar();')).to eq([ - ["def", "foo", ["T_ID:bar"]] - ]) - end - end - - context "function applications" do - it "should leave an application with no args alone" do - expect(anf('foo()')).to eq([ - ['T_ID:foo'] - ]) - end - - it "should leave an application with one arg alone" do - expect(anf('foo(a)')).to eq([ - ['T_ID:foo', 'T_ID:a'] - ]) - end - - it "should normalize an application with a complex function" do - expect(anf('(foo())()')).to eq([ - ['let', ['$:0', ['T_ID:foo']], - ['$:0']] - ]) - end - - it "should normalize an application with a complex arg" do - expect(anf('foo(bar())')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['T_ID:foo', '$:0']] - ]) - end - - it "should normalize an application with two complex args" do - expect(anf('foo(bar(),baz())')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['let', ['$:1', ['T_ID:baz']], - ['T_ID:foo', '$:0', '$:1']]] - ]) - end - - it "should normalize an application with three complex args" do - expect(anf('foo(bar(),baz(),boo())')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['let', ['$:1', ['T_ID:baz']], - ['let', ['$:2', ['T_ID:boo']], - ['T_ID:foo', '$:0', '$:1', '$:2']]]] - ]) - end - - it "should normalize an application with simple and complex args (s,c,c)" do - expect(anf('foo(a,bar(),baz())')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['let', ['$:1', ['T_ID:baz']], - ['T_ID:foo', 'T_ID:a', '$:0', '$:1']]] - ]) - end - - it "should normalize an application with simple and complex args (c,s,c)" do - expect(anf('foo(bar(),a,baz())')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['let', ['$:1', ['T_ID:baz']], - ['T_ID:foo', '$:0', 'T_ID:a', '$:1']]] - ]) - end - - it "should normalize an application with simple and complex args (c,c,s)" do - expect(anf('foo(bar(),baz(),a)')).to eq([ - ['let', ['$:0', ['T_ID:bar']], - ['let', ['$:1', ['T_ID:baz']], - ['T_ID:foo', '$:0', '$:1', 'T_ID:a']]] - ]) - end - end - - context "if expressions" do - it "should leave atomic expressions alone" do - expect(anf('if 1 2 3;')).to eq([ - ["if", "T_INT:1", - ["let", ["$:0", "T_INT:2"], - ["let", ["$:1", "T_INT:3"], - "$:1"]]] - ]) - end - - it "should normalize the conditional expression" do - expect(anf('if foo() 2 else 3;')).to eq([ - ["let", ["$:2", ["T_ID:foo"]], - ["if", "$:2", - ["let", ["$:0", "T_INT:2"], "$:0"], - ["let", ["$:1", "T_INT:3"], "$:1"]]] - ]) - end - - it "should normalize the first branch expression" do - expect(anf('if 1 foo() else 3;')).to eq([ - ["if", "T_INT:1", - ["let", ["$:0", ["T_ID:foo"]], "$:0"], - ["let", ["$:1", "T_INT:3"], "$:1"]] - ]) - end - - it "should normalize the first branch expression" do - expect(anf('if 1 2 else foo();')).to eq([ - ["if", "T_INT:1", - ["let", ["$:0", "T_INT:2"], "$:0"], - ["let", ["$:1", ["T_ID:foo"]], "$:1"]] - ]) - end - end - - context "function literals" do - it "should normalize a literal with a simple expression" do - expect(anf('fn() 123;')).to eq([ - ["fn", [], - ["let", ["$:0", "T_INT:123"], - "$:0"]] - ]) - end - - it "should normalize a literal with two sequential simple expressions" do - expect(anf('fn() 1 2;')).to eq([ - ["fn", [], - ["let", ["$:0", "T_INT:1"], - ["let", ["$:1", "T_INT:2"], - "$:1"]]] - ]) - end - - it "should normalize a literal with three sequential simple expressions" do - expect(anf('fn() 1 2 3;')).to eq([ - ["fn", [], - ["let", ["$:0", "T_INT:1"], - ["let", ["$:1", "T_INT:2"], - ["let", ["$:2", "T_INT:3"], - "$:2"]]]] - ]) - end - - it "should normalize a literal with a complex expression" do - expect(anf('fn() foo(bar());')).to eq([ - ["fn", [], - ["let", ["$:1", ["T_ID:bar"]], - ["let", ["$:0", ["T_ID:foo", "$:1"]], - "$:0"]]] - ]) - end - - #it "should normalize a literal with an if expression" do - # expect(anf('fn() if 1 2 else 3;;')).to eq([ - # ["fn", [], - # ["if", "T_INT:1", - # ["let", ["$:1", "T_INT:2"], "$:1"], - # ["let", ["$:2", "T_INT:3"], "$:2"]]] - # ]) - #end - - #it "should normalize a literal with two sequential if expressions" do - # expect(anf('fn() if 1 2 else 3; if 1 2 else 3; ;')).to eq([ - # ]) - #end - end -end