feat: implement address deferencing

This commit is contained in:
samsonium
2026-10-18 18:42:02 +03:00
parent c0df5fc9d4
commit 801b28e27d
4 changed files with 53 additions and 3 deletions
+1
View File
@@ -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
+1
View File
@@ -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};
}
+47 -3
View File
@@ -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)
+4
View File
@@ -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;