aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c55
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
22typedef struct Chunk { 22typedef 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
99Str op_str[] = { 117Str 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
151typedef enum { 182typedef 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) {
252CompResult 291CompResult
253compile_expr(Chunk *chunk, Node *node) { 292compile_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: