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 { struct {
void (*append) (GroundInstruction* instruction, GroundArg arg); void (*append) (GroundInstruction* instruction, GroundArg arg);
void (*execute) (GroundInstruction* instruction, GroundState* state); int64_t (*execute) (GroundInstruction* instruction, GroundValue* heap);
} Instruction; } Instruction;
struct { struct {

View File

@@ -1,6 +1,7 @@
#include "../../include/ground.h" #include "../../include/ground.h"
#include <stdio.h> #include <stdio.h>
#include <inttypes.h> #include <inttypes.h>
#include <string.h>
/* /*
* Return values guide: * Return values guide:
@@ -123,9 +124,19 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
printf("\n"); printf("\n");
return -1; return -1;
} }
SET: {} SET: {
GETTYPE: {} size_t offset = instruction->args.at[0]._offset;
EXISTS: {} 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: {} SETLIST: {}
SETLISTAT: {} SETLISTAT: {}
GETLISTAT: {} GETLISTAT: {}
@@ -133,13 +144,374 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
LISTAPPEND: {} LISTAPPEND: {}
GETSTRSIZE: {} GETSTRSIZE: {}
GETSTRCHARAT: {} GETSTRCHARAT: {}
ADD: {} ADD: {
SUBTRACT: {} GroundValue* final = &heap[instruction->args.at[2]._offset];
MULTIPLY: {} GroundValue* left = &instruction->args.at[0].as.value;
DIVIDE: {} GroundValue* right = &instruction->args.at[1].as.value;
EQUAL: {}
INEQUAL: {} switch (left->type.type) {
NOT: {} 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: {} GREATER: {}
LESSER: {} LESSER: {}
AND: {} AND: {}
@@ -172,4 +544,8 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
THROW: {} THROW: {}
CATCH: {} 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; return;
} }
arg->_offset = *line;
} else if (instruction->type == GroundInstruction_IF) { } else if (instruction->type == GroundInstruction_IF) {
GroundArg* arg = &instruction->args.at[1]; GroundArg* arg = &instruction->args.at[1];
size_t* line = Ground.State.findLabel(state, arg->as.ref); size_t* line = Ground.State.findLabel(state, arg->as.ref);
@@ -51,6 +53,8 @@ static inline void doLabels(GroundProgram* program, GroundState* state) {
return; return;
} }
arg->_offset = *line;
} else if (instruction->type == GroundInstruction_CATCH) { } else if (instruction->type == GroundInstruction_CATCH) {
GroundArg* arg = &instruction->args.at[1]; GroundArg* arg = &instruction->args.at[1];
size_t* line = Ground.State.findLabel(state, arg->as.ref); size_t* line = Ground.State.findLabel(state, arg->as.ref);
@@ -62,6 +66,8 @@ static inline void doLabels(GroundProgram* program, GroundState* state) {
return; return;
} }
arg->_offset = *line;
} }
} }