diff options
-rw-r--r-- | src/compiler.c | 20 | ||||
-rw-r--r-- | src/semantic.c | 25 | ||||
-rw-r--r-- | src/vm.c | 12 | ||||
-rw-r--r-- | tests/compilation.bad | 11 |
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 | ||
15 | MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq) | 16 | MAPDEF(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 | ||
149 | typedef struct FindSymbolResult { | ||
150 | SymbolMap *map; | ||
151 | Scope *scope; | ||
152 | } FindSymbolResult; | ||
153 | |||
154 | FindSymbolResult | ||
155 | find_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 | |||
149 | void | 166 | void |
150 | graph_typescope(Scope *scope, Arena a) { | 167 | graph_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; |
@@ -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 @@ | |||
1 | let b = 8 | ||
1 | let a = 8 | 2 | let 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 | |||
8 | 1 + a | ||
6 | ; 0xf | 0xf0 | 9 | ; 0xf | 0xf0 |
7 | ; 0xf & 0xff | 10 | ; 0xf & 0xff |
8 | ; 0x1 << 2 | 11 | ; 0x1 << 2 |