feat: implement address deferencing
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user