#include "../../include/ground.h" #include #include /* * 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; } 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(""); 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(""); 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: {} }