Implement some more instructions
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "../../../include/ground.h"
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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), "<FIXME>");
|
||||
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: {
|
||||
|
||||
Reference in New Issue
Block a user