aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-29 11:04:24 +0200
committerBad Diode <bd@badd10de.dev>2024-06-29 14:28:01 +0200
commitb643366c0ef18c27aa1ac52e1dd035f1d6efa45e (patch)
treeebae0239988d353d1e94f49b31df924a1a9858c7
parent5ad13b02773735b66e5fc1f78252548fae124c93 (diff)
downloadbdl-b643366c0ef18c27aa1ac52e1dd035f1d6efa45e.tar.gz
bdl-b643366c0ef18c27aa1ac52e1dd035f1d6efa45e.zip
Add linecol info for debugging if needed
-rw-r--r--src/compiler.c61
-rw-r--r--src/main.c8
-rw-r--r--src/vm.c6
-rw-r--r--tests/compilation.bad34
4 files changed, 47 insertions, 62 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,
diff --git a/src/main.c b/src/main.c
index e14ef43..0e453c6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/vm.c b/src/vm.c
index fac477a..4e15bee 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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];
diff --git a/tests/compilation.bad b/tests/compilation.bad
index 0ffbb06..f1f027a 100644
--- a/tests/compilation.bad
+++ b/tests/compilation.bad
@@ -1,30 +1,8 @@
1let b = 8
2let a = 8 1let a = 8
3; { 2let b = 16
4; let a = 1 + 2 * 4 3let c = {
5; let b = 3.0 4 let a = 32
6; } 5 a + 8
6}
7 7
81 + a 8a + b + c
9; 0xf | 0xf0
10; 0xf & 0xff
11; 0x1 << 2
12; 0x1 << 2
13; (~0xf & 0xfff << 8) == 0xfff00
14; 0xf << 4 | 0xf
15; 1 + 2
16; 1 < 2
17; !(1 == 0 || 1 <= 1)
18; 1 == 1 && 1 <= 1
19; !((1 * 2 * 3) * (1 * 2 * 3) >= 3 && 4 != 3 + 2)
20; 1 + 2 * 3
21; 1.0 + 2.0 * 3.0
22; true
23; false
24; 0 1
25; "hello"
26; "world"
27; fun foo(): int {
28; 32
29; }
30; 1 + 2 + foo()