diff options
Diffstat (limited to 'src/compiler.c')
-rw-r--r-- | src/compiler.c | 20 |
1 files changed, 20 insertions, 0 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); |