diff options
Diffstat (limited to 'src/compiler.c')
-rw-r--r-- | src/compiler.c | 61 |
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 | ||
32 | typedef struct LineCol { | ||
33 | sz line; | ||
34 | sz col; | ||
35 | } LineCol; | ||
36 | |||
32 | typedef struct Chunk { | 37 | typedef 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 | ||
60 | typedef enum OpCode { | 65 | typedef 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 | ||
148 | Str op_str[] = { | 153 | Str 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 | ||
246 | CompResult compile_expr(Chunk *chunk, Node *node); | 251 | CompResult 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 | ||
259 | CompResult | 266 | CompResult |
@@ -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 | ||
669 | void | 676 | void |
670 | disassemble_chunk(Chunk chunk) { | 677 | disassemble_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, |