char* binop_name(SsaNode* node)
{
char* name = NULL;
- if (node->type->form == FORM_INT)
+ if (node->ret_type->form == FORM_INT)
{
switch(node->code)
{
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)
{
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;
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("");
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("");
if (expr->code == RETURN)
{
printf(" ret ");
- emit_type(expr->type);
+ emit_type(expr->ret_type);
+ printf(" ");
+ print_ident(p, &(expr->dest));
puts("");
}
break;
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(", ");
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");
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;
int code : 27;
int mode : 4;
int loaded : 1;
- Type* type;
+ Type* ret_type;
+ Type* arg_type;
SsaVar dest;
SsaValue left;
SsaValue right;
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");
}
case '[':
{
expect(p, '[');
- if (expr->type->form != FORM_ARRAY)
+ if (expr->ret_type->form != FORM_ARRAY)
{
error(p, "attempting to index non-array value");
}
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 */
{
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");
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;
{
(void)p;
SsaNode* node = ssa_node(BOOL, MODE_CONST);
- node->type = &BoolType;
+ node->ret_type = &BoolType;
node->left.val.i = val;
return node;
}
{
(void)p;
SsaNode* node = ssa_node(INT, MODE_CONST);
- node->type = &IntType;
+ node->ret_type = &IntType;
node->left.val.i = val;
return node;
}
{
(void)p;
SsaNode* node = ssa_node(REAL, MODE_CONST);
- node->type = &RealType;
+ node->ret_type = &RealType;
node->left.val.f = val;
return node;
}
{
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);
{
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);
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;
}
/* 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:
case LTEQ:
case '>':
case GTEQ:
- node->type = &BoolType;
+ node->ret_type = &BoolType;
break;
}
}
{
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;
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)
{
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:
break;
}
}
- else if (a->type->form == FORM_REAL)
+ else if (a->ret_type->form == FORM_REAL)
{
switch (op)
{
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:
static SsaNode* const_unop(int op, SsaNode* a)
{
- if (a->type->form == FORM_INT)
+ if (a->ret_type->form == FORM_INT)
{
switch (op)
{
default: assert(!"not a valid op"); break;
}
}
- else if (a->type->form == FORM_REAL)
+ else if (a->ret_type->form == FORM_REAL)
{
switch (op)
{
default: assert(!"not a valid op"); break;
}
}
- else if (a->type->form == FORM_BOOL)
+ else if (a->ret_type->form == FORM_BOOL)
{
switch (op)
{
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");
}
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");
}
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);
}
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);
}
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");
}
{
check_bool(p, a);
}
-// else if (a->type->form == FORM_ARRAY)
+// else if (a->ret_type->form == FORM_ARRAY)
// {
// }
else
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
#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;
# 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;