From da75cf7590cf52b55e8078cdfcb761cb8104cbd1 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 15 Jun 2026 21:33:58 +1000 Subject: [PATCH] Start work on the interpreter --- src/Instruction/execute.c | 281 +++++++++++++++++++++++--------------- src/Internal/run.c | 27 +++- src/libmain.c | 2 +- 3 files changed, 196 insertions(+), 114 deletions(-) diff --git a/src/Instruction/execute.c b/src/Instruction/execute.c index 7fa34de..0ae68ac 100644 --- a/src/Instruction/execute.c +++ b/src/Instruction/execute.c @@ -1,116 +1,175 @@ #include "../../include/ground.h" +#include +#include -#define handle(instruction) handle##instruction##(instruction, state); break; +/* + * Return values guide: + * -2: Exit program + * -1: Nothing + * 0-infinity: Jump to instruction number + */ -void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state) { - switch (instruction->type) { - case GroundInstruction_IF: - break; - case GroundInstruction_JUMP: - break; - case GroundInstruction_END: - break; - case GroundInstruction_INPUT: - break; - case GroundInstruction_PRINT: - break; - case GroundInstruction_PRINTLN: - break; - case GroundInstruction_SET: - break; - case GroundInstruction_GETTYPE: - break; - case GroundInstruction_EXISTS: - break; - case GroundInstruction_SETLIST: - break; - case GroundInstruction_SETLISTAT: - break; - case GroundInstruction_GETLISTAT: - break; - case GroundInstruction_GETLISTSIZE: - break; - case GroundInstruction_LISTAPPEND: - break; - case GroundInstruction_GETSTRSIZE: - break; - case GroundInstruction_GETSTRCHARAT: - break; - case GroundInstruction_ADD: - break; - case GroundInstruction_SUBTRACT: - break; - case GroundInstruction_MULTIPLY: - break; - case GroundInstruction_DIVIDE: - break; - case GroundInstruction_EQUAL: - break; - case GroundInstruction_INEQUAL: - break; - case GroundInstruction_NOT: - break; - case GroundInstruction_GREATER: - break; - case GroundInstruction_LESSER: - break; - case GroundInstruction_AND: - break; - case GroundInstruction_OR: - break; - case GroundInstruction_XOR: - break; - case GroundInstruction_NEG: - break; - case GroundInstruction_SHIFT: - break; - case GroundInstruction_STOI: - break; - case GroundInstruction_STOD: - break; - case GroundInstruction_ITOC: - break; - case GroundInstruction_CTOI: - break; - case GroundInstruction_TOSTRING: - break; - case GroundInstruction_FUN: - break; - case GroundInstruction_RETURN: - break; - case GroundInstruction_ENDFUN: - break; - case GroundInstruction_CALL: - break; - case GroundInstruction_CALLMETHOD: - break; - case GroundInstruction_STRUCT: - break; - case GroundInstruction_ENDSTRUCT: - break; - case GroundInstruction_INIT: - break; - case GroundInstruction_GETFIELD: - break; - case GroundInstruction_SETFIELD: - break; - case GroundInstruction_USE: - break; - case GroundInstruction_EXTERN: - break; - case GroundInstruction_CREATELABEL: - break; - case GroundInstruction_PAUSE: - break; - case GroundInstruction_DROP: - break; - case GroundInstruction_LICENSE: - break; - case GroundInstruction_ERROR: - break; - case GroundInstruction_THROW: - break; - case GroundInstruction_CATCH: - break; +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: {} + } diff --git a/src/Internal/run.c b/src/Internal/run.c index ed29d9a..cf601e2 100644 --- a/src/Internal/run.c +++ b/src/Internal/run.c @@ -4,7 +4,7 @@ #include #include -void doLabels(GroundProgram* program, GroundState* state) { +static inline void doLabels(GroundProgram* program, GroundState* state) { for (size_t i = 0; i < program->len; i++) { for (size_t j = 0; j < program->len; j++) { @@ -70,7 +70,7 @@ void doLabels(GroundProgram* program, GroundState* state) { /* * Assigns an offset to each variable referenced. */ -size_t doOffsets(GroundProgram* program, GroundState* state) { +static inline size_t doOffsets(GroundProgram* program, GroundState* state) { size_t size = 0; for (size_t i = 0; i < program->len; i++) { for (size_t j = 0; j < program->at[i].args.len; j++) { @@ -113,5 +113,28 @@ void _GroundInternalRun(GroundProgram* program, GroundState* state) { size_t size = doOffsets(program, state); if (Ground.Flags.error) return; + + GroundValue* heap = malloc(sizeof(GroundValue) * size); + + for (size_t i = 0; i < program->len; i++) { + GroundInstruction instruction = Ground.Copy.Instruction(&program->at[i]); + int64_t status = Ground.Instruction.execute(&instruction, heap); + switch (status) { + case -2: + return; + case -1: + break; + default: + if (status < program->len) { + i = status; + } else { + Ground.Log.Error("out of bounds jump in Ground.Internal.Run()"); + Ground.Flags.error = true; + return; + } + } + // TODO: implement + // Ground.Free.Instruction(&instruction); + } } diff --git a/src/libmain.c b/src/libmain.c index 2a28ed0..bf40bf6 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -56,7 +56,7 @@ void _GroundListAppend(GroundList* list, GroundValue value); void _GroundInstructionAppend(GroundInstruction* instruction, GroundArg arg); -void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state); +int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* heap); void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction);