aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler.c20
-rw-r--r--src/semantic.c25
-rw-r--r--src/vm.c12
-rw-r--r--tests/compilation.bad11
4 files changed, 62 insertions, 6 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 04afd5d..bd50955 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -10,6 +10,7 @@ typedef struct Variable {
10 Str type; 10 Str type;
11 sz size; 11 sz size;
12 sz offset; 12 sz offset;
13 sz idx;
13} Variable; 14} Variable;
14 15
15MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq) 16MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq)
@@ -63,6 +64,7 @@ typedef enum OpCode {
63 OP_HALT, // halt 64 OP_HALT, // halt
64 OP_STVARI, // stvari vx, ca 65 OP_STVARI, // stvari vx, ca
65 OP_STVAR, // stvar vx, ra 66 OP_STVAR, // stvar vx, ra
67 OP_LDVAR, // ldvar rx, vx
66 // Load/Store instructions. 68 // Load/Store instructions.
67 OP_LD8K, // ld8k rx, ca -> u8 rx = ca 69 OP_LD8K, // ld8k rx, ca -> u8 rx = ca
68 OP_LD16K, // ld16k rx, ca -> u16 rx = ca 70 OP_LD16K, // ld16k rx, ca -> u16 rx = ca
@@ -147,6 +149,7 @@ Str op_str[] = {
147 [OP_HALT] = cstr("HALT "), 149 [OP_HALT] = cstr("HALT "),
148 [OP_STVAR] = cstr("STVAR "), 150 [OP_STVAR] = cstr("STVAR "),
149 [OP_STVARI] = cstr("STVARI "), 151 [OP_STVARI] = cstr("STVARI "),
152 [OP_LDVAR] = cstr("LDVAR "),
150 // Load ops. 153 // Load ops.
151 [OP_LD8K] = cstr("LD8K "), 154 [OP_LD8K] = cstr("LD8K "),
152 [OP_LD16K] = cstr("LD16K "), 155 [OP_LD16K] = cstr("LD16K "),
@@ -498,6 +501,7 @@ compile_expr(Chunk *chunk, Node *node) {
498 .type = type, 501 .type = type,
499 .size = size, 502 .size = size,
500 .offset = chunk->var_off, 503 .offset = chunk->var_off,
504 .idx = idx,
501 }; 505 };
502 varmap_insert(&chunk->varmap, name, var, chunk->storage); 506 varmap_insert(&chunk->varmap, name, var, chunk->storage);
503 array_push(chunk->vars, var, chunk->storage); 507 array_push(chunk->vars, var, chunk->storage);
@@ -523,6 +527,18 @@ compile_expr(Chunk *chunk, Node *node) {
523 527
524 return (CompResult){.type = COMP_NIL}; 528 return (CompResult){.type = COMP_NIL};
525 } break; 529 } break;
530 case NODE_SYMBOL: {
531 Str name = node->unique_name;
532 StrVarMap *map = varmap_lookup(&chunk->varmap, name);
533 if (!map) {
534 println("error: unreachable... name: %s", name);
535 exit(EXIT_FAILURE);
536 }
537 Variable var = map->val;
538 u8 reg_dst = chunk->reg_idx++;
539 EMIT_OP(OP_LDVAR, reg_dst, var.idx, 0, node->var_val, chunk);
540 return (CompResult){.type = COMP_REG, .idx = reg_dst};
541 } break;
526 case NODE_BLOCK: { 542 case NODE_BLOCK: {
527 CompResult res; 543 CompResult res;
528 for (sz i = 0; i < array_size(node->elements); i++) { 544 for (sz i = 0; i < array_size(node->elements); i++) {
@@ -623,6 +639,10 @@ disassemble_instruction(Instruction instruction) {
623 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, 639 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst,
624 instruction.a, instruction.b); 640 instruction.a, instruction.b);
625 break; 641 break;
642 case OP_LDVAR:
643 println("%s r%d, v%d", op_str[instruction.op], instruction.dst,
644 instruction.a, instruction.b);
645 break;
626 case OP_STVAR: 646 case OP_STVAR:
627 println("%s v%d, r%d", op_str[instruction.op], instruction.dst, 647 println("%s v%d, r%d", op_str[instruction.op], instruction.dst,
628 instruction.a, instruction.b); 648 instruction.a, instruction.b);
diff --git a/src/semantic.c b/src/semantic.c
index 1b40723..d782cac 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -146,6 +146,23 @@ find_struct(Scope *scope, Str type) {
146 return (FindStructResult){0}; 146 return (FindStructResult){0};
147} 147}
148 148
149typedef struct FindSymbolResult {
150 SymbolMap *map;
151 Scope *scope;
152} FindSymbolResult;
153
154FindSymbolResult
155find_symbol(Scope *scope, Str type) {
156 while (scope != NULL) {
157 SymbolMap *val = symmap_lookup(&scope->symbols, type);
158 if (val != NULL) {
159 return (FindSymbolResult){.map = val, .scope = scope};
160 }
161 scope = scope->parent;
162 }
163 return (FindSymbolResult){0};
164}
165
149void 166void
150graph_typescope(Scope *scope, Arena a) { 167graph_typescope(Scope *scope, Arena a) {
151 if (!scope->symbols) { 168 if (!scope->symbols) {
@@ -868,6 +885,13 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
868 a->err = true; 885 a->err = true;
869 return cstr(""); 886 return cstr("");
870 } 887 }
888
889 FindSymbolResult sym = find_symbol(scope, symbol);
890 node->unique_name = str_concat(cstr("."), symbol, a->storage);
891 node->unique_name =
892 str_concat(node->unique_name,
893 str_from_int(sym.scope->id, a->storage), a->storage);
894
871 Str type_name = type->val.name; 895 Str type_name = type->val.name;
872 if (node->kind == NODE_SYMBOL_IDX) { 896 if (node->kind == NODE_SYMBOL_IDX) {
873 Str idx_type = type_inference(a, node->arr_size, scope); 897 Str idx_type = type_inference(a, node->arr_size, scope);
@@ -904,6 +928,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
904 a->err = true; 928 a->err = true;
905 return cstr(""); 929 return cstr("");
906 } 930 }
931
907 node->next->type = type_name; 932 node->next->type = type_name;
908 node->type = type_name; 933 node->type = type_name;
909 return node->next->type; 934 return node->next->type;
diff --git a/src/vm.c b/src/vm.c
index 556fbe9..fac477a 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -134,18 +134,26 @@ 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: {
138 u8 dst = instruction.dst;
139 u8 src = instruction.a;
140 println("dst: %d src: %d", dst, src);
141 Variable var = vm->chunk->vars[src];
142 s64 *stack = (s64 *)&vm->stack[var.offset];
143 vm->regs[dst].i = *stack;
144 } break;
137 case OP_STVAR: { 145 case OP_STVAR: {
138 u8 dst = instruction.dst; 146 u8 dst = instruction.dst;
139 u8 src = instruction.a; 147 u8 src = instruction.a;
140 Variable var = vm->chunk->vars[dst]; 148 Variable var = vm->chunk->vars[dst];
141 s64 *stack = (s64*)&vm->stack[var.offset]; 149 s64 *stack = (s64 *)&vm->stack[var.offset];
142 *stack = vm->regs[src].i; 150 *stack = vm->regs[src].i;
143 } break; 151 } break;
144 case OP_STVARI: { 152 case OP_STVARI: {
145 u8 dst = instruction.dst; 153 u8 dst = instruction.dst;
146 u8 src = instruction.a; 154 u8 src = instruction.a;
147 Variable var = vm->chunk->vars[dst]; 155 Variable var = vm->chunk->vars[dst];
148 s64 *stack = (s64*)&vm->stack[var.offset]; 156 s64 *stack = (s64 *)&vm->stack[var.offset];
149 *stack = vm->chunk->constants[src].i; 157 *stack = vm->chunk->constants[src].i;
150 } break; 158 } break;
151 case OP_HALT: { 159 case OP_HALT: {
diff --git a/tests/compilation.bad b/tests/compilation.bad
index 120c020..0ffbb06 100644
--- a/tests/compilation.bad
+++ b/tests/compilation.bad
@@ -1,8 +1,11 @@
1let b = 8
1let a = 8 2let a = 8
2{ 3; {
3 let a = 1 + 2 * 4 4; let a = 1 + 2 * 4
4 let b = 3.0 5; let b = 3.0
5} 6; }
7
81 + a
6; 0xf | 0xf0 9; 0xf | 0xf0
7; 0xf & 0xff 10; 0xf & 0xff
8; 0x1 << 2 11; 0x1 << 2