progress
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user