Implement some more instructions
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
#include "../../../include/ground.h"
|
#include "../../../include/ground.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
|
||||||
@@ -479,18 +481,124 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
GREATER: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
LESSER: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
AND: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
OR: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
XOR: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
NEG: {
|
NEG: {
|
||||||
@@ -500,27 +608,99 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
STOI: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
STOD: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
ITOC: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
CTOI: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
TOSTRING: {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
FUN: {
|
FUN: {
|
||||||
|
// no-op
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
RETURN: {
|
RETURN: {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ENDFUN: {
|
ENDFUN: {
|
||||||
|
// no-op
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CALL: {
|
CALL: {
|
||||||
@@ -530,9 +710,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
STRUCT: {
|
STRUCT: {
|
||||||
|
// no-op
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ENDSTRUCT: {
|
ENDSTRUCT: {
|
||||||
|
// no-op
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
INIT: {
|
INIT: {
|
||||||
@@ -551,12 +733,16 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CREATELABEL: {
|
CREATELABEL: {
|
||||||
|
// no-op
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
PAUSE: {
|
PAUSE: {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
DROP: {
|
DROP: {
|
||||||
|
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]);
|
||||||
|
Ground.Free.Value(in);
|
||||||
|
*in = Ground.New.Value.Int(0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
LICENSE: {
|
LICENSE: {
|
||||||
|
|||||||
Reference in New Issue
Block a user