- Feat: add usage of vm reader instead of old way in vm.c - Ref: update debug opcodes printing
128 lines
3.1 KiB
C
128 lines
3.1 KiB
C
#include <stdio.h>
|
|
#include <vm/fzl_vm.h>
|
|
#include <vm/internals/opcode.h>
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_add(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t add1 = vm->dstack[--vm->dtop];
|
|
fzl_value_t add2 = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = add1.type, .as.u = add1.as.u + add2.as.u};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_sub(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t sub2 = vm->dstack[--vm->dtop];
|
|
fzl_value_t sub1 = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = sub1.type, .as.u = sub1.as.u - sub2.as.u};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_mul(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t mul1 = vm->dstack[--vm->dtop];
|
|
fzl_value_t mul2 = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = mul1.type, .as.u = mul1.as.u * mul2.as.u};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_div(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t div1 = vm->dstack[--vm->dtop];
|
|
fzl_value_t div2 = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = div1.type, .as.u = div2.as.u / div1.as.u};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_pow(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t pow2 = vm->dstack[--vm->dtop];
|
|
fzl_value_t pow1 = vm->dstack[--vm->dtop];
|
|
|
|
uint64_t pow_n = pow1.as.u;
|
|
uint64_t pow_res = pow_n;
|
|
uint64_t pow_times = pow2.as.u;
|
|
for (size_t i = 1; i < pow_times; i++)
|
|
pow_res *= pow_n;
|
|
|
|
vm->dstack[vm->dtop++] = (fzl_value_t){.type = pow1.type, .as.u = pow_res};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_mod(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 2)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected 2 values in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t mod1 = vm->dstack[--vm->dtop];
|
|
fzl_value_t mod2 = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = mod1.type, .as.u = mod2.as.u % mod1.as.u};
|
|
return 0;
|
|
}
|
|
|
|
// Pop two numbers and push sum result
|
|
int op_neg(fzl_vm_t *vm)
|
|
{
|
|
if (vm->dtop < 1)
|
|
{
|
|
snprintf(last_err, sizeof(last_err),
|
|
"runtime error - expected value in stack");
|
|
print_err_data(vm);
|
|
return -1;
|
|
}
|
|
fzl_value_t neg_n = vm->dstack[--vm->dtop];
|
|
vm->dstack[vm->dtop++] =
|
|
(fzl_value_t){.type = neg_n.type, .as.u = -neg_n.as.u};
|
|
return 0;
|
|
}
|