From 801b28e27d522b1259ce8662103950ef8b24a9e6 Mon Sep 17 00:00:00 2001 From: samsonium Date: Sun, 18 Oct 2026 18:42:02 +0300 Subject: [PATCH] feat: implement address deferencing --- include/common/fzl_opcodes.h | 1 + src/compiler/fzl_walker.c | 1 + src/vm/fzl_vm.c | 50 +++++++++++++++++++++++++++++++++--- src/vm/fzl_vm_debug.c | 4 +++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/common/fzl_opcodes.h b/include/common/fzl_opcodes.h index 35e26a0..1484134 100644 --- a/include/common/fzl_opcodes.h +++ b/include/common/fzl_opcodes.h @@ -25,6 +25,7 @@ typedef enum FZL_OPCODE_GET_FIELD = 0xFA0002, // Get field N of an object at dstack FZL_OPCODE_SET_FIELD = 0xFA0003, // Set field N of an object at dstack FZL_OPCODE_ESCAPE_OBJECT = 0xFA0004, // Make parent envtable as owner + FZL_OPCODE_DEREFERENCE = 0xFA0005, // Dereference address FZL_OPCODE_ADD = 0xA00001, // Sum two numbers in dstack FZL_OPCODE_SUB = 0xA00002, // Subract two numbers in dstack diff --git a/src/compiler/fzl_walker.c b/src/compiler/fzl_walker.c index 6537e88..a99af45 100644 --- a/src/compiler/fzl_walker.c +++ b/src/compiler/fzl_walker.c @@ -942,6 +942,7 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node) fzl_token_t *tok = node->token; push_op(walker, FZL_OPCODE_PUSHNUM); push_word(walker, 0); + push_op(walker, FZL_OPCODE_DEREFERENCE); current_res = (fzl_walk_res_t){ .type = FZL_TYPE_OBJECT, .error = false, .classname = null_name}; } diff --git a/src/vm/fzl_vm.c b/src/vm/fzl_vm.c index d9f1d02..3b13ee7 100644 --- a/src/vm/fzl_vm.c +++ b/src/vm/fzl_vm.c @@ -279,6 +279,37 @@ int fzl_vm_run(fzl_vm_t *vm) switch (opcode) { + case FZL_OPCODE_DEREFERENCE: + { + if (vm->dtop < 1) + { + snprintf(last_err, sizeof(last_err), + "runtime error - expected value in data stack"); + print_err_data(vm); + return -1; + } + + fzl_value_t addr = vm->dstack[--vm->dtop]; + if (addr.type < FZL_TYPE_INT8) + { + snprintf(last_err, sizeof(last_err), + "runtime error - expected address"); + print_err_data(vm); + return -1; + } + + if (addr.as.u == 0) + { + vm->dstack[vm->dtop++] = + (fzl_value_t){.type = FZL_TYPE_OBJECT, .as.obj = NULL}; + break; + } + + vm->dstack[vm->dtop++] = (fzl_value_t){ + .type = FZL_TYPE_OBJECT, .as.obj = (fzl_vm_object_t *)addr.as.u}; + break; + } + case FZL_OPCODE_CMP_EQ_STR: { if (vm->dtop < 2) @@ -359,7 +390,7 @@ int fzl_vm_run(fzl_vm_t *vm) return -1; } fzl_value_t obj = vm->dstack[--vm->dtop]; - if (obj.type != FZL_TYPE_OBJECT && obj.type < FZL_TYPE_INT8) + if (obj.type != FZL_TYPE_OBJECT) { snprintf(last_err, sizeof(last_err), "runtime error - cannot escape non-object type"); @@ -679,8 +710,21 @@ int fzl_vm_run(fzl_vm_t *vm) fzl_value_t writevar = vm->dstack[--vm->dtop]; fzl_value_t value = vm->dstack[--vm->dtop]; - fzl_vm_env_wresult_t wresult = fzl_env_writevalue( - vm->estack[vm->etop - 1], (char *)writevar.as.s.value, value); + char *wrname = (char *)writevar.as.s.value; + bool wrfound; + fzl_value_t wrenv; + ssize_t wrlvl = -1; + for (ssize_t i = vm->etop - 1; i >= 0; i--) + { + if ((wrfound = fzl_env_lookup(vm->estack[i], wrname, &wrenv))) + { + wrlvl = i; + break; + } + } + + fzl_vm_env_wresult_t wresult = + fzl_env_writevalue(vm->estack[wrlvl], (char *)wrname, value); if (wresult != FZL_VM_ENV_WRESULT_OK) { switch (wresult) diff --git a/src/vm/fzl_vm_debug.c b/src/vm/fzl_vm_debug.c index 26404ad..eea0ef2 100644 --- a/src/vm/fzl_vm_debug.c +++ b/src/vm/fzl_vm_debug.c @@ -20,6 +20,10 @@ void fzl_vm_print_ops(fzl_vm_t *vm) switch (vm->ops[i]) { + case FZL_OPCODE_DEREFERENCE: + printf("DEREFERENCE\n"); + break; + case FZL_OPCODE_CMP_EQ_STR: printf("CMP_EQ_STR\n"); break;