aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/compiler.c b/src/compiler.c
index bd50955..84cc99a 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -29,6 +29,11 @@ typedef union Constant {
29 ptrsize ptr; 29 ptrsize ptr;
30} Constant; 30} Constant;
31 31
32typedef struct LineCol {
33 sz line;
34 sz col;
35} LineCol;
36
32typedef struct Chunk { 37typedef struct Chunk {
33 sz id; 38 sz id;
34 Instruction *code; 39 Instruction *code;
@@ -54,17 +59,17 @@ typedef struct Chunk {
54 // Debugging. 59 // Debugging.
55 Str file_name; 60 Str file_name;
56 Arena *storage; 61 Arena *storage;
57 // TODO: line/col info for debugging. 62 LineCol *linecol;
58} Chunk; 63} Chunk;
59 64
60typedef enum OpCode { 65typedef enum OpCode {
61 // OP DST A B 66 // OP DST A B
62 // --------------------------------------------------------------- 67 // ---------------------------------------------------------------
63 // VM/high level instructions. 68 // VM/high level instructions.
64 OP_HALT, // halt 69 OP_HALT, // halt
65 OP_STVARI, // stvari vx, ca 70 OP_STGVARI, // stgvari vx, ca
66 OP_STVAR, // stvar vx, ra 71 OP_STGVAR, // stgvar vx, ra
67 OP_LDVAR, // ldvar rx, vx 72 OP_LDGVAR, // ldgvar rx, vx
68 // Load/Store instructions. 73 // Load/Store instructions.
69 OP_LD8K, // ld8k rx, ca -> u8 rx = ca 74 OP_LD8K, // ld8k rx, ca -> u8 rx = ca
70 OP_LD16K, // ld16k rx, ca -> u16 rx = ca 75 OP_LD16K, // ld16k rx, ca -> u16 rx = ca
@@ -147,9 +152,9 @@ typedef enum OpCode {
147 152
148Str op_str[] = { 153Str op_str[] = {
149 [OP_HALT] = cstr("HALT "), 154 [OP_HALT] = cstr("HALT "),
150 [OP_STVAR] = cstr("STVAR "), 155 [OP_STGVAR] = cstr("STGVAR "),
151 [OP_STVARI] = cstr("STVARI "), 156 [OP_STGVARI] = cstr("STGVARI "),
152 [OP_LDVAR] = cstr("LDVAR "), 157 [OP_LDGVAR] = cstr("LDGVAR "),
153 // Load ops. 158 // Load ops.
154 [OP_LD8K] = cstr("LD8K "), 159 [OP_LD8K] = cstr("LD8K "),
155 [OP_LD16K] = cstr("LD16K "), 160 [OP_LD16K] = cstr("LD16K "),
@@ -245,15 +250,17 @@ typedef struct CompResult {
245 250
246CompResult compile_expr(Chunk *chunk, Node *node); 251CompResult compile_expr(Chunk *chunk, Node *node);
247 252
248#define EMIT_OP(OP, DST, A, B, NODE, CHUNK) \ 253#define EMIT_OP(OP, DST, A, B, NODE, CHUNK) \
249 do { \ 254 do { \
250 Instruction inst = (Instruction){ \ 255 Instruction inst = (Instruction){ \
251 .op = (OP), \ 256 .op = (OP), \
252 .dst = (DST), \ 257 .dst = (DST), \
253 .a = (A), \ 258 .a = (A), \
254 .b = (B), \ 259 .b = (B), \
255 }; \ 260 }; \
256 array_push((CHUNK)->code, inst, (CHUNK)->storage); \ 261 array_push((CHUNK)->code, inst, (CHUNK)->storage); \
262 LineCol linecol = (LineCol){.line = (NODE)->line, .col = (NODE)->col}; \
263 array_push((CHUNK)->linecol, linecol, (CHUNK)->storage); \
257 } while (0) 264 } while (0)
258 265
259CompResult 266CompResult
@@ -512,11 +519,11 @@ compile_expr(Chunk *chunk, Node *node) {
512 CompResult res = compile_expr(chunk, node->var_val); 519 CompResult res = compile_expr(chunk, node->var_val);
513 switch (res.type) { 520 switch (res.type) {
514 case COMP_CONST: { 521 case COMP_CONST: {
515 EMIT_OP(OP_STVARI, idx, res.idx, 0, node->var_val, 522 EMIT_OP(OP_STGVARI, idx, res.idx, 0, node->var_val,
516 chunk); 523 chunk);
517 } break; 524 } break;
518 case COMP_REG: { 525 case COMP_REG: {
519 EMIT_OP(OP_STVAR, idx, res.idx, 0, node->var_val, 526 EMIT_OP(OP_STGVAR, idx, res.idx, 0, node->var_val,
520 chunk); 527 chunk);
521 } break; 528 } break;
522 default: { 529 default: {
@@ -536,7 +543,7 @@ compile_expr(Chunk *chunk, Node *node) {
536 } 543 }
537 Variable var = map->val; 544 Variable var = map->val;
538 u8 reg_dst = chunk->reg_idx++; 545 u8 reg_dst = chunk->reg_idx++;
539 EMIT_OP(OP_LDVAR, reg_dst, var.idx, 0, node->var_val, chunk); 546 EMIT_OP(OP_LDGVAR, reg_dst, var.idx, 0, node, chunk);
540 return (CompResult){.type = COMP_REG, .idx = reg_dst}; 547 return (CompResult){.type = COMP_REG, .idx = reg_dst};
541 } break; 548 } break;
542 case NODE_BLOCK: { 549 case NODE_BLOCK: {
@@ -639,15 +646,15 @@ disassemble_instruction(Instruction instruction) {
639 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, 646 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst,
640 instruction.a, instruction.b); 647 instruction.a, instruction.b);
641 break; 648 break;
642 case OP_LDVAR: 649 case OP_LDGVAR:
643 println("%s r%d, v%d", op_str[instruction.op], instruction.dst, 650 println("%s r%d, v%d", op_str[instruction.op], instruction.dst,
644 instruction.a, instruction.b); 651 instruction.a, instruction.b);
645 break; 652 break;
646 case OP_STVAR: 653 case OP_STGVAR:
647 println("%s v%d, r%d", op_str[instruction.op], instruction.dst, 654 println("%s v%d, r%d", op_str[instruction.op], instruction.dst,
648 instruction.a, instruction.b); 655 instruction.a, instruction.b);
649 break; 656 break;
650 case OP_STVARI: 657 case OP_STGVARI:
651 println("%s v%d, c%d", op_str[instruction.op], instruction.dst, 658 println("%s v%d, c%d", op_str[instruction.op], instruction.dst,
652 instruction.a, instruction.b); 659 instruction.a, instruction.b);
653 break; 660 break;
@@ -668,26 +675,26 @@ disassemble_instruction(Instruction instruction) {
668 675
669void 676void
670disassemble_chunk(Chunk chunk) { 677disassemble_chunk(Chunk chunk) {
671 println("%s: =========== code ===========", chunk.file_name); 678 println("%s: ============== code ==============", chunk.file_name);
672 for (sz i = 0; i < array_size(chunk.code); i++) { 679 for (sz i = 0; i < array_size(chunk.code); i++) {
673 print("%s: %x{4}: ", chunk.file_name, i); 680 print("%s: %x{4}: ", chunk.file_name, i);
674 disassemble_instruction(chunk.code[i]); 681 disassemble_instruction(chunk.code[i]);
675 } 682 }
676 if (array_size(chunk.constants) > 0) { 683 if (array_size(chunk.constants) > 0) {
677 println("%s: ========= constants ========", chunk.file_name); 684 println("%s: ============ constants ===========", chunk.file_name);
678 for (sz i = 0; i < array_size(chunk.constants); i++) { 685 for (sz i = 0; i < array_size(chunk.constants); i++) {
679 println("%s: %x{2}: %x{8}", chunk.file_name, i, 686 println("%s: %x{2}: %x{8}", chunk.file_name, i,
680 chunk.constants[i]); 687 chunk.constants[i]);
681 } 688 }
682 } 689 }
683 if (array_size(chunk.strings) > 0) { 690 if (array_size(chunk.strings) > 0) {
684 println("%s: ========== strings =========", chunk.file_name); 691 println("%s: ============= strings ============", chunk.file_name);
685 for (sz i = 0; i < array_size(chunk.strings); i++) { 692 for (sz i = 0; i < array_size(chunk.strings); i++) {
686 println("%s: %x{2}: %s", chunk.file_name, i, chunk.strings[i]); 693 println("%s: %x{2}: %s", chunk.file_name, i, chunk.strings[i]);
687 } 694 }
688 } 695 }
689 if (array_size(chunk.vars) > 0) { 696 if (array_size(chunk.vars) > 0) {
690 println("%s: ========= variables ========", chunk.file_name); 697 println("%s: ============ variables ===========", chunk.file_name);
691 for (sz i = 0; i < array_size(chunk.vars); i++) { 698 for (sz i = 0; i < array_size(chunk.vars); i++) {
692 println("%s: %x{2}: [%x{4}:%x{4}] %s: %s", chunk.file_name, i, 699 println("%s: %x{2}: [%x{4}:%x{4}] %s: %s", chunk.file_name, i,
693 chunk.vars[i].offset, 700 chunk.vars[i].offset,