From 7007afc2c4532326fa3bc32f70b7ad080c880925 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 28 Jun 2024 19:56:20 +0200 Subject: Add LDVAR to compilation and vm --- src/compiler.c | 20 ++++++++++++++++++++ src/semantic.c | 25 +++++++++++++++++++++++++ src/vm.c | 12 ++++++++++-- 3 files changed, 55 insertions(+), 2 deletions(-) (limited to 'src') 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 { Str type; sz size; sz offset; + sz idx; } Variable; MAPDEF(StrVarMap, varmap, Str, Variable, str_hash, str_eq) @@ -63,6 +64,7 @@ typedef enum OpCode { OP_HALT, // halt OP_STVARI, // stvari vx, ca OP_STVAR, // stvar vx, ra + OP_LDVAR, // ldvar rx, vx // Load/Store instructions. OP_LD8K, // ld8k rx, ca -> u8 rx = ca OP_LD16K, // ld16k rx, ca -> u16 rx = ca @@ -147,6 +149,7 @@ Str op_str[] = { [OP_HALT] = cstr("HALT "), [OP_STVAR] = cstr("STVAR "), [OP_STVARI] = cstr("STVARI "), + [OP_LDVAR] = cstr("LDVAR "), // Load ops. [OP_LD8K] = cstr("LD8K "), [OP_LD16K] = cstr("LD16K "), @@ -498,6 +501,7 @@ compile_expr(Chunk *chunk, Node *node) { .type = type, .size = size, .offset = chunk->var_off, + .idx = idx, }; varmap_insert(&chunk->varmap, name, var, chunk->storage); array_push(chunk->vars, var, chunk->storage); @@ -523,6 +527,18 @@ compile_expr(Chunk *chunk, Node *node) { return (CompResult){.type = COMP_NIL}; } break; + case NODE_SYMBOL: { + Str name = node->unique_name; + StrVarMap *map = varmap_lookup(&chunk->varmap, name); + if (!map) { + println("error: unreachable... name: %s", name); + exit(EXIT_FAILURE); + } + Variable var = map->val; + u8 reg_dst = chunk->reg_idx++; + EMIT_OP(OP_LDVAR, reg_dst, var.idx, 0, node->var_val, chunk); + return (CompResult){.type = COMP_REG, .idx = reg_dst}; + } break; case NODE_BLOCK: { CompResult res; for (sz i = 0; i < array_size(node->elements); i++) { @@ -623,6 +639,10 @@ disassemble_instruction(Instruction instruction) { println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, instruction.a, instruction.b); break; + case OP_LDVAR: + println("%s r%d, v%d", op_str[instruction.op], instruction.dst, + instruction.a, instruction.b); + break; case OP_STVAR: println("%s v%d, r%d", op_str[instruction.op], instruction.dst, 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) { return (FindStructResult){0}; } +typedef struct FindSymbolResult { + SymbolMap *map; + Scope *scope; +} FindSymbolResult; + +FindSymbolResult +find_symbol(Scope *scope, Str type) { + while (scope != NULL) { + SymbolMap *val = symmap_lookup(&scope->symbols, type); + if (val != NULL) { + return (FindSymbolResult){.map = val, .scope = scope}; + } + scope = scope->parent; + } + return (FindSymbolResult){0}; +} + void graph_typescope(Scope *scope, Arena a) { if (!scope->symbols) { @@ -868,6 +885,13 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { a->err = true; return cstr(""); } + + FindSymbolResult sym = find_symbol(scope, symbol); + node->unique_name = str_concat(cstr("."), symbol, a->storage); + node->unique_name = + str_concat(node->unique_name, + str_from_int(sym.scope->id, a->storage), a->storage); + Str type_name = type->val.name; if (node->kind == NODE_SYMBOL_IDX) { Str idx_type = type_inference(a, node->arr_size, scope); @@ -904,6 +928,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { a->err = true; return cstr(""); } + node->next->type = type_name; node->type = type_name; 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) { vm->regs[dst].f = fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); } break; + case OP_LDVAR: { + u8 dst = instruction.dst; + u8 src = instruction.a; + println("dst: %d src: %d", dst, src); + Variable var = vm->chunk->vars[src]; + s64 *stack = (s64 *)&vm->stack[var.offset]; + vm->regs[dst].i = *stack; + } break; case OP_STVAR: { u8 dst = instruction.dst; u8 src = instruction.a; Variable var = vm->chunk->vars[dst]; - s64 *stack = (s64*)&vm->stack[var.offset]; + s64 *stack = (s64 *)&vm->stack[var.offset]; *stack = vm->regs[src].i; } break; case OP_STVARI: { u8 dst = instruction.dst; u8 src = instruction.a; Variable var = vm->chunk->vars[dst]; - s64 *stack = (s64*)&vm->stack[var.offset]; + s64 *stack = (s64 *)&vm->stack[var.offset]; *stack = vm->chunk->constants[src].i; } break; case OP_HALT: { -- cgit v1.2.1