From f97cec45671fa16c94d1cbd0f2975df2af1966c4 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 20 Jun 2026 19:45:52 +1000 Subject: [PATCH] progress --- README.md | 4 +++ include/ground.h | 75 +++++++++++++++++++++++++++++---------- src/Copy/Function.c | 2 +- src/Copy/Instruction.c | 2 +- src/Copy/List.c | 2 +- src/Copy/Program.c | 2 +- src/Free/Function.c | 2 +- src/Free/Instruction.c | 2 +- src/Free/Program.c | 2 +- src/Instruction/execute.c | 10 +++--- src/Internal/run.c | 22 ++++++------ src/Log/printErrors.c | 4 +-- src/New/List.c | 2 +- src/New/NativeFunction.c | 4 +-- src/New/String.c | 2 +- src/State/findLabel.c | 2 +- src/libmain.c | 4 +-- 17 files changed, 92 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index f5207f7..cb27d2a 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,7 @@ meson install -C builddir ``` You may need to run `ldconfig` or reboot to update your ld cache. + +## Bytecode Format + +Under the hood, Ground uses a bytecode format to store things. diff --git a/include/ground.h b/include/ground.h index 7efeb91..eecab56 100644 --- a/include/ground.h +++ b/include/ground.h @@ -20,6 +20,10 @@ typedef struct GroundInstruction GroundInstruction; typedef struct GroundProgram GroundProgram; typedef struct GroundState GroundState; +typedef struct GroundBytecodeProgram GroundBytecodeProgram; +typedef struct GroundBytecodeInstruction GroundBytecodeInstruction; +typedef struct GroundBytecodeHeap GroundBytecodeHeap; + // --- Literal types --- typedef int64_t GroundInt; @@ -48,23 +52,25 @@ typedef struct GroundVariable GroundVariable; typedef struct GroundLabel GroundLabel; typedef struct GroundCatch GroundCatch; +typedef uint64_t GroundSize; + // --- Complex types definitions --- struct GroundString { char* cstr; - size_t len; + GroundSize len; }; struct GroundList { - size_t capacity; - size_t count; + GroundSize capacity; + GroundSize count; GroundValue* at; }; struct GroundFunction { struct { - size_t capacity; - size_t count; + GroundSize capacity; + GroundSize count; GroundFunctionArg* at; } args; @@ -77,7 +83,7 @@ struct GroundFunction { GroundState* closure; - size_t _requiredSize; + GroundSize _requiredSize; }; struct GroundStruct { @@ -149,7 +155,7 @@ struct GroundArg { GroundValue value; } as; - size_t _offset; + GroundSize _offset; }; enum GroundInstructionType { @@ -209,15 +215,15 @@ enum GroundInstructionType { struct GroundInstruction { enum GroundInstructionType type; struct { - size_t len; - size_t capacity; + GroundSize len; + GroundSize capacity; GroundArg* at; } args; }; struct GroundProgram { - size_t len; - size_t capacity; + GroundSize len; + GroundSize capacity; GroundInstruction* at; }; @@ -226,12 +232,12 @@ struct GroundVariable { GroundValue value; UT_hash_handle hh; - size_t _offset; + GroundSize _offset; }; struct GroundLabel { char name[2048]; - size_t lineNum; + GroundSize lineNum; UT_hash_handle hh; }; @@ -246,14 +252,36 @@ struct GroundState { GroundLabel* labels; GroundCatch* catches; - size_t _size; + GroundSize _size; }; struct GroundIdentifier { char* string; - size_t referenceCount; + GroundSize referenceCount; }; +struct GroundBytecodeProgram { + GroundBytecodeInstruction* at; + GroundSize capacity; + GroundSize len; +}; + +struct GroundBytecodeInstruction { + GroundInstruction instruction; + struct { + GroundSize* at; + GroundSize capacity; + GroundSize len; + } args; +}; + +struct GroundBytecodeHeap { + GroundValue* heap; + GroundSize capacity; + GroundSize count; +}; + + // // INTERFACE // @@ -299,7 +327,7 @@ struct _Ground { GroundObject (*Object) (GroundStruct* in); GroundError (*Error) (GroundValue* in); - GroundFunction (*NativeFunction) (void* function, size_t argc, ...); + GroundFunction (*NativeFunction) (void* function, GroundSize argc, ...); GroundInstruction (*Instruction) (enum GroundInstructionType type); GroundProgram (*Program) (); @@ -368,7 +396,7 @@ struct _Ground { struct { GroundValue* (*findVariable) (GroundState* state, const char* id); - size_t* (*findLabel) (GroundState* state, const char* id); + GroundSize* (*findLabel) (GroundState* state, const char* id); GroundCatch* (*findCatch) (GroundState* state, const char* id); } State; @@ -384,10 +412,19 @@ struct _Ground { void (*printErrors)(); char* errors[4096]; - size_t errorCount; + GroundSize errorCount; char* warnings[4096]; - size_t warningCount; + GroundSize warningCount; } Log; + + struct { + struct { + void (*execute) (GroundBytecodeProgram* program, GroundBytecodeHeap* heap); + void (*optimise) (GroundBytecodeProgram* program); + } Program; + struct {} Instruction; + struct {} Heap; + } Bytecode; }; extern struct _Ground Ground; diff --git a/src/Copy/Function.c b/src/Copy/Function.c index 9adfbe5..8401a8b 100644 --- a/src/Copy/Function.c +++ b/src/Copy/Function.c @@ -31,7 +31,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) { Ground.Flags.error = true; return newFunction; } - for (size_t i = 0; i < in->args.count; i++) { + for (GroundSize i = 0; i < in->args.count; i++) { if (newFunction.args.at == NULL) { Ground.Log.Error("malloc failed in Ground.Copy.Function()"); Ground.Flags.error = true; diff --git a/src/Copy/Instruction.c b/src/Copy/Instruction.c index 73b3d65..e08d6bd 100644 --- a/src/Copy/Instruction.c +++ b/src/Copy/Instruction.c @@ -12,7 +12,7 @@ GroundInstruction _GroundCopyInstruction(GroundInstruction* in) { return instruction; } - for (size_t i = 0; i < in->args.len; i++) { + for (GroundSize i = 0; i < in->args.len; i++) { instruction.args.at[i] = Ground.Copy.Arg(&in->args.at[i]); } diff --git a/src/Copy/List.c b/src/Copy/List.c index f1234ad..98e38c2 100644 --- a/src/Copy/List.c +++ b/src/Copy/List.c @@ -9,7 +9,7 @@ GroundList _GroundCopyList(GroundList* in) { return list; } - for (size_t i = 0; i < in->count; i++) { + for (GroundSize i = 0; i < in->count; i++) { list.at[i] = Ground.Copy.Value(&in->at[i]); } diff --git a/src/Copy/Program.c b/src/Copy/Program.c index b7220bd..a64a388 100644 --- a/src/Copy/Program.c +++ b/src/Copy/Program.c @@ -9,7 +9,7 @@ GroundProgram _GroundCopyProgram(GroundProgram* in) { return program; } - for (size_t i = 0; i < in->len; i++) { + for (GroundSize i = 0; i < in->len; i++) { program.at[i] = Ground.Copy.Instruction(&in->at[i]); } diff --git a/src/Free/Function.c b/src/Free/Function.c index 38c0d02..c9c9962 100644 --- a/src/Free/Function.c +++ b/src/Free/Function.c @@ -5,7 +5,7 @@ void _GroundFreeFunction(GroundFunction* in) { Ground.Free.Program(in->program.ground); free(in->program.ground); - for (size_t i = 0; i < in->args.count; i++) { + for (GroundSize i = 0; i < in->args.count; i++) { free(in->args.at[i].as.id); } } diff --git a/src/Free/Instruction.c b/src/Free/Instruction.c index 10670e6..56b1c6c 100644 --- a/src/Free/Instruction.c +++ b/src/Free/Instruction.c @@ -1,7 +1,7 @@ #include "../../include/ground.h" void _GroundFreeInstruction(GroundInstruction* in) { - for (size_t i = 0; i < in->args.len; i++) { + for (GroundSize i = 0; i < in->args.len; i++) { Ground.Free.Arg(&in->args.at[i]); } free(in->args.at); diff --git a/src/Free/Program.c b/src/Free/Program.c index d0a0167..df8a550 100644 --- a/src/Free/Program.c +++ b/src/Free/Program.c @@ -1,7 +1,7 @@ #include "../../include/ground.h" void _GroundFreeProgram(GroundProgram* in) { - for (size_t i = 0; i < in->len; i++) { + for (GroundSize i = 0; i < in->len; i++) { Ground.Free.Instruction(&in->at[i]); } free(in->at); diff --git a/src/Instruction/execute.c b/src/Instruction/execute.c index 76fe8c5..d4a9e40 100644 --- a/src/Instruction/execute.c +++ b/src/Instruction/execute.c @@ -29,9 +29,9 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h }; // Preprocess any ValueRefs - for (size_t i = 0; i < instruction->args.len; i++) { + for (GroundSize i = 0; i < instruction->args.len; i++) { if (instruction->args.at[i].type == GroundArg_ValueRef) { - size_t offset = instruction->args.at[i]._offset; + GroundSize offset = instruction->args.at[i]._offset; instruction->args.at[i] = Ground.New.Arg.Value(heap[offset]); } } @@ -62,7 +62,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h return -1; } PRINT: { - for (size_t i = 0; i < instruction->args.len; i++) { + for (GroundSize i = 0; i < instruction->args.len; i++) { GroundValue* val = &instruction->args.at[i].as.value; switch (val->type.type) { case GroundType_Int: @@ -93,7 +93,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h return -1; } PRINTLN: { - for (size_t i = 0; i < instruction->args.len; i++) { + for (GroundSize i = 0; i < instruction->args.len; i++) { GroundValue* val = &instruction->args.at[i].as.value; switch (val->type.type) { case GroundType_Int: @@ -125,7 +125,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h return -1; } SET: { - size_t offset = instruction->args.at[0]._offset; + GroundSize offset = instruction->args.at[0]._offset; heap[offset] = instruction->args.at[1].as.value; return -1; } diff --git a/src/Internal/run.c b/src/Internal/run.c index 3f3eda8..50ccb0c 100644 --- a/src/Internal/run.c +++ b/src/Internal/run.c @@ -6,7 +6,7 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { - for (size_t i = 0; i < program->len; i++) { + for (GroundSize i = 0; i < program->len; i++) { GroundInstruction* instruction = &program->at[i]; if (instruction->type == GroundInstruction_CREATELABEL) { if (instruction->args.len > 0) { @@ -30,11 +30,11 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { } } - for (size_t i = 0; i < program->len; i++) { + for (GroundSize i = 0; i < program->len; i++) { GroundInstruction* instruction = &program->at[i]; if (instruction->type == GroundInstruction_JUMP) { GroundArg* arg = &instruction->args.at[0]; - size_t* line = Ground.State.findLabel(state, arg->as.ref->string); + GroundSize* line = Ground.State.findLabel(state, arg->as.ref->string); if (line == NULL) { char buf[2048]; snprintf(buf, 2047, "couldn't find label '%s' (instruction JUMP at %zu) in Ground.Internal.Run()", arg->as.ref->string, i); @@ -47,7 +47,7 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { } else if (instruction->type == GroundInstruction_IF) { GroundArg* arg = &instruction->args.at[1]; - size_t* line = Ground.State.findLabel(state, arg->as.ref->string); + GroundSize* line = Ground.State.findLabel(state, arg->as.ref->string); if (line == NULL) { char buf[2048]; snprintf(buf, 2047, "couldn't find label '%s' (instruction IF at %zu) in Ground.Internal.Run()", arg->as.ref->string, i); @@ -60,7 +60,7 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { } else if (instruction->type == GroundInstruction_CATCH) { GroundArg* arg = &instruction->args.at[1]; - size_t* line = Ground.State.findLabel(state, arg->as.ref->string); + GroundSize* line = Ground.State.findLabel(state, arg->as.ref->string); if (line == NULL) { char buf[2048]; snprintf(buf, 2047, "couldn't find label '%s' (instruction CATCH at %zu) in Ground.Internal.Run()", arg->as.ref->string, i); @@ -79,10 +79,10 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { /* * Assigns an offset to each variable referenced. */ -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++) { +static inline GroundSize doOffsets(GroundProgram* program, GroundState* state) { + GroundSize size = 0; + for (GroundSize i = 0; i < program->len; i++) { + for (GroundSize j = 0; j < program->at[i].args.len; j++) { GroundArg* arg = &program->at[i].args.at[j]; if ( @@ -120,12 +120,12 @@ void _GroundInternalRun(GroundProgram* program, GroundState* state) { doLabels(program, state); if (Ground.Flags.error) return; - size_t size = doOffsets(program, state); + GroundSize size = doOffsets(program, state); if (Ground.Flags.error) return; GroundValue* heap = malloc(sizeof(GroundValue) * size); - for (size_t i = 0; i < program->len; i++) { + for (GroundSize i = 0; i < program->len; i++) { GroundInstruction instruction = Ground.Copy.Instruction(&program->at[i]); int64_t status = Ground.Instruction.execute(&instruction, heap); switch (status) { diff --git a/src/Log/printErrors.c b/src/Log/printErrors.c index 432746d..bb9ca60 100644 --- a/src/Log/printErrors.c +++ b/src/Log/printErrors.c @@ -3,13 +3,13 @@ void _GroundLogPrintErrors() { if (Ground.Log.errorCount != 0) { printf("%zu errors:\n", Ground.Log.errorCount); - for (size_t i = 0; i < Ground.Log.errorCount; i++) { + for (GroundSize i = 0; i < Ground.Log.errorCount; i++) { printf(" \e[0;31m%zu: %s\n\e[0m", Ground.Log.errorCount, Ground.Log.errors[i]); } } if (Ground.Log.warningCount != 0) { printf("%zu warnings:\n", Ground.Log.warningCount); - for (size_t i = 0; i < Ground.Log.warningCount; i++) { + for (GroundSize i = 0; i < Ground.Log.warningCount; i++) { printf(" \e[0;33m%zu: %s\n\e[0m", Ground.Log.warningCount, Ground.Log.warnings[i]); } } diff --git a/src/New/List.c b/src/New/List.c index 8981430..c984f70 100644 --- a/src/New/List.c +++ b/src/New/List.c @@ -1,6 +1,6 @@ #include "../../include/ground.h" -GroundList _GroundNewList(size_t len, GroundValue* contents) { +GroundList _GroundNewList(GroundSize len, GroundValue* contents) { GroundList list = { .capacity = 16, .count = 0, diff --git a/src/New/NativeFunction.c b/src/New/NativeFunction.c index a26b810..0a4ec2b 100644 --- a/src/New/NativeFunction.c +++ b/src/New/NativeFunction.c @@ -2,7 +2,7 @@ #include #include -GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { +GroundFunction _GroundNewNativeFunction(void* function, GroundSize argc, ...) { GroundState state = {NULL, NULL, NULL}; GroundFunction gf = Ground.New.Function(&state); @@ -13,7 +13,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { va_list args; va_start(args, argc); - for (size_t i = 0; i < argc; i++) { + for (GroundSize i = 0; i < argc; i++) { GroundType type = va_arg(args, GroundType); if (type.type == GroundType_Struct) { Ground.Log.Error("Cannot pass struct to native function in Ground.New.NativeFunction()"); diff --git a/src/New/String.c b/src/New/String.c index 48a617c..12dc5a1 100644 --- a/src/New/String.c +++ b/src/New/String.c @@ -2,7 +2,7 @@ GroundString _GroundNewString(const char* in) { - size_t len = strlen(in); + GroundSize len = strlen(in); GroundString string = { .len = len, diff --git a/src/State/findLabel.c b/src/State/findLabel.c index 68987e4..5ff79e6 100644 --- a/src/State/findLabel.c +++ b/src/State/findLabel.c @@ -1,6 +1,6 @@ #include "../../include/ground.h" -size_t* _GroundStateFindLabel(GroundState* state, char* id) { +GroundSize* _GroundStateFindLabel(GroundState* state, char* id) { GroundLabel* item = NULL; HASH_FIND_STR(state->labels, id, item); diff --git a/src/libmain.c b/src/libmain.c index daa91ce..5a8c0b5 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -21,7 +21,7 @@ GroundArg _GroundNewArgTypeRef(GroundIdentifier* ref); GroundList _GroundNewList(); GroundString _GroundNewString(const char* in); GroundFunction _GroundNewFunction(GroundState* state); -GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...); +GroundFunction _GroundNewNativeFunction(void* function, GroundSize argc, ...); GroundStruct _GroundNewStruct(); GroundObject _GroundNewObject(GroundStruct* in); GroundError _GroundNewError(GroundValue* in); @@ -81,7 +81,7 @@ void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value); GroundValue* _GroundStateFindVariable(GroundState* state, const char* id); -size_t* _GroundStateFindLabel(GroundState* state, const char* id); +GroundSize* _GroundStateFindLabel(GroundState* state, const char* id); GroundCatch* _GroundStateFindCatch(GroundState* state, const char* id);