From fa2c205f333a13ef5f4e303efbf2aa9b86ce3904 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Wed, 24 Jun 2026 10:17:58 +1000 Subject: [PATCH] Implement some more instructions --- src/Bytecode/Instruction/execute.c | 186 +++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/src/Bytecode/Instruction/execute.c b/src/Bytecode/Instruction/execute.c index 26e8220..c4c1af1 100644 --- a/src/Bytecode/Instruction/execute.c +++ b/src/Bytecode/Instruction/execute.c @@ -1,6 +1,8 @@ #include "../../../include/ground.h" #include #include +#include +#include #include #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), ""); + 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: {