This commit is contained in:
2026-06-16 19:19:37 +10:00
parent da75cf7590
commit 9539629cfb
3 changed files with 393 additions and 11 deletions

View File

@@ -336,7 +336,7 @@ struct _Ground {
struct {
void (*append) (GroundInstruction* instruction, GroundArg arg);
void (*execute) (GroundInstruction* instruction, GroundState* state);
int64_t (*execute) (GroundInstruction* instruction, GroundValue* heap);
} Instruction;
struct {

View File

@@ -1,6 +1,7 @@
#include "../../include/ground.h"
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
/*
* Return values guide:
@@ -123,9 +124,19 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
printf("\n");
return -1;
}
SET: {}
GETTYPE: {}
EXISTS: {}
SET: {
size_t offset = instruction->args.at[0]._offset;
heap[offset] = instruction->args.at[1].as.value;
return -1;
}
GETTYPE: {
Ground.Log.Warning("GETTYPE is deprecated");
return -1;
}
EXISTS: {
Ground.Log.Warning("EXISTS is deprecated");
return -1;
}
SETLIST: {}
SETLISTAT: {}
GETLISTAT: {}
@@ -133,13 +144,374 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
LISTAPPEND: {}
GETSTRSIZE: {}
GETSTRCHARAT: {}
ADD: {}
SUBTRACT: {}
MULTIPLY: {}
DIVIDE: {}
EQUAL: {}
INEQUAL: {}
NOT: {}
ADD: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int + right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int + right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid add operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double + right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double + right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid add operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
case GroundType_String: {
switch (right->type.type) {
case GroundType_String: {
char* buf = malloc(sizeof(char) * (left->as.String.len + right->as.String.len + 1));
if (buf == NULL) {
Ground.Log.Error("malloc failed (instruction ADD{string, string, dirref}) in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
sprintf(buf, "%s%s", left->as.String.cstr, right->as.String.cstr);
*final = Ground.New.Value.String(Ground.New.String(buf));
break;
}
default: {
Ground.Log.Error("invalid add operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
}
default: {
Ground.Log.Error("invalid add operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
return -1;
}
SUBTRACT: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int - right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int - right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double - right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double - right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
return -1;
}
MULTIPLY: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int * right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int * right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double * right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double * right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
return -1;
}
DIVIDE: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
switch (left->type.type) {
case GroundType_Int: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int / right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int / right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
case GroundType_Double: {
switch (right->type.type) {
case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double / right->as.Int);
break;
}
case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double / right->as.Double);
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
break;
}
default: {
Ground.Log.Error("invalid subtract operation in Ground.Instruction.execute()");
Ground.Flags.error = true;
break;
}
}
return -1;
}
EQUAL: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
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(false);
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(false);
break;
}
}
break;
}
case GroundType_Char: {
if (right->type.type == GroundType_Char) {
*final = Ground.New.Value.Bool(left->as.Char == right->as.Char);
} else {
*final = Ground.New.Value.Bool(false);
}
break;
}
case GroundType_Bool: {
if (right->type.type == GroundType_Bool) {
*final = Ground.New.Value.Bool(left->as.Bool == right->as.Bool);
} else {
*final = Ground.New.Value.Bool(false);
}
break;
}
case GroundType_String: {
if (right->type.type == GroundType_String) {
*final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr));
} else {
*final = Ground.New.Value.Bool(false);
}
break;
}
default: {
// FIXME implement for complex types
*final = Ground.New.Value.Bool(false);
break;
}
}
return -1;
}
INEQUAL: {
GroundValue* final = &heap[instruction->args.at[2]._offset];
GroundValue* left = &instruction->args.at[0].as.value;
GroundValue* right = &instruction->args.at[1].as.value;
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;
}
case GroundType_Char: {
if (right->type.type == GroundType_Char) {
*final = Ground.New.Value.Bool(left->as.Char != right->as.Char);
} else {
*final = Ground.New.Value.Bool(true);
}
break;
}
case GroundType_Bool: {
if (right->type.type == GroundType_Bool) {
*final = Ground.New.Value.Bool(left->as.Bool != right->as.Bool);
} else {
*final = Ground.New.Value.Bool(true);
}
break;
}
case GroundType_String: {
if (right->type.type == GroundType_String) {
*final = Ground.New.Value.Bool(!strcmp(left->as.String.cstr, right->as.String.cstr));
} else {
*final = Ground.New.Value.Bool(true);
}
break;
}
default: {
// FIXME implement for complex types
*final = Ground.New.Value.Bool(false);
break;
}
}
return -1;
}
NOT: {
heap[instruction->args.at[1]._offset] = Ground.New.Value.Bool(!instruction->args.at[0].as.value.as.Bool);
return -1;
}
GREATER: {}
LESSER: {}
AND: {}
@@ -172,4 +544,8 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
THROW: {}
CATCH: {}
Ground.Log.Error("operation fell through in Ground.Instruction.execute()");
Ground.Flags.error = true;
return -1;
}

View File

@@ -40,6 +40,8 @@ static inline void doLabels(GroundProgram* program, GroundState* state) {
return;
}
arg->_offset = *line;
} else if (instruction->type == GroundInstruction_IF) {
GroundArg* arg = &instruction->args.at[1];
size_t* line = Ground.State.findLabel(state, arg->as.ref);
@@ -51,6 +53,8 @@ static inline void doLabels(GroundProgram* program, GroundState* state) {
return;
}
arg->_offset = *line;
} else if (instruction->type == GroundInstruction_CATCH) {
GroundArg* arg = &instruction->args.at[1];
size_t* line = Ground.State.findLabel(state, arg->as.ref);
@@ -62,6 +66,8 @@ static inline void doLabels(GroundProgram* program, GroundState* state) {
return;
}
arg->_offset = *line;
}
}