diff options
Diffstat (limited to 'src/compiler.c')
-rw-r--r-- | src/compiler.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/src/compiler.c b/src/compiler.c index bc875fd..51d7cd6 100644 --- a/src/compiler.c +++ b/src/compiler.c | |||
@@ -20,6 +20,7 @@ typedef union Constant { | |||
20 | } Constant; | 20 | } Constant; |
21 | 21 | ||
22 | typedef struct Chunk { | 22 | typedef struct Chunk { |
23 | sz id; | ||
23 | Instruction *code; | 24 | Instruction *code; |
24 | 25 | ||
25 | // Constant values that fit in 64 bits. | 26 | // Constant values that fit in 64 bits. |
@@ -94,6 +95,23 @@ typedef enum OpCode { | |||
94 | OP_MOV16, // mov16 rx, ra -> rx = ra & 0xFFFF | 95 | OP_MOV16, // mov16 rx, ra -> rx = ra & 0xFFFF |
95 | OP_MOV32, // mov32 rx, ra -> rx = ra & 0xFFFFFFFF | 96 | OP_MOV32, // mov32 rx, ra -> rx = ra & 0xFFFFFFFF |
96 | OP_MOV64, // mov64 rx, ra -> rx = ra & 0xFFFFFFFFFFFFFFFF | 97 | OP_MOV64, // mov64 rx, ra -> rx = ra & 0xFFFFFFFFFFFFFFFF |
98 | // Logic operations (only 64 bits for now). | ||
99 | OP_EQI, // eqk rx, ra, cb | ||
100 | OP_NEQI, // neqk rx, ra, cb | ||
101 | OP_LTI, // ltk rx, ra, cb | ||
102 | OP_GTI, // gtk rx, ra, cb | ||
103 | OP_LEI, // lek rx, ra, cb | ||
104 | OP_GEI, // gek rx, ra, cb | ||
105 | OP_ANDI, // andk rx, ra, cb | ||
106 | OP_ORI, // ork rx, ra, cb | ||
107 | OP_EQ, // eq rx, ra, rb | ||
108 | OP_NEQ, // neq rx, ra, rb | ||
109 | OP_LT, // lt rx, ra, rb | ||
110 | OP_GT, // gt rx, ra, rb | ||
111 | OP_LE, // le rx, ra, rb | ||
112 | OP_GE, // ge rx, ra, rb | ||
113 | OP_AND, // and rx, ra, rb | ||
114 | OP_OR, // or rx, ra, rb | ||
97 | } OpCode; | 115 | } OpCode; |
98 | 116 | ||
99 | Str op_str[] = { | 117 | Str op_str[] = { |
@@ -146,6 +164,19 @@ Str op_str[] = { | |||
146 | [OP_MOV16] = cstr("MOV16 "), | 164 | [OP_MOV16] = cstr("MOV16 "), |
147 | [OP_MOV32] = cstr("MOV32 "), | 165 | [OP_MOV32] = cstr("MOV32 "), |
148 | [OP_MOV64] = cstr("MOV64 "), | 166 | [OP_MOV64] = cstr("MOV64 "), |
167 | // Logic operations. | ||
168 | [OP_EQI] = cstr("EQI "), | ||
169 | [OP_NEQI] = cstr("NEQI "), | ||
170 | [OP_LTI] = cstr("LTI "), | ||
171 | [OP_GTI] = cstr("GTI "), | ||
172 | [OP_LEI] = cstr("LEI "), | ||
173 | [OP_GEI] = cstr("GEI "), | ||
174 | [OP_EQ] = cstr("EQ "), | ||
175 | [OP_NEQ] = cstr("NEQ "), | ||
176 | [OP_LT] = cstr("LT "), | ||
177 | [OP_GT] = cstr("GT "), | ||
178 | [OP_LE] = cstr("LE "), | ||
179 | [OP_GE] = cstr("GE "), | ||
149 | }; | 180 | }; |
150 | 181 | ||
151 | typedef enum { | 182 | typedef enum { |
@@ -213,6 +244,14 @@ compile_binary(Chunk *chunk, Node *node) { | |||
213 | op = OP_MODF; | 244 | op = OP_MODF; |
214 | } | 245 | } |
215 | } break; | 246 | } break; |
247 | case NODE_EQ: op = OP_EQ; break; | ||
248 | case NODE_NEQ: op = OP_NEQ; break; | ||
249 | case NODE_LT: op = OP_LT; break; | ||
250 | case NODE_GT: op = OP_GT; break; | ||
251 | case NODE_LE: op = OP_LE; break; | ||
252 | case NODE_GE: op = OP_GE; break; | ||
253 | case NODE_AND: op = OP_EQ; break; | ||
254 | case NODE_OR: op = OP_NEQ; break; | ||
216 | default: break; | 255 | default: break; |
217 | } | 256 | } |
218 | CompResult comp_a = compile_expr(chunk, node->left); | 257 | CompResult comp_a = compile_expr(chunk, node->left); |
@@ -243,8 +282,8 @@ compile_binary(Chunk *chunk, Node *node) { | |||
243 | return (CompResult){.type = COMP_ERR}; | 282 | return (CompResult){.type = COMP_ERR}; |
244 | } break; | 283 | } break; |
245 | } | 284 | } |
246 | sz reg_dst = comp_a.idx; // Less registers | 285 | // sz reg_dst = comp_a.idx; // Less registers |
247 | // sz reg_dst = chunk->reg_idx++; // Better for optimization | 286 | sz reg_dst = chunk->reg_idx++; // Better for optimization |
248 | EMIT_OP(op, reg_dst, reg_a, reg_b, node, chunk); | 287 | EMIT_OP(op, reg_dst, reg_a, reg_b, node, chunk); |
249 | return (CompResult){.type = COMP_REG, .idx = reg_dst}; | 288 | return (CompResult){.type = COMP_REG, .idx = reg_dst}; |
250 | } | 289 | } |
@@ -252,6 +291,18 @@ compile_binary(Chunk *chunk, Node *node) { | |||
252 | CompResult | 291 | CompResult |
253 | compile_expr(Chunk *chunk, Node *node) { | 292 | compile_expr(Chunk *chunk, Node *node) { |
254 | switch (node->kind) { | 293 | switch (node->kind) { |
294 | // Logic. | ||
295 | // case NODE_NOT: | ||
296 | // case NODE_XOR: | ||
297 | case NODE_AND: | ||
298 | case NODE_OR: | ||
299 | case NODE_EQ: | ||
300 | case NODE_NEQ: | ||
301 | case NODE_LT: | ||
302 | case NODE_GT: | ||
303 | case NODE_LE: | ||
304 | // Arithmetic. | ||
305 | case NODE_GE: | ||
255 | case NODE_ADD: | 306 | case NODE_ADD: |
256 | case NODE_SUB: | 307 | case NODE_SUB: |
257 | case NODE_MUL: | 308 | case NODE_MUL: |