feat: implement functions
This commit is contained in:
+43
-13
@@ -4,6 +4,7 @@
|
||||
#include <common/fzl_types.h>
|
||||
#include <common/fzl_value.h>
|
||||
#include <compiler/utils/fzl_const_pool.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -123,6 +124,27 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case FZL_OPCODE_CALL:
|
||||
{
|
||||
uint64_t ip = vm->ops[++vm->ip];
|
||||
vm->cstack[vm->ctop++] = vm->ip;
|
||||
vm->ip = ip - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_RET:
|
||||
{
|
||||
if (vm->ctop < 1)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - no place to jump");
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm->ip = vm->cstack[--vm->ctop];
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_CMP_EQ:
|
||||
if (vm->dtop < 2)
|
||||
{
|
||||
@@ -131,10 +153,10 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t leq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t req = vm->dstack[--vm->dtop];
|
||||
fzl_value_t leq = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = leq.as.b == req.as.b};
|
||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = leq.as.u == req.as.u};
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_CMP_NEQ:
|
||||
@@ -145,8 +167,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t lneq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rneq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t lneq = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_BOOL,
|
||||
.as.b = lneq.as.u != rneq.as.u};
|
||||
break;
|
||||
@@ -159,8 +181,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t llt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rlt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t llt = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = llt.as.u < rlt.as.u};
|
||||
break;
|
||||
@@ -173,8 +195,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t llteq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rlteq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t llteq = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){
|
||||
.type = FZL_TYPE_BOOL, .as.b = llteq.as.u <= rlteq.as.u};
|
||||
break;
|
||||
@@ -187,8 +209,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t lgt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rgt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t lgt = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = lgt.as.u > rgt.as.u};
|
||||
break;
|
||||
@@ -201,8 +223,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t lgteq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rgteq = vm->dstack[--vm->dtop];
|
||||
fzl_value_t lgteq = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){
|
||||
.type = FZL_TYPE_BOOL, .as.b = lgteq.as.u >= rgteq.as.u};
|
||||
break;
|
||||
@@ -319,7 +341,9 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
}
|
||||
}
|
||||
|
||||
vm->dstack[vm->dtop++] = value;
|
||||
// vm->dstack[vm->dtop++] = value;
|
||||
// NOTE: add POP opcode to prevent
|
||||
// stack overflow!
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_MK_ENVTABLE:
|
||||
@@ -340,8 +364,14 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
}
|
||||
|
||||
fzl_value_t val = vm->dstack[--vm->dtop];
|
||||
fzl_value_t env_val =
|
||||
fzl_env_lookup(vm->estack[vm->etop - 1], (char *)val.as.s.value);
|
||||
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;
|
||||
|
||||
break;
|
||||
@@ -411,10 +441,10 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
"runtime error - expected 2 values in stack");
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t sub1 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t sub2 = vm->dstack[--vm->dtop];
|
||||
fzl_value_t sub1 = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = add1.type, .as.u = sub1.as.u - sub2.as.u};
|
||||
(fzl_value_t){.type = sub1.type, .as.u = sub1.as.u - sub2.as.u};
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_MUL:
|
||||
@@ -450,8 +480,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
"runtime error - expected 2 values in stack");
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t pow1 = vm->dstack[--vm->dtop];
|
||||
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;
|
||||
|
||||
+13
-1
@@ -20,6 +20,17 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
|
||||
switch (vm->ops[i])
|
||||
{
|
||||
case FZL_OPCODE_CALL:
|
||||
{
|
||||
size_t ip = vm->ops[++i];
|
||||
printf("Call IP: %lu\n", ip);
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_RET:
|
||||
printf("Return\n");
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_LOADCONST:
|
||||
{
|
||||
size_t const_n = vm->ops[++i];
|
||||
@@ -79,6 +90,7 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
|
||||
case FZL_OPCODE_CMP_EQ:
|
||||
printf("CMP_EQ\n");
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_CMP_NEQ:
|
||||
printf("CMP_NEQ\n");
|
||||
@@ -113,7 +125,7 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_JMP:
|
||||
printf("JMP IP %ld\n", vm->ops[++i]);
|
||||
printf("JMP IP: %ld\n", vm->ops[++i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+7
-4
@@ -28,16 +28,19 @@ static void resize_env_if_needed(fzl_vm_env_t *env)
|
||||
env->table = realloc(env->table, env->remainder * sizeof(fzl_vm_env_entry_t));
|
||||
}
|
||||
|
||||
fzl_value_t fzl_env_lookup(fzl_vm_env_t *env, char *name)
|
||||
bool fzl_env_lookup(fzl_vm_env_t *env, char *name, fzl_value_t *res)
|
||||
{
|
||||
if (!env)
|
||||
return null;
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < env->size; i++)
|
||||
if (strcmp(env->table[i].name, name) == 0)
|
||||
return env->table[i].value;
|
||||
{
|
||||
*res = env->table[i].value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return (fzl_value_t){.type = FZL_TYPE_NULL};
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fzl_env_contains(fzl_vm_env_t *env, char *name)
|
||||
|
||||
Reference in New Issue
Block a user