# 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
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);
}
}
break;
- case MODE_CONTROL:
+ case MODE_CTRL:
+ case MODE_CTRL_CONST:
if (expr->code == RETURN)
{
printf(" ret ");
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("");
}
} 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 {
expect(p, ';');
ssa_return(p, retval);
}
+ else
+ {
+ ssa_return(p, NULL);
+ }
expect(p, END);
codegen_block(p, block);
{
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
{
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;
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);
ssa_block_add(p->curr_block, node);
node->loaded = 1;
}
+ else
+ {
+// assert(!"die");
+ }
return node;
}
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