Files
fz-lang/src/vm/handlers/group_ctx.c
T

128 lines
2.9 KiB
C

#include <vm/fzl_vm.h>
#include <vm/internals/opcode.h>
// Allocate environment table and increment scope level
int op_mk_envtable(fzl_vm_t *vm)
{
vm->estack[vm->etop++] = fzl_mkenv();
return 0;
}
// Remove environment table and decrement scope level
int op_rm_envtable(fzl_vm_t *vm)
{
fzl_freeenv(vm->estack[--vm->etop]);
return 0;
}
// Store new variable
int op_store(fzl_vm_t *vm)
{
if (vm->dtop < 1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected var name in data stack");
print_err_data(vm);
return -1;
}
fzl_value_t varname = vm->dstack[--vm->dtop];
fzl_env_storevalue(vm->estack[vm->etop - 1], (char *)varname.as.s.value,
(fzl_value_t){});
return 0;
}
// Lookup environment(s) for variable using name on stack
int op_lookup_env(fzl_vm_t *vm)
{
if (vm->dtop < 1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - LOOKUP_ENV: empty data stack");
print_err_data(vm);
return -1;
}
fzl_value_t val = vm->dstack[--vm->dtop];
fzl_value_t env_val;
bool result;
for (ssize_t i = vm->etop - 1; i >= 0; i--)
{
if ((result =
fzl_env_lookup(vm->estack[i], (char *)val.as.s.value, &env_val)))
break;
}
vm->dstack[vm->dtop++] = env_val;
return 0;
}
// Writable variable value
int op_write(fzl_vm_t *vm)
{
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected 2 values in data stack");
print_err_data(vm);
return -1;
}
fzl_value_t writevar = vm->dstack[--vm->dtop];
fzl_value_t value = vm->dstack[--vm->dtop];
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;
}
}
if (wrlvl <= -1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - name '%s' not found in this scope", wrname);
print_err_data(vm);
return -1;
}
fzl_vm_env_wresult_t wresult =
fzl_env_writevalue(vm->estack[wrlvl], (char *)wrname, value);
if (wresult != FZL_VM_ENV_WRESULT_OK)
{
switch (wresult)
{
case FZL_VM_ENV_WRESULT_ERR:
snprintf(last_err, sizeof(last_err),
"runtime error - failed to write variable");
print_err_data(vm);
return -1;
case FZL_VM_ENV_WRESULT_ERR_EXISTS:
snprintf(last_err, sizeof(last_err),
"runtime error - redefenition of '%s'", writevar.as.s.value);
print_err_data(vm);
return -1;
case FZL_VM_ENV_WRESULT_ERR_NOT_FOUND:
snprintf(last_err, sizeof(last_err),
"runtime error - cannot find name '%s'", writevar.as.s.value);
print_err_data(vm);
return -1;
default:
print_err_data(vm);
return -1;
}
}
return 0;
}