2026-06-13 19:45:36 +10:00
|
|
|
#include "../../include/ground.h"
|
2026-06-15 21:33:58 +10:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <inttypes.h>
|
2026-06-13 19:45:36 +10:00
|
|
|
|
2026-06-15 21:33:58 +10:00
|
|
|
/*
|
|
|
|
|
* Return values guide:
|
|
|
|
|
* -2: Exit program
|
|
|
|
|
* -1: Nothing
|
|
|
|
|
* 0-infinity: Jump to instruction number
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* heap) {
|
|
|
|
|
|
|
|
|
|
static const void* jumpTable[] = {
|
|
|
|
|
&&IF, &&JUMP, &&END,
|
|
|
|
|
&&INPUT, &&PRINT, &&PRINTLN,
|
|
|
|
|
&&SET, &&GETTYPE, &&EXISTS,
|
|
|
|
|
&&SETLIST, &&SETLISTAT, &&GETLISTAT, &&GETLISTSIZE, &&LISTAPPEND,
|
|
|
|
|
&&GETSTRSIZE, &&GETSTRCHARAT,
|
|
|
|
|
&&ADD, &&SUBTRACT, &&MULTIPLY, &&DIVIDE,
|
|
|
|
|
&&EQUAL, &&INEQUAL, &&NOT, &&GREATER, &&LESSER,
|
|
|
|
|
&&AND, &&OR, &&XOR, &&NEG, &&SHIFT,
|
|
|
|
|
&&STOI, &&STOD, &&ITOC, &&CTOI, &&TOSTRING,
|
|
|
|
|
&&FUN, &&RETURN, &&ENDFUN, &&CALL, &&CALLMETHOD,
|
|
|
|
|
&&STRUCT, &&ENDSTRUCT, &&INIT, &&GETFIELD, &&SETFIELD,
|
|
|
|
|
&&USE, &&EXTERN, &&CREATELABEL,
|
|
|
|
|
&&PAUSE, &&DROP, &&LICENSE, &&ERRORCMD, &&THROW, &&CATCH
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Preprocess any ValueRefs
|
|
|
|
|
for (size_t i = 0; i < instruction->args.len; i++) {
|
|
|
|
|
if (instruction->args.at[i].type == GroundArg_ValueRef) {
|
|
|
|
|
size_t offset = instruction->args.at[i]._offset;
|
|
|
|
|
instruction->args.at[i] = Ground.New.Arg.Value(heap[offset]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Jump to the spot
|
|
|
|
|
goto *jumpTable[instruction->type];
|
|
|
|
|
|
|
|
|
|
IF: {
|
|
|
|
|
if (instruction->args.at[0].as.value.as.Bool) {
|
|
|
|
|
return instruction->args.at[1]._offset;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
2026-06-15 20:27:50 +10:00
|
|
|
}
|
2026-06-15 21:33:58 +10:00
|
|
|
JUMP: {
|
|
|
|
|
return instruction->args.at[0]._offset;
|
|
|
|
|
}
|
|
|
|
|
END: {
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
INPUT: {
|
|
|
|
|
char input[2048];
|
|
|
|
|
fgets(input, sizeof(input) - 1, stdin);
|
|
|
|
|
input[2047] = '\0';
|
|
|
|
|
|
|
|
|
|
GroundString string = Ground.New.String(input);
|
|
|
|
|
GroundValue value = Ground.New.Value.String(string);
|
|
|
|
|
heap[instruction->args.at[0]._offset] = value;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
PRINT: {
|
|
|
|
|
for (size_t i = 0; i < instruction->args.len; i++) {
|
|
|
|
|
GroundValue* val = &instruction->args.at[i].as.value;
|
|
|
|
|
switch (val->type.type) {
|
|
|
|
|
case GroundType_Int:
|
|
|
|
|
printf("%" PRId64, val->as.Int);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Double:
|
|
|
|
|
printf("%f", val->as.Double);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Bool:
|
|
|
|
|
printf(val->as.Bool ? "true" : "false");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Char:
|
|
|
|
|
printf("%c", val->as.Char);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_String:
|
|
|
|
|
printf("%s", val->as.String.cstr);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
printf("<fixme>");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
PRINTLN: {
|
|
|
|
|
for (size_t i = 0; i < instruction->args.len; i++) {
|
|
|
|
|
GroundValue* val = &instruction->args.at[i].as.value;
|
|
|
|
|
switch (val->type.type) {
|
|
|
|
|
case GroundType_Int:
|
|
|
|
|
printf("%" PRId64, val->as.Int);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Double:
|
|
|
|
|
printf("%f", val->as.Double);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Bool:
|
|
|
|
|
printf(val->as.Bool ? "true" : "false");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_Char:
|
|
|
|
|
printf("%c", val->as.Char);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_String:
|
|
|
|
|
printf("%s", val->as.String.cstr);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
printf("<fixme>");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
SET: {}
|
|
|
|
|
GETTYPE: {}
|
|
|
|
|
EXISTS: {}
|
|
|
|
|
SETLIST: {}
|
|
|
|
|
SETLISTAT: {}
|
|
|
|
|
GETLISTAT: {}
|
|
|
|
|
GETLISTSIZE: {}
|
|
|
|
|
LISTAPPEND: {}
|
|
|
|
|
GETSTRSIZE: {}
|
|
|
|
|
GETSTRCHARAT: {}
|
|
|
|
|
ADD: {}
|
|
|
|
|
SUBTRACT: {}
|
|
|
|
|
MULTIPLY: {}
|
|
|
|
|
DIVIDE: {}
|
|
|
|
|
EQUAL: {}
|
|
|
|
|
INEQUAL: {}
|
|
|
|
|
NOT: {}
|
|
|
|
|
GREATER: {}
|
|
|
|
|
LESSER: {}
|
|
|
|
|
AND: {}
|
|
|
|
|
OR: {}
|
|
|
|
|
XOR: {}
|
|
|
|
|
NEG: {}
|
|
|
|
|
SHIFT: {}
|
|
|
|
|
STOI: {}
|
|
|
|
|
STOD: {}
|
|
|
|
|
ITOC: {}
|
|
|
|
|
CTOI: {}
|
|
|
|
|
TOSTRING: {}
|
|
|
|
|
FUN: {}
|
|
|
|
|
RETURN: {}
|
|
|
|
|
ENDFUN: {}
|
|
|
|
|
CALL: {}
|
|
|
|
|
CALLMETHOD: {}
|
|
|
|
|
STRUCT: {}
|
|
|
|
|
ENDSTRUCT: {}
|
|
|
|
|
INIT: {}
|
|
|
|
|
GETFIELD: {}
|
|
|
|
|
SETFIELD: {}
|
|
|
|
|
USE: {}
|
|
|
|
|
EXTERN: {}
|
|
|
|
|
CREATELABEL: {}
|
|
|
|
|
PAUSE: {}
|
|
|
|
|
DROP: {}
|
|
|
|
|
LICENSE: {}
|
|
|
|
|
ERRORCMD: {}
|
|
|
|
|
THROW: {}
|
|
|
|
|
CATCH: {}
|
|
|
|
|
|
2026-06-13 19:45:36 +10:00
|
|
|
}
|