From: Michael D. Lowis Date: Fri, 4 Mar 2022 21:46:14 +0000 (-0500) Subject: added arg and return types to operations X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=593fa5187568db139eb4a1808d48a560462e46b0;p=proto%2Fobnc.git added arg and return types to operations --- diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index 0a0bf5b..cd427b6 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -195,7 +195,7 @@ static void print_const(Type* type, SsaValue* val) char* binop_name(SsaNode* node) { char* name = NULL; - if (node->type->form == FORM_INT) + if (node->ret_type->form == FORM_INT) { switch(node->code) { @@ -204,16 +204,9 @@ char* binop_name(SsaNode* node) case '*': name = "mul"; break; case '/': name = "sdiv"; break; case '%': name = "srem"; break; - - case EQ: name = "icmp eq"; break; - case NEQ: name = "icmp ne"; break; - case '<': name = "icmp slt"; break; - case '>': name = "icmp sgt"; break; - case LTEQ: name = "icmp sle"; break; - case GTEQ: name = "icmp sge"; break; } } - else if (node->type->form == FORM_REAL) + else if (node->ret_type->form == FORM_REAL) { switch(node->code) { @@ -222,17 +215,39 @@ char* binop_name(SsaNode* node) case '*': name = "fmul"; break; case '/': name = "fdiv"; break; case '%': name = "frem"; break; - - case EQ: name = "fcmp eq"; break; - case NEQ: name = "fcmp ne"; break; - case '<': name = "fcmp slt"; break; - case '>': name = "fcmp sgt"; break; - case LTEQ: name = "fcmp sle"; break; - case GTEQ: name = "fcmp sge"; break; + } + } + else if (node->ret_type->form == FORM_BOOL) + { + if (node->arg_type->form == FORM_INT) + { + switch(node->code) + { + case EQ: name = "icmp eq"; break; + case NEQ: name = "icmp ne"; break; + case '<': name = "icmp slt"; break; + case '>': name = "icmp sgt"; break; + case LTEQ: name = "icmp sle"; break; + case GTEQ: name = "icmp sge"; break; + } + } + else if (node->arg_type->form == FORM_REAL) + { + switch(node->code) + { + case EQ: name = "fcmp eq"; break; + case NEQ: name = "fcmp ne"; break; + case '<': name = "fcmp slt"; break; + case '>': name = "fcmp sgt"; break; + case LTEQ: name = "fcmp sle"; break; + case GTEQ: name = "fcmp sge"; break; + } } } else { + printf("\n%d %d\n", node->mode, node->code); + fflush(stdout); assert(!"not implemented"); } return name; @@ -248,9 +263,9 @@ void print_op(Parser* p, SsaNode* expr) printf(" "); print_ident(p, &(expr->dest)); printf(" = load "); - emit_type(expr->type); + emit_type(expr->ret_type); printf(", "); - emit_type(expr->type); + emit_type(expr->ret_type); printf("* "); print_ident(p, &(expr->left.var)); puts(""); @@ -258,11 +273,11 @@ void print_op(Parser* p, SsaNode* expr) else if (expr->code == STORE) { printf(" store "); - emit_type(expr->type); + emit_type(expr->arg_type); printf(" "); print_ident(p, &(expr->left.var)); printf(", "); - emit_type(expr->type); + emit_type(expr->ret_type); printf("* "); print_ident(p, &(expr->dest)); puts(""); @@ -277,7 +292,9 @@ void print_op(Parser* p, SsaNode* expr) if (expr->code == RETURN) { printf(" ret "); - emit_type(expr->type); + emit_type(expr->ret_type); + printf(" "); + print_ident(p, &(expr->dest)); puts(""); } break; @@ -292,7 +309,7 @@ void print_op(Parser* p, SsaNode* expr) printf(" "); print_ident(p, &(expr->dest)); printf(" = %s ", binop_name(expr)); - emit_type(expr->type); + emit_type(expr->ret_type); printf(" "); print_ident(p, &(expr->left.var)); printf(", "); @@ -304,9 +321,9 @@ void print_op(Parser* p, SsaNode* expr) printf(" "); print_ident(p, &(expr->dest)); printf(" = %s ", binop_name(expr)); - emit_type(expr->type); + emit_type(expr->ret_type); printf(" "); - print_const(expr->type, &(expr->left)); + print_const(expr->ret_type, &(expr->left)); printf(", "); print_ident(p, &(expr->right.var)); printf("\n"); @@ -316,11 +333,11 @@ void print_op(Parser* p, SsaNode* expr) printf(" "); print_ident(p, &(expr->dest)); printf(" = %s ", binop_name(expr)); - emit_type(expr->type); + emit_type(expr->ret_type); printf(" "); print_ident(p, &(expr->left.var)); printf(", "); - print_const(expr->type, &(expr->right)); + print_const(expr->ret_type, &(expr->right)); printf("\n"); break; diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index c1af2d7..0bc3180 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -130,7 +130,8 @@ typedef struct SsaNode { int code : 27; int mode : 4; int loaded : 1; - Type* type; + Type* ret_type; + Type* arg_type; SsaVar dest; SsaValue left; SsaValue right; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 57f9ed3..34998a3 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -92,7 +92,7 @@ static SsaNode* designator(Parser* p) case '.': { expect(p, '.'); - if (expr->type->form != FORM_RECORD) + if (expr->ret_type->form != FORM_RECORD) { error(p, "attempting to access field of non-array object"); } @@ -104,7 +104,7 @@ static SsaNode* designator(Parser* p) case '[': { expect(p, '['); - if (expr->type->form != FORM_ARRAY) + if (expr->ret_type->form != FORM_ARRAY) { error(p, "attempting to index non-array value"); } @@ -436,9 +436,9 @@ static SsaBlock* statement_seq(Parser* p) expect(p, END); } - else if (matches(p, END) || matches(p,RETURN)) + else if (matches(p, END) || matches(p, RETURN)) { - /* empty sequence */ + /* end of block */ } else /* assignments/expressions */ { @@ -514,7 +514,7 @@ static void const_decl(Parser* p) sym = symbol_new(p, 0, name, SYM_CONST, export); expect(p, '='); sym->value = expression(p); - sym->type = sym->value->type; + sym->type = sym->value->ret_type; if (sym->value->mode != MODE_CONST) { error(p, "constant defined with non-constant expression"); diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index 30a3880..0ae1aff 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -136,7 +136,7 @@ SsaNode* ssa_ident(Parser* p, long long index) else { node = ssa_node(IDENT, MODE_VAR); - node->type = sym->type; + node->ret_type = sym->type; node->loaded = !sym->global; node->dest.symid = index; node->dest.symver = sym->version; @@ -150,7 +150,7 @@ SsaNode* ssa_bool(Parser* p, bool val) { (void)p; SsaNode* node = ssa_node(BOOL, MODE_CONST); - node->type = &BoolType; + node->ret_type = &BoolType; node->left.val.i = val; return node; } @@ -159,7 +159,7 @@ SsaNode* ssa_int(Parser* p, long long val) { (void)p; SsaNode* node = ssa_node(INT, MODE_CONST); - node->type = &IntType; + node->ret_type = &IntType; node->left.val.i = val; return node; } @@ -168,7 +168,7 @@ SsaNode* ssa_real(Parser* p, double val) { (void)p; SsaNode* node = ssa_node(REAL, MODE_CONST); - node->type = &RealType; + node->ret_type = &RealType; node->left.val.f = val; return node; } @@ -184,7 +184,7 @@ SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value) { load(p, value); SsaNode* node = ssa_node(STORE, MODE_MEMORY); - node->type = dest->type; + node->ret_type = dest->ret_type; node->dest = dest->left.var; node->left.var = value->dest; node->dest.symver = phi_add(p, node->dest); @@ -233,7 +233,7 @@ SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2) { cond = load(p, cond); SsaNode* node = ssa_node(IF, MODE_CONTROL); - node->type = &VoidType; + node->ret_type = &VoidType; node->left.block = br1; node->right.block = br2; node = load(p, node); @@ -247,13 +247,13 @@ SsaNode* ssa_return(Parser* p, SsaNode* expr) if (expr) { load(p, expr); - node->type = expr->type; + node->ret_type = expr->ret_type; node = load(p, node); node->dest = expr->dest; } else { - node->type = &VoidType; + node->ret_type = &VoidType; node = load(p, node); } return node; @@ -294,7 +294,10 @@ static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right) } /* set the result type appropriately */ - node->type = left->type; + node->ret_type = left->ret_type; + node->arg_type = left->ret_type; + + /* comparison ops are handled specially */ switch (op) { case EQ: @@ -303,7 +306,7 @@ static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right) case LTEQ: case '>': case GTEQ: - node->type = &BoolType; + node->ret_type = &BoolType; break; } } @@ -321,7 +324,7 @@ static SsaNode* unop(Parser* p, int op, SsaNode* operand) { operand = load(p, operand); node = ssa_node(op, MODE_UNOP); - node->type = operand->type; + node->ret_type = operand->ret_type; node->left.var = operand->dest; } return node; @@ -329,7 +332,7 @@ static SsaNode* unop(Parser* p, int op, SsaNode* operand) static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) { - if (a->type->form == FORM_INT || a->type->form == FORM_BOOL) + if (a->ret_type->form == FORM_INT || a->ret_type->form == FORM_BOOL) { switch (op) { @@ -344,32 +347,32 @@ static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) case EQ: puts("EQ"); a->left.val.i = a->left.val.i == b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; case NEQ: a->left.val.i = a->left.val.i != b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; case '<': a->left.val.i = a->left.val.i < b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; case LTEQ: a->left.val.i = a->left.val.i <= b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; case '>': a->left.val.i = a->left.val.i > b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; case GTEQ: a->left.val.i = a->left.val.i >= b->left.val.i; - a->type = &BoolType; + a->ret_type = &BoolType; break; default: @@ -377,7 +380,7 @@ static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) break; } } - else if (a->type->form == FORM_REAL) + else if (a->ret_type->form == FORM_REAL) { switch (op) { @@ -388,32 +391,32 @@ static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) case EQ: a->left.val.f = a->left.val.f == b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; case NEQ: a->left.val.f = a->left.val.f != b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; case '<': a->left.val.f = a->left.val.f < b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; case LTEQ: a->left.val.f = a->left.val.f <= b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; case '>': a->left.val.f = a->left.val.f > b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; case GTEQ: a->left.val.f = a->left.val.f >= b->left.val.f; - a->type = &BoolType; + a->ret_type = &BoolType; break; default: @@ -430,7 +433,7 @@ static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) static SsaNode* const_unop(int op, SsaNode* a) { - if (a->type->form == FORM_INT) + if (a->ret_type->form == FORM_INT) { switch (op) { @@ -439,7 +442,7 @@ static SsaNode* const_unop(int op, SsaNode* a) default: assert(!"not a valid op"); break; } } - else if (a->type->form == FORM_REAL) + else if (a->ret_type->form == FORM_REAL) { switch (op) { @@ -448,7 +451,7 @@ static SsaNode* const_unop(int op, SsaNode* a) default: assert(!"not a valid op"); break; } } - else if (a->type->form == FORM_BOOL) + else if (a->ret_type->form == FORM_BOOL) { switch (op) { diff --git a/cerise/src/type_checks.c b/cerise/src/type_checks.c index 603ab82..8abc5fc 100644 --- a/cerise/src/type_checks.c +++ b/cerise/src/type_checks.c @@ -2,7 +2,7 @@ void check_int(Parser* p, SsaNode* a) { - if (a->type->form != FORM_INT) + if (a->ret_type->form != FORM_INT) { error(p, "not an int"); } @@ -16,7 +16,7 @@ void check_ints(Parser* p, SsaNode* a, SsaNode* b) void check_real(Parser* p, SsaNode* a) { - if (a->type->form != FORM_REAL) + if (a->ret_type->form != FORM_REAL) { error(p, "not a real"); } @@ -30,11 +30,11 @@ void check_reals(Parser* p, SsaNode* a, SsaNode* b) void check_num(Parser* p, SsaNode* a) { - if (a->type->form == FORM_REAL) + if (a->ret_type->form == FORM_REAL) { check_real(p, a); } - else if (a->type->form == FORM_INT) + else if (a->ret_type->form == FORM_INT) { check_int(p, a); } @@ -46,7 +46,7 @@ void check_num(Parser* p, SsaNode* a) void check_nums(Parser* p, SsaNode* a, SsaNode* b) { - if (a->type->form == FORM_REAL) + if (a->ret_type->form == FORM_REAL) { check_reals(p, a, b); } @@ -58,7 +58,7 @@ void check_nums(Parser* p, SsaNode* a, SsaNode* b) void check_bool(Parser* p, SsaNode* a) { - if (a->type->form != FORM_BOOL) + if (a->ret_type->form != FORM_BOOL) { error(p, "not an bool"); } @@ -84,7 +84,7 @@ void check_type(Parser* p, Type* type, SsaNode* a) { check_bool(p, a); } -// else if (a->type->form == FORM_ARRAY) +// else if (a->ret_type->form == FORM_ARRAY) // { // } else @@ -95,20 +95,20 @@ void check_type(Parser* p, Type* type, SsaNode* a) void check_types(Parser* p, SsaNode* a, SsaNode* b) { -// printf("%d %d\n", a->type->form, b->type->form); - if (a->type->form == FORM_REAL) +// printf("%d %d\n", a->ret_type->form, b->ret_type->form); + if (a->ret_type->form == FORM_REAL) { check_reals(p, a, b); } - else if (a->type->form == FORM_INT) + else if (a->ret_type->form == FORM_INT) { check_ints(p, a, b); } - else if (a->type->form == FORM_BOOL) + else if (a->ret_type->form == FORM_BOOL) { check_bools(p, a, b); } -// else if (a->type->form == FORM_ARRAY) +// else if (a->ret_type->form == FORM_ARRAY) // { // } else diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 9b4b1cf..3111238 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -71,8 +71,42 @@ var #end begin +# # Global variables # i = 42; # b = i; + +# # Arithmetic ops +# c = b + 1; +# c = 1 + b; +# c = b + b; +# +# c = b - 1; +# c = 1 - b; +# c = b - b; +# +# c = b * 1; +# c = 1 * b; +# c = b * b; +# +# c = b / 1; +# c = 1 / b; +# c = b / b; +# +# c = b % 1; +# c = 1 % b; +# c = b % b; + +# # Comparison ops + a = b == 1; +# a = b != 1; +# a = b < 1; +# a = b > 1; +# a = b <= 1; +# a = b >= 1; + + + + # b = 1; # if c == b then # b = b - 1; @@ -111,34 +145,6 @@ begin # b = +b; # b = -b; - # Arithmetic ops - c = b + 1; - c = 1 + b; - c = b + b; - - c = b - 1; - c = 1 - b; - c = b - b; - - c = b * 1; - c = 1 * b; - c = b * b; - - c = b / 1; - c = 1 / b; - c = b / b; - - c = b % 1; - c = 1 % b; - c = b % b; - -# # Comparison ops -# c = b == 1; -# c = b != 1; -# c = b < 1; -# c = b > 1; -# c = b <= 1; -# c = b >= 1; # # # c = b + b;