diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-29 11:04:24 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-29 14:28:01 +0200 |
commit | b643366c0ef18c27aa1ac52e1dd035f1d6efa45e (patch) | |
tree | ebae0239988d353d1e94f49b31df924a1a9858c7 /src | |
parent | 5ad13b02773735b66e5fc1f78252548fae124c93 (diff) | |
download | bdl-b643366c0ef18c27aa1ac52e1dd035f1d6efa45e.tar.gz bdl-b643366c0ef18c27aa1ac52e1dd035f1d6efa45e.zip |
Add linecol info for debugging if needed
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler.c | 61 | ||||
-rw-r--r-- | src/main.c | 8 | ||||
-rw-r--r-- | src/vm.c | 6 |
3 files changed, 41 insertions, 34 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, |
@@ -219,10 +219,10 @@ process_file(Str path) { | |||
219 | // println("VM REGISTERS BEFORE:\n%{Mem}", | 219 | // println("VM REGISTERS BEFORE:\n%{Mem}", |
220 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); | 220 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); |
221 | vm_run(&vm); | 221 | vm_run(&vm); |
222 | println("VM REGISTERS AFTER:\n%{Mem}", | 222 | // println("VM REGISTERS AFTER:\n%{Mem}", |
223 | &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); | 223 | // &(Array){.mem = (u8 *)&vm.regs, sizeof(vm.regs)}); |
224 | println("VM MEMORY AFTER:\n%{Mem}", | 224 | // println("VM MEMORY AFTER:\n%{Mem}", |
225 | &(Array){.mem = (u8 *)&vm.stack, sizeof(vm.stack)}); | 225 | // &(Array){.mem = (u8 *)&vm.stack, sizeof(vm.stack)}); |
226 | 226 | ||
227 | #if DEBUG == 1 | 227 | #if DEBUG == 1 |
228 | println("Space used: %{Arena}", &lexer_arena); | 228 | println("Space used: %{Arena}", &lexer_arena); |
@@ -134,7 +134,7 @@ vm_run(VM *vm) { | |||
134 | vm->regs[dst].f = | 134 | vm->regs[dst].f = |
135 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); | 135 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); |
136 | } break; | 136 | } break; |
137 | case OP_LDVAR: { | 137 | case OP_LDGVAR: { |
138 | u8 dst = instruction.dst; | 138 | u8 dst = instruction.dst; |
139 | u8 src = instruction.a; | 139 | u8 src = instruction.a; |
140 | println("dst: %d src: %d", dst, src); | 140 | println("dst: %d src: %d", dst, src); |
@@ -142,14 +142,14 @@ vm_run(VM *vm) { | |||
142 | s64 *stack = (s64 *)&vm->stack[var.offset]; | 142 | s64 *stack = (s64 *)&vm->stack[var.offset]; |
143 | vm->regs[dst].i = *stack; | 143 | vm->regs[dst].i = *stack; |
144 | } break; | 144 | } break; |
145 | case OP_STVAR: { | 145 | case OP_STGVAR: { |
146 | u8 dst = instruction.dst; | 146 | u8 dst = instruction.dst; |
147 | u8 src = instruction.a; | 147 | u8 src = instruction.a; |
148 | Variable var = vm->chunk->vars[dst]; | 148 | Variable var = vm->chunk->vars[dst]; |
149 | s64 *stack = (s64 *)&vm->stack[var.offset]; | 149 | s64 *stack = (s64 *)&vm->stack[var.offset]; |
150 | *stack = vm->regs[src].i; | 150 | *stack = vm->regs[src].i; |
151 | } break; | 151 | } break; |
152 | case OP_STVARI: { | 152 | case OP_STGVARI: { |
153 | u8 dst = instruction.dst; | 153 | u8 dst = instruction.dst; |
154 | u8 src = instruction.a; | 154 | u8 src = instruction.a; |
155 | Variable var = vm->chunk->vars[dst]; | 155 | Variable var = vm->chunk->vars[dst]; |