From: Mike Lowis Date: Tue, 29 Dec 2015 14:13:58 +0000 (+0000) Subject: checkpoint commit. stuff's broke. Add some tests before attempting to fix it X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a3112ec1fbe9f22aed4c9e5d302c2c0db64924f4;p=proto%2Fsclpl.git checkpoint commit. stuff's broke. Add some tests before attempting to fix it --- diff --git a/Makefile b/Makefile index 5fe3b0a..180c6c2 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ LD = ${CC} # flags INCS = -Isource/ CPPFLAGS = -D_XOPEN_SOURCE=700 -CFLAGS += ${INCS} ${CPPFLAGS} -g -LDFLAGS += ${LIBS} +CFLAGS += ${INCS} ${CPPFLAGS} -g --coverage +LDFLAGS += --coverage ${LIBS} #------------------------------------------------------------------------------ # Build Targets and Rules @@ -48,7 +48,7 @@ test: sclpl @${CC} ${CFLAGS} -c -o $@ $< clean: - @rm -f sclpl ${OBJS} + @rm -f sclpl ${OBJS} ${OBJS:.o=.gcda} ${OBJS:.o=.gcno} .PHONY: all options test diff --git a/source/anf.c b/source/anf.c index 3cc1f76..0ded73a 100644 --- a/source/anf.c +++ b/source/anf.c @@ -11,6 +11,7 @@ static bool isatomic(AST* tree) case AST_FLOAT: case AST_BOOL: case AST_FUNC: + case AST_TEMP: return true; default: return false; @@ -73,13 +74,13 @@ static AST* normalize_if(AST* tree) AST* elsebr = normalize(ifexpr_else(tree)); if (!isatomic(cond)) { AST* temp = TempVar(); - AST* body = IfExpr(); //(temp, thenbr, elsebr); + 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(); //(cond, thenbr, elsebr); + tree = IfExpr(); ifexpr_set_cond(tree, cond); ifexpr_set_then(tree, thenbr); ifexpr_set_else(tree, elsebr); @@ -99,7 +100,9 @@ static AST* normalize_let(AST* tree) AST* val = normalize(let_val(tree)); AST* body = normalize(let_body(tree)); /* Find the inner most let block */ - if (!isconst(val)) { + 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); diff --git a/spec/anf_spec.rb b/spec/anf_spec.rb index 52fce54..1a7cda2 100644 --- a/spec/anf_spec.rb +++ b/spec/anf_spec.rb @@ -29,36 +29,51 @@ describe "sclpl a-normal form" do context "definitions" do it "should leave atomic defintions alone" do - expect(anf('def foo 123;')).to eq([["def", "foo", "T_INT:123"]]) + 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"]]]) + 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']]) + 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']]) + 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']]]) + 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']]]) + 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']]]]) + ['T_ID:foo', '$:0', '$:1']]] + ]) end it "should normalize an application with three complex args" do @@ -66,28 +81,32 @@ describe "sclpl a-normal form" do ['let', ['$:0', ['T_ID:bar']], ['let', ['$:1', ['T_ID:baz']], ['let', ['$:2', ['T_ID:boo']], - ['T_ID:foo', '$:0', '$:1', '$:2']]]]]) + ['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']]]]) + ['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']]]]) + ['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']]]]) + ['T_ID:foo', '$:0', '$:1', 'T_ID:a']]] + ]) end end @@ -97,7 +116,8 @@ describe "sclpl a-normal form" do ["if", "T_INT:1", ["let", ["$:0", "T_INT:2"], ["let", ["$:1", "T_INT:3"], - "$:1"]]]]) + "$:1"]]] + ]) end it "should normalize the conditional expression" do @@ -105,25 +125,55 @@ describe "sclpl a-normal form" do ["let", ["$:2", ["T_ID:foo"]], ["if", "$:2", ["let", ["$:0", "T_INT:2"], "$:0"], - ["let", ["$:1", "T_INT:3"], "$:1"]]]]) + ["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"]]]) + ["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"]]]) + ["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", [], @@ -133,13 +183,18 @@ describe "sclpl a-normal form" do ]) end - it "should normalize a literal with a complex expression" do + it "should normalize a literal with an if expression" do expect(anf('fn() if 1 2 else 3;;')).to eq([ ["fn", [], - ["let", ["$:1", ["T_ID:bar"]], - ["let", ["$:0", ["T_ID:foo", "$:1"]], - "$:0"]]] + ["if", "T_INT:1", + ["let", ["$:0", "T_INT:2"], "$:0"], + ["let", ["$:1", "T_INT:3"], "$:1"]]] ]) 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 diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index a6eeed7..d0d0065 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -162,6 +162,54 @@ describe "sclpl grammar" do ["fn", ["T_ID:a", "T_ID:b"], ["let", ["$:0", "T_INT:123"], "$:0"]]]) end + + it "should parse a literal with two sequential simple expressions" do + expect(ast('fn() 1 2;')).to eq([ + ["fn", [], + ["let", ["$:0", "T_INT:1"], + ["let", ["$:1", "T_INT:2"], + "$:1"]]] + ]) + end + + it "should parse a literal with three sequential simple expressions" do + expect(ast('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 parse a literal with a complex expression" do + expect(ast('fn() foo(bar());')).to eq([ + ["fn", [], ["let", ["$:0", ["T_ID:foo", ["T_ID:bar"]]], "$:0"]] + ]) + end + + it "should normalize a literal with an if expression" do + expect(ast('fn() if 1 2 else 3;;')).to eq([ + ["fn", [], + ["let", ["$:2", ["if", "T_INT:1", + ["let", ["$:0", "T_INT:2"], "$:0"], + ["let", ["$:1", "T_INT:3"], "$:1"]]], + "$:2"]] + ]) + end + + it "should normalize a literal with two sequential if expressions" do + expect(ast('fn() if 1 2 else 3; if 1 2 else 3; ;')).to eq([ + ["fn", [], + ["let", ["$:2", ["if", "T_INT:1", + ["let", ["$:0", "T_INT:2"], "$:0"], + ["let", ["$:1", "T_INT:3"], "$:1"]]], + ["let", ["$:5", ["if", "T_INT:1", + ["let", ["$:3", "T_INT:2"], "$:3"], + ["let", ["$:4", "T_INT:3"], "$:4"]]], + "$:5"]]] + ]) + end end context "function application" do