feat: implement conditions

This commit is contained in:
samsonium
2026-10-14 19:56:27 +03:00
parent 4a908f9fd8
commit 83ff0b5774
11 changed files with 731 additions and 25 deletions
+152 -1
View File
@@ -123,6 +123,149 @@ int fzl_vm_run(fzl_vm_t *vm)
switch (opcode)
{
case FZL_OPCODE_CMP_EQ:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t leq = vm->dstack[--vm->dtop];
fzl_value_t req = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = leq.as.b == req.as.b};
break;
case FZL_OPCODE_CMP_NEQ:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t lneq = vm->dstack[--vm->dtop];
fzl_value_t rneq = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_BOOL,
.as.b = lneq.as.u != rneq.as.u};
break;
case FZL_OPCODE_CMP_LT:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t llt = vm->dstack[--vm->dtop];
fzl_value_t rlt = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = llt.as.u < rlt.as.u};
break;
case FZL_OPCODE_CMP_LTEQ:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t llteq = vm->dstack[--vm->dtop];
fzl_value_t rlteq = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] = (fzl_value_t){
.type = FZL_TYPE_BOOL, .as.b = llteq.as.u <= rlteq.as.u};
break;
case FZL_OPCODE_CMP_GT:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t lgt = vm->dstack[--vm->dtop];
fzl_value_t rgt = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = lgt.as.u > rgt.as.u};
break;
case FZL_OPCODE_CMP_GTEQ:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t lgteq = vm->dstack[--vm->dtop];
fzl_value_t rgteq = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] = (fzl_value_t){
.type = FZL_TYPE_BOOL, .as.b = lgteq.as.u >= rgteq.as.u};
break;
case FZL_OPCODE_NOT:
if (vm->dtop < 1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected value in data stack");
return -1;
}
fzl_value_t notval = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = !notval.as.b};
break;
case FZL_OPCODE_JZ:
if (vm->dtop < 1)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected value in data stack");
return -1;
}
fzl_value_t jzval = vm->dstack[--vm->dtop];
uint64_t jzip = vm->ops[++vm->ip] - 1;
if (jzval.as.b == 0)
vm->ip = jzip;
break;
case FZL_OPCODE_JMP:
vm->ip = vm->ops[++vm->ip] - 1;
break;
case FZL_OPCODE_AND:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t land = vm->dstack[--vm->dtop];
fzl_value_t rand = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_BOOL,
.as.b = land.as.b && rand.as.b};
break;
case FZL_OPCODE_OR:
if (vm->dtop < 2)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected two values in data stack");
return -1;
}
fzl_value_t lor = vm->dstack[--vm->dtop];
fzl_value_t ror = vm->dstack[--vm->dtop];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = lor.as.b || ror.as.b};
break;
case FZL_OPCODE_STORE:
if (vm->dtop < 1)
{
@@ -350,8 +493,16 @@ int fzl_vm_run(fzl_vm_t *vm)
uint64_t push_n = vm->ops[++vm->ip];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_UINT, .as.u = push_n};
break;
}
case FZL_OPCODE_PUSHBOOL:
{
uint64_t push_b = vm->ops[++vm->ip];
vm->dstack[vm->dtop++] =
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = push_b};
break;
}
break;
default:
snprintf(last_err, sizeof(last_err),
+56 -2
View File
@@ -1,4 +1,5 @@
#include "common/fzl_opcodes.h"
#include <stdbool.h>
#include <stdio.h>
#include <vm/fzl_vm.h>
@@ -15,11 +16,17 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
for (size_t i = 0; i < vm->ops_count; i++)
{
printf("%04ld: ", i);
switch (vm->ops[i])
{
case FZL_OPCODE_LOADCONST:
printf("LOADCONST #%lu\n", vm->ops[++i]);
{
size_t const_n = vm->ops[++i];
fzl_const_t c = vm->consts[const_n];
printf("LOADCONST #%lu ('%s')\n", const_n, c.as.string.chars);
break;
}
case FZL_OPCODE_CALL_BUILTIN:
printf("CALL_BUILTIN #%lu\n", vm->ops[++i]);
@@ -29,6 +36,10 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
printf("PUSHNUM %lu\n", vm->ops[++i]);
break;
case FZL_OPCODE_PUSHBOOL:
printf("PUSHBOOL %s\n", vm->ops[++i] ? "true" : "false");
break;
case FZL_OPCODE_MK_ENVTABLE:
printf("MK_ENVTABLE\n");
break;
@@ -58,12 +69,55 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
printf("Math opcode\n");
break;
case FZL_OPCODE_AND:
printf("AND\n");
break;
case FZL_OPCODE_OR:
printf("OR\n");
break;
case FZL_OPCODE_CMP_EQ:
printf("CMP_EQ\n");
case FZL_OPCODE_CMP_NEQ:
printf("CMP_NEQ\n");
break;
case FZL_OPCODE_CMP_LT:
printf("CMP_LT\n");
break;
case FZL_OPCODE_CMP_LTEQ:
printf("CMP_LTEQ\n");
break;
case FZL_OPCODE_CMP_GT:
printf("CMP_GT\n");
break;
case FZL_OPCODE_CMP_GTEQ:
printf("CMP_GTEQ\n");
break;
case FZL_OPCODE_NOT:
printf("CMP_NOT\n");
break;
case FZL_OPCODE_NEG:
printf("NEG\n");
break;
case FZL_OPCODE_JZ:
printf("JZ IP: %ld\n", vm->ops[++i]);
break;
case FZL_OPCODE_JMP:
printf("JMP IP %ld\n", vm->ops[++i]);
break;
default:
printf("Unknown");
printf("<Unknown>\n");
}
}
}