feat: implement conditions
This commit is contained in:
+152
-1
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user