feat: implement address deferencing
This commit is contained in:
+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