This commit is contained in:
Lobo 2026-01-22 14:47:08 -03:00
parent 80d8f87883
commit e654143a90
7 changed files with 37 additions and 46 deletions

View file

@ -1,7 +1,7 @@
#ifndef CHUNK_H
#define CHUNK_H
#define CHUNK_DEBUG DEBUG
#define CHUNK_DEBUG 0
#include "common.h"
#include "object.h"
@ -12,6 +12,11 @@ typedef struct Bl {
I col;
} Bl;
typedef struct Bs {
const char *name;
struct Dt *resolved;
} Bs;
typedef struct Bc {
I ref;
const char *name;
@ -25,6 +30,10 @@ typedef struct Bc {
Bl *items;
Z count, capacity;
} lines;
struct {
Bs *items;
Z count, capacity;
} symbols;
} Bc;
Bc *chunk_new(const char *);

View file

@ -13,6 +13,4 @@ typedef uint8_t U8;
typedef uint32_t U32;
typedef uint64_t U64;
#define DEBUG 0
#endif

View file

@ -11,6 +11,7 @@
#include "vm.h"
#include "vendor/mpc.h"
#include "vendor/yar.h"
// clang-format off
struct {
@ -124,6 +125,18 @@ static I compile_constant(Cm *cm, O value, I line, I col) {
return 1;
}
static I add_sym(Bc *chunk, const char *name, Dt *word) {
for (Z i = 0; i < chunk->symbols.count; i++) {
if (strcmp(chunk->symbols.items[i].name, name) == 0)
return i;
}
Z idx = chunk->symbols.count;
Bs *sym = yar_append(&chunk->symbols);
sym->name = name;
sym->resolved = word;
return idx;
}
static I compile_call(Cm *cm, const char *name, I line, I col) {
for (Z i = 0; primitives[i].name != NULL; i++) {
if (strcmp(name, primitives[i].name) == 0) {
@ -139,8 +152,9 @@ static I compile_call(Cm *cm, const char *name, I line, I col) {
line + 1, col + 1, name);
return 0;
}
I idx = add_sym(cm->chunk, name, word);
chunk_emit_byte_with_line(cm->chunk, OP_DOWORD, line, col);
chunk_emit_sleb128(cm->chunk, (I)word->hash);
chunk_emit_sleb128(cm->chunk, idx);
return 1;
}

View file

@ -7,7 +7,7 @@
#include "vendor/mpc.h"
#define COMPILER_DEBUG DEBUG
#define COMPILER_DEBUG 0
/** Compiler context */
typedef struct Cm {
@ -19,12 +19,4 @@ typedef struct Cm {
V compiler_init(Cm *, Vm *, const char *);
V compiler_deinit(Cm *);
// Hash function for word names
U64 hash64(const char *);
// Dictionary lookup
Dt *upsert(Dt **, const char *, Ar *);
// The chunk returned by `compile_program` is owned by the caller.
Bc *compile_program(Cm *, mpc_ast_t *);

View file

@ -92,39 +92,17 @@ static Z dis_instr(Bc *chunk, Z offset, Dt **dictionary, I indent) {
SIMPLE(FROMR);
CASE(DOWORD) {
Z bytes_read;
I hash = decode_sleb128(&chunk->items[offset], &bytes_read);
printf("DOWORD");
if (dictionary && *dictionary) {
Dt *entry = lookup_hash(dictionary, hash);
if (entry != NULL) {
printf(" %s", entry->name);
} else {
printf(" ???");
}
} else {
printf(" 0x%lx", hash);
}
printf("\n");
I idx = decode_sleb128(&chunk->items[offset], &bytes_read);
Dt *word = chunk->symbols.items[idx].resolved;
printf("DOWORD %s\n", word->name);
return offset + bytes_read;
}
SIMPLE(CALL);
CASE(TAIL_DOWORD) {
Z bytes_read;
I hash = decode_sleb128(&chunk->items[offset], &bytes_read);
printf("TAIL_DOWORD");
if (dictionary && *dictionary) {
Dt *entry = lookup_hash(dictionary, hash);
if (entry != NULL) {
printf(" %s", entry->name);
} else {
printf(" ???");
}
} else {
printf(" 0x%lx", hash);
}
printf("\n");
I idx = decode_sleb128(&chunk->items[offset], &bytes_read);
Dt *word = chunk->symbols.items[idx].resolved;
printf("TAIL_DOWORD %s\n", word->name);
return offset + bytes_read;
}
SIMPLE(TAIL_CALL);

View file

@ -4,7 +4,7 @@
#include "common.h"
#include "object.h"
#define GC_DEBUG 1
#define GC_DEBUG 0
#if GC_DEBUG
#define HEAP_BYTES (8 * 1024)
#else

View file

@ -228,8 +228,8 @@ I vm_run(Vm *vm, Bc *chunk, I offset) {
break;
}
case OP_DOWORD: {
I hash = decode_sleb128(&vm->ip);
Dt *word = lookup_hash(&vm->dictionary, hash);
I idx = decode_sleb128(&vm->ip);
Dt *word = vm->chunk->symbols.items[idx].resolved;
if (!word)
vm_error(vm, VM_ERR_RUNTIME, "word not found");
vm_rpush(vm, vm->chunk, vm->ip);
@ -251,8 +251,8 @@ I vm_run(Vm *vm, Bc *chunk, I offset) {
break;
}
case OP_TAIL_DOWORD: {
I hash = decode_sleb128(&vm->ip);
Dt *word = lookup_hash(&vm->dictionary, hash);
I idx = decode_sleb128(&vm->ip);
Dt *word = vm->chunk->symbols.items[idx].resolved;
if (!word)
vm_error(vm, VM_ERR_RUNTIME, "word not found");
vm->chunk = word->chunk;