aboutsummaryrefslogtreecommitdiffstats
path: root/src/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/ir.c b/src/ir.c
index f1b7eb9..86a1a9a 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -13,8 +13,8 @@ emit_arith(ProgramBASM *program, Node *node, Operator op) {
13 Operand reg_b; 13 Operand reg_b;
14 for (size_t i = 1; i < array_size(node->builtin.args); ++i) { 14 for (size_t i = 1; i < array_size(node->builtin.args); ++i) {
15 Node *arg = node->builtin.args[i]; 15 Node *arg = node->builtin.args[i];
16 Operand reg_dst = NEW_REG();
17 reg_b = emit_basm(program, arg); 16 reg_b = emit_basm(program, arg);
17 Operand reg_dst = NEW_REG();
18 EMIT_2(program, line, op, reg_dst, reg_a, reg_b); 18 EMIT_2(program, line, op, reg_dst, reg_a, reg_b);
19 reg_a = reg_dst; 19 reg_a = reg_dst;
20 } 20 }
@@ -90,14 +90,50 @@ emit_bool(ProgramBASM *program, Node *node) {
90 return reg_dst; 90 return reg_dst;
91} 91}
92 92
93// TODO: emit_if 93Operand
94emit_if(ProgramBASM *program, Node *node) {
95 LineInfo line = (LineInfo){.line = node->line, .col = node->col};
96 Operand label_false = NEW_LAB();
97 Operand label_end = NEW_LAB();
98
99 // If type of expression is `void`, there is nothing to return. Don't
100 // generate a new register or copy output.
101 Operand reg_out = (Operand){0};
102 if (node->expr_type != &default_types[TYPE_VOID]) {
103 reg_out = NEW_REG();
104 }
105
106 Operand cond = emit_basm(program, node->ifexpr.cond);
107 EMIT_1(program, line, OP_JMP_FALSE, label_false, cond);
108
109 Operand ret_true = emit_basm(program, node->ifexpr.expr_true);
110 if (node->ifexpr.expr_false != NULL) {
111 if (node->expr_type != &default_types[TYPE_VOID]) {
112 EMIT_1(program, line, OP_CP64, reg_out, ret_true); // TODO: depends on the type of output
113 }
114 EMIT_0(program, line, OP_JMP, label_end);
115 EMIT_0(program, line, OP_LABEL, label_false);
116 Operand ret_false = emit_basm(program, node->ifexpr.expr_false);
117 if (node->expr_type != &default_types[TYPE_VOID]) {
118 EMIT_1(program, line, OP_CP64, reg_out, ret_false); // TODO: depends on the type of output
119 }
120 EMIT_0(program, line, OP_LABEL, label_end);
121 } else {
122 EMIT_0(program, line, OP_LABEL, label_false);
123 }
124
125 return reg_out;
126}
127
94// TODO: emit_and 128// TODO: emit_and
95// TODO: emit_or 129// TODO: emit_or
96// TODO: emit_not 130// TODO: emit_not
97// TODO: emit_global 131// TODO: emit_block
98// TODO: emit_local
99// TODO: emit_procedure 132// TODO: emit_procedure
133// TODO: emit_local_vars
134// TODO: emit_param_vars
100// TODO: emit_proc_call 135// TODO: emit_proc_call
136// TODO: emit_global_vars
101 137
102Operand 138Operand
103emit_basm(ProgramBASM *program, Node *node) { 139emit_basm(ProgramBASM *program, Node *node) {
@@ -105,6 +141,7 @@ emit_basm(ProgramBASM *program, Node *node) {
105 case NODE_BOOL: { return emit_bool(program, node); } break; 141 case NODE_BOOL: { return emit_bool(program, node); } break;
106 case NODE_NUMBER: { return emit_number(program, node); } break; 142 case NODE_NUMBER: { return emit_number(program, node); } break;
107 case NODE_BUILTIN: { return emit_builtin(program, node); } break; 143 case NODE_BUILTIN: { return emit_builtin(program, node); } break;
144 case NODE_IF: { return emit_if(program, node); } break;
108 default: { 145 default: {
109 push_error(ERR_TYPE_BASM, ERR_UNIMPLEMENTED, node->line, node->col); 146 push_error(ERR_TYPE_BASM, ERR_UNIMPLEMENTED, node->line, node->col);
110 return (Operand){0}; 147 return (Operand){0};