Files
ground-rewrite/src/Instruction/execute.c

176 lines
4.4 KiB
C
Raw Normal View History

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
}