Implement some more instructions

This commit is contained in:
2026-06-24 10:17:58 +10:00
parent c495b7c6fc
commit fa2c205f33

View File

@@ -1,6 +1,8 @@
#include "../../../include/ground.h"
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
@@ -479,18 +481,124 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1;
}
GREATER: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int > right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int > right->as.Double);
break;
}
default: {
*final = Ground.New.Value.Bool(true);
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double > right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double > right->as.Double);
break;
}
default: {
*final = Ground.New.Value.Bool(true);
break;
}
}
break;
}
default: {
*final = Ground.New.Value.Bool(false);
break;
}
}
return -1;
}
LESSER: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int < right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int < right->as.Double);
break;
}
default: {
*final = Ground.New.Value.Bool(true);
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double < right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double < right->as.Double);
break;
}
default: {
*final = Ground.New.Value.Bool(true);
break;
}
}
break;
}
default: {
*final = Ground.New.Value.Bool(false);
break;
}
}
return -1;
}
AND: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool && right->as.Bool);
return -1;
}
OR: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool || right->as.Bool);
return -1;
}
XOR: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool != right->as.Bool);
return -1;
}
NEG: {
@@ -500,27 +608,99 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1;
}
STOI: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
char* status = NULL;
*final = Ground.New.Value.Int(strtoll(in->as.String.cstr, &status, 0));
if (status != in->as.String.cstr) {
Ground.Flags.error = true;
Ground.Log.Error("Failed converting string to double");
}
return -1;
}
STOD: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
char* status = NULL;
*final = Ground.New.Value.Double(strtod(in->as.String.cstr, &status));
if (status != in->as.String.cstr) {
Ground.Flags.error = true;
Ground.Log.Error("Failed converting string to double");
}
return -1;
}
ITOC: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
*final = Ground.New.Value.Char((char)in->as.Int);
return -1;
}
CTOI: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
*final = Ground.New.Value.Int((int64_t)in->as.Char);
return -1;
}
TOSTRING: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
char buf[4096];
switch (in->type.type) {
case GroundType_Int: {
snprintf(buf, sizeof(buf), "%" PRId64, in->as.Int);
break;
}
case GroundType_Double: {
snprintf(buf, sizeof(buf), "%f", in->as.Double);
break;
}
case GroundType_Char: {
snprintf(buf, sizeof(buf), "%c", in->as.Char);
break;
}
case GroundType_Bool: {
snprintf(buf, sizeof(buf), in->as.Bool ? "true" : "false");
break;
}
case GroundType_String: {
*in = Ground.New.Value.String(final->as.String);
return -1;
}
default: {
// TODO: implement tostring for complex types
snprintf(buf, sizeof(buf), "<FIXME>");
break;
}
}
*in = Ground.New.Value.String(Ground.New.String(buf));
return -1;
}
FUN: {
// no-op
return -1;
}
RETURN: {
return -1;
}
ENDFUN: {
// no-op
return -1;
}
CALL: {
@@ -530,9 +710,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1;
}
STRUCT: {
// no-op
return -1;
}
ENDSTRUCT: {
// no-op
return -1;
}
INIT: {
@@ -551,12 +733,16 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1;
}
CREATELABEL: {
// no-op
return -1;
}
PAUSE: {
return -1;
}
DROP: {
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
Ground.Free.Value(in);
*in = Ground.New.Value.Int(0);
return -1;
}
LICENSE: {