From 5d91e4fdc916c135b0a200749d27638f4adb50af Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 4 Jul 2022 21:14:31 -0400 Subject: [PATCH] fixed void return functions and reworked test file --- cerise/TODO.md | 2 + cerise/backend/ssa/codegen.c | 14 +- cerise/inc/cerise.h | 13 +- cerise/src/grammar.c | 15 +- cerise/src/ssa.c | 18 +- cerise/tests/Module.m | 570 +++++++++++++++++++++-------------- 6 files changed, 394 insertions(+), 238 deletions(-) diff --git a/cerise/TODO.md b/cerise/TODO.md index 2011e9d..2f661df 100644 --- a/cerise/TODO.md +++ b/cerise/TODO.md @@ -4,6 +4,8 @@ # Up Next +* void returns are busted + * Linearize the AST expression nodes * Split the AST into basic blocks ala CFG representation * Convert the CFG representation to SSA form diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index 7a9ae30..325f97a 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -182,7 +182,7 @@ static void print_ident(Parser* p, SsaVar* var) static void print_const(Type* type, SsaValue* val) { - if (type->form == FORM_INT) + if (type->form == FORM_INT || type->form == FORM_BOOL) { printf(" %lld", val->val.i); } @@ -291,7 +291,8 @@ void print_op(Parser* p, SsaNode* expr) } break; - case MODE_CONTROL: + case MODE_CTRL: + case MODE_CTRL_CONST: if (expr->code == RETURN) { printf(" ret "); @@ -299,7 +300,14 @@ void print_op(Parser* p, SsaNode* expr) if (expr->ret_type->form != FORM_VOID) { printf(" "); - print_ident(p, &(expr->dest)); + if (expr->mode == MODE_CTRL) + { + print_ident(p, &(expr->dest)); + } + else + { + print_const(expr->ret_type, &(expr->left)); + } } puts(""); } diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index be90539..ffb8627 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -163,12 +163,13 @@ typedef struct SsaBlock { } SsaBlock; enum { - MODE_CONST = 0, - MODE_VAR = 1, - MODE_CONTROL = 2, - MODE_UNOP = 3, - MODE_BINOP = 4, - MODE_MEMORY = 5, + MODE_CONST = 0, + MODE_VAR = 1, + MODE_CTRL = 2, + MODE_CTRL_CONST = 3, + MODE_UNOP = 4, + MODE_BINOP = 5, + MODE_MEMORY = 6, }; typedef struct Symbol { diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 46d520a..bb9e354 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -587,6 +587,10 @@ void proc_decl(Parser* p) expect(p, ';'); ssa_return(p, retval); } + else + { + ssa_return(p, NULL); + } expect(p, END); codegen_block(p, block); @@ -666,13 +670,14 @@ static void module(Parser* p) { SsaBlock* seqblock = statement_seq(p); block->links[0] = seqblock; + ssa_join(p); + codegen_block(p, block); + } + else + { + printf("{\n ret void\n}\n"); } - ssa_return(p, NULL); expect(p, END); - ssa_join(p); - - /* debug dump the result */ - codegen_block(p, block); } else { diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index bef2c36..cae0fea 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -247,7 +247,7 @@ void ssa_block_add(SsaBlock* blk, SsaNode* node) SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2) { cond = load(p, cond); - SsaNode* node = ssa_node(IF, MODE_CONTROL); + SsaNode* node = ssa_node(IF, MODE_CTRL); node->ret_type = &VoidType; node->arg_type = &BoolType; node->left.block = br1; @@ -259,10 +259,18 @@ SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2) SsaNode* ssa_return(Parser* p, SsaNode* expr) { - SsaNode* node = ssa_node(RETURN, MODE_CONTROL); + SsaNode* node = ssa_node(RETURN, MODE_CTRL); if (expr) { - load(p, expr); + if (expr->mode == MODE_CONST) + { + node->mode = MODE_CTRL_CONST; + node->left = expr->left; + } + else + { + load(p, expr); + } node->ret_type = expr->ret_type; node->arg_type = expr->ret_type; node = load(p, node); @@ -516,5 +524,9 @@ static SsaNode* load(Parser* p, SsaNode* node) ssa_block_add(p->curr_block, node); node->loaded = 1; } + else + { +// assert(!"die"); + } return node; } diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 9f051a7..1088426 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -1,268 +1,396 @@ module Module -import - Foo - Bar3 = Bar2 - -const - A* = true - B* = 42 - C* = 42.0 - D = -B - E = -C - F = not A - G = B + 2 - 2 * 2 - H = false or A - -type - TypeA* = Int - TypeB* = array 5*B of Int - TypeC* = array 5 of array 10 of Int - TypeD* = record - x,y : Int - label : array 10 of Int - dim : record - w,h : Int - end - end - TypeE* = record - i : Int - a : array 5 of Int - end - TypeF* = array 5 of TypeE - var - a* : Bool - b* : Int - c : Int - d : Real - e : Real - f : array 5 of array 10 of Int - g : TypeD - h : array 5 of Int - i : TypeF - j : TypeA + vBool* : Bool + vInt* : Int + vReal : Real -#procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int -# const FOO = 2 -# type foo = Int -# var -# z1 : Int -# q : array 5 of array 10 of Int -#begin -## e = q; -# c = 1; -# z1 = 2; -# return z1; -#end +procedure TestReturnVoid() +begin +end -#procedure Bar*(a : Int) : Int -#begin -# a = 42; -# return a; -#end -# -#procedure Baz*(a : Int) -#begin -# if (1 > 2) then -# 42; -# else -# 24; -# end -#end +procedure TestReturnIntLiteral() : Int +begin + return 0; +end +procedure TestReturnRealLiteral() : Real begin - # Global variables - b = 42; - b = j; + return 0.0; +end - # Integer Arithmetic ops - c = b + 1; - c = 1 + b; - c = b + b; +procedure TestReturnBoolLiteral() : Bool +begin + return false; +end - c = b - 1; - c = 1 - b; - c = b - b; +procedure TestStoreLiterals() +begin + vBool = true; + vInt = 42; + vReal = 42.0; +end - c = b * 1; - c = 1 * b; - c = b * b; +procedure TestIntArithOps() +begin + vInt = vInt + 1; + vInt = 1 + vInt; + vInt = vInt + vInt; - c = b / 1; - c = 1 / b; - c = b / b; + vInt = vInt - 1; + vInt = 1 - vInt; + vInt = vInt - vInt; - c = b % 1; - c = 1 % b; - c = b % b; + vInt = vInt * 1; + vInt = 1 * vInt; + vInt = vInt * vInt; - # Integer Comparison ops - a = b == 1; - a = 1 == b; - a = b == b; + vInt = vInt / 1; + vInt = 1 / vInt; + vInt = vInt / vInt; - a = b != 1; - a = 1 != b; - a = b != b; + vInt = vInt % 1; + vInt = 1 % vInt; + vInt = vInt % vInt; +end - a = b < 1; - a = 1 < b; - a = b < b; +procedure TestIntCompOps() +begin + vBool = vInt == 1; + vBool = 1 == vInt; + vBool = vInt == vInt; - a = b > 1; - a = 1 > b; - a = b > b; + vBool = vInt != 1; + vBool = 1 != vInt; + vBool = vInt != vInt; - a = b <= 1; - a = 1 <= b; - a = b <= b; + vBool = vInt < 1; + vBool = 1 < vInt; + vBool = vInt < vInt; - a = b >= 1; - a = 1 >= b; - a = b >= b; + vBool = vInt > 1; + vBool = 1 > vInt; + vBool = vInt > vInt; - # Real Arithmetic ops - e = d + 1.0; - e = 1.0 + d; - e = d + d; + vBool = vInt <= 1; + vBool = 1 <= vInt; + vBool = vInt <= vInt; - e = d - 1.0; - e = 1.0 - d; - e = d - d; + vBool = vInt >= 1; + vBool = 1 >= vInt; + vBool = vInt >= vInt; +end - e = d * 1.0; - e = 1.0 * d; - e = d * d; - e = d / 1.0; - e = 1.0 / d; - e = d / d; +procedure TestRealArithOps() +begin + vReal = vReal + 1.0; + vReal = 1.0 + vReal; + vReal = vReal + vReal; - e = d % 1.0; - e = 1.0 % d; - e = d % d; + vReal = vReal - 1.0; + vReal = 1.0 - vReal; + vReal = vReal - vReal; - # Real Comparison ops - a = d == 1.0; - a = 1.0 == d; - a = d == d; + vReal = vReal * 1.0; + vReal = 1.0 * vReal; + vReal = vReal * vReal; - a = d != 1.0; - a = 1.0 != d; - a = d != d; + vReal = vReal / 1.0; + vReal = 1.0 / vReal; + vReal = vReal / vReal; - a = d < 1.0; - a = 1.0 < d; - a = d < d; + vReal = vReal % 1.0; + vReal = 1.0 % vReal; + vReal = vReal % vReal; +end - a = d > 1.0; - a = 1.0 > d; - a = d > d; +procedure TestRealCompOps() +begin + vBool = vReal == 1.0; + vBool = 1.0 == vReal; + vBool = vReal == vReal; - a = d <= 1.0; - a = 1.0 <= d; - a = d <= d; + vBool = vReal != 1.0; + vBool = 1.0 != vReal; + vBool = vReal != vReal; - a = d >= 1.0; - a = 1.0 >= d; - a = d >= d; + vBool = vReal < 1.0; + vBool = 1.0 < vReal; + vBool = vReal < vReal; + vBool = vReal > 1.0; + vBool = 1.0 > vReal; + vBool = vReal > vReal; + vBool = vReal <= 1.0; + vBool = 1.0 <= vReal; + vBool = vReal <= vReal; -# b = 1; -# if c == b then -# b = b - 1; -# b = b - 1; -# else -# b = b + 1; -# b = b + 1; -# end -# b = 4; -# b = 5; + vBool = vReal >= 1.0; + vBool = 1.0 >= vReal; + vBool = vReal >= vReal; +end -# b = 42; -# b = -b; -# c = b + 1; +#import +# Foo +# Bar3 = Bar2 # -# if c == b then -# c = 42; -# else -# c = 24; -# end +#const +# A* = true +# B* = 42 +# C* = 42.0 +# D = -B +# E = -C +# F = not A +# G = B + 2 - 2 * 2 +# H = false or A # -# if c == b then -# b = 42; -# else -# b = 24; +#type +# TypeA* = Int +# TypeB* = array 5*B of Int +# TypeC* = array 5 of array 10 of Int +# TypeD* = record +# x,y : Int +# label : array 10 of Int +# dim : record +# w,h : Int +# end # end - -# h[1].i = 42; -# a = true; -# a = A; -# b = 24; -# b = B; - -# # Unary ops -# b = +b; -# b = -b; - +# TypeE* = record +# i : Int +# a : array 5 of Int +# end +# TypeF* = array 5 of TypeE # +#var +# a* : Bool +# b* : Int +# c : Int +# d : Real +# e : Real +# f : array 5 of array 10 of Int +# g : TypeD +# h : array 5 of Int +# i : TypeF +# j : TypeA # +##procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int +## const FOO = 2 +## type foo = Int +## var +## z1 : Int +## q : array 5 of array 10 of Int +##begin +### e = q; +## c = 1; +## z1 = 2; +## return z1; +##end +# +##procedure Bar*(a : Int) : Int +##begin +## a = 42; +## return a; +##end +## +##procedure Baz*(a : Int) +##begin +## if (1 > 2) then +## 42; +## else +## 24; +## end +##end +# +begin +# # Integer Arithmetic ops +# c = b + 1; +# c = 1 + b; # c = b + b; # -# # Complex arithmetic -# c = b + b * b + b; +# c = b - 1; +# c = 1 - b; +# c = b - b; # +# c = b * 1; +# c = 1 * b; +# c = b * b; # -# # If statements -# if 1 == 1 then -# c = 1; -# end +# c = b / 1; +# c = 1 / b; +# c = b / b; # -# if 1 == 1 then -# c = 1; -# else -# c = 1; -# end +# c = b % 1; +# c = 1 % b; +# c = b % b; # -# if 1 == 1 then -# c = 1; -# elsif 2 == 2 then -# c = 1; -# end +# # Integer Comparison ops +# a = b == 1; +# a = 1 == b; +# a = b == b; # -# if 1 == 1 then -# c = 1; -# elsif 2 == 2 then -# c = 2; -# elsif 2 == 2 then -# c = 2; -# else -# c = 3; -# end +# a = b != 1; +# a = 1 != b; +# a = b != b; # -# # Function calls -# c = Foo(1,2); -# e[0] = 1; -# Foo(1,2); -# e[2][1] = 1 + e[2][1]; -# e[b] = 1; -# e[1][2] = 1; -# c = e[1][c]; -# c = f.dim.w; -# f.dim.h = 0; -# f.label[0] = 42; - -# c = 4; -# g[c] = 42; -# e[0][9] = 42; - -# c = Bar(42); -# c = 42; -# c = 24; - -# Bar(Foo.testint); -# Bar(Bar2.testint); -# Bar(Bar3.testint); +# a = b < 1; +# a = 1 < b; +# a = b < b; +# +# a = b > 1; +# a = 1 > b; +# a = b > b; +# +# a = b <= 1; +# a = 1 <= b; +# a = b <= b; +# +# a = b >= 1; +# a = 1 >= b; +# a = b >= b; +# +# # Real Arithmetic ops +# e = d + 1.0; +# e = 1.0 + d; +# e = d + d; +# +# e = d - 1.0; +# e = 1.0 - d; +# e = d - d; +# +# e = d * 1.0; +# e = 1.0 * d; +# e = d * d; +# +# e = d / 1.0; +# e = 1.0 / d; +# e = d / d; +# +# e = d % 1.0; +# e = 1.0 % d; +# e = d % d; +# +# # Real Comparison ops +# a = d == 1.0; +# a = 1.0 == d; +# a = d == d; +# +# a = d != 1.0; +# a = 1.0 != d; +# a = d != d; +# +# a = d < 1.0; +# a = 1.0 < d; +# a = d < d; +# +# a = d > 1.0; +# a = 1.0 > d; +# a = d > d; +# +# a = d <= 1.0; +# a = 1.0 <= d; +# a = d <= d; +# +# a = d >= 1.0; +# a = 1.0 >= d; +# a = d >= d; +# +# +# +## b = 1; +## if c == b then +## b = b - 1; +## b = b - 1; +## else +## b = b + 1; +## b = b + 1; +## end +## b = 4; +## b = 5; +# +## b = 42; +## b = -b; +## c = b + 1; +## +## if c == b then +## c = 42; +## else +## c = 24; +## end +## +## if c == b then +## b = 42; +## else +## b = 24; +## end +# +## h[1].i = 42; +## a = true; +## a = A; +## b = 24; +## b = B; +# +## # Unary ops +## b = +b; +## b = -b; +# +## +## +## c = b + b; +## +## # Complex arithmetic +## c = b + b * b + b; +## +## +## # If statements +## if 1 == 1 then +## c = 1; +## end +## +## if 1 == 1 then +## c = 1; +## else +## c = 1; +## end +## +## if 1 == 1 then +## c = 1; +## elsif 2 == 2 then +## c = 1; +## end +## +## if 1 == 1 then +## c = 1; +## elsif 2 == 2 then +## c = 2; +## elsif 2 == 2 then +## c = 2; +## else +## c = 3; +## end +## +## # Function calls +## c = Foo(1,2); +## e[0] = 1; +## Foo(1,2); +## e[2][1] = 1 + e[2][1]; +## e[b] = 1; +## e[1][2] = 1; +## c = e[1][c]; +## c = f.dim.w; +## f.dim.h = 0; +## f.label[0] = 42; +# +## c = 4; +## g[c] = 42; +## e[0][9] = 42; +# +## c = Bar(42); +## c = 42; +## c = 24; +# +## Bar(Foo.testint); +## Bar(Bar2.testint); +## Bar(Bar3.testint); end -- 2.49.0