From 7c29048397e8791d96cfc51cbb5aaf7f4c69f392 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 4 Jul 2026 17:53:14 +1000 Subject: [PATCH] Begin work on reworked extern instruction --- README.md | 8 ++++ include/ground.h | 8 +++- src/Bytecode/Instruction/execute.c | 28 ++++++++++++++ src/New/Bytecode.c | 59 +++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb27d2a..0a9ef07 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,11 @@ 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. + +## Changes from old CGround + +### `extern` instruction + +`extern` no longer loads a dynamic library from /usr/lib/ground, it is now used to detail a system shared library to open. + +Format: `extern "libName" "symbolName" !functionName -returnType -argType...` diff --git a/include/ground.h b/include/ground.h index 53324e0..98d1092 100644 --- a/include/ground.h +++ b/include/ground.h @@ -126,7 +126,8 @@ struct GroundError { enum GroundTypeType { GroundType_Int, GroundType_Double, GroundType_Char, GroundType_Bool, GroundType_String, GroundType_List, - GroundType_Function, GroundType_Struct, GroundType_Object + GroundType_Function, GroundType_Struct, GroundType_Object, + GroundType_CoreType, }; struct GroundType { @@ -152,6 +153,8 @@ struct GroundValue { GroundFunction Function; GroundStruct Struct; GroundObject Object; + + enum GroundTypeType CoreType; } as; GroundType type; @@ -313,6 +316,9 @@ struct GroundBytecodeValue { GroundBytecodeFunction Function; GroundBytecodeStruct Struct; GroundBytecodeObject Object; + + // For core types + enum GroundTypeType CoreType; } as; GroundType type; diff --git a/src/Bytecode/Instruction/execute.c b/src/Bytecode/Instruction/execute.c index c64d09a..1166cd8 100644 --- a/src/Bytecode/Instruction/execute.c +++ b/src/Bytecode/Instruction/execute.c @@ -822,6 +822,34 @@ struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeIns return CONTINUE; } EXTERN: { + // extern "libfile.so" "symbolName" !fnName -returnType -argType... + void* handle = Ground.FFI.openSharedObject(HEAP_GET(heap, instruction->args.at[0])->as.String.cstr); + if (Ground.Flags.error) { + return CONTINUE; + } + void* function = Ground.FFI.getFunction(handle, HEAP_GET(heap, instruction->args.at[0])->as.String.cstr); + if (Ground.Flags.error) { + return CONTINUE; + } + GroundSize argsSize = instruction->args.len - 4; // subtract 4 for libfile, symbol name, fn name, return type + GroundBytecodeFunction bf = { + .isNativeFunction = true, + .closure = NULL, + .program.native = handle, + .args = { + .at = malloc(sizeof(GroundFunctionArg) * argsSize), + .capacity = argsSize, + .count = argsSize + }, + }; + if (bf.args.at == NULL) { + Ground.Log.Error("malloc failed in Ground.Bytecode.Instruction.execute"); + Ground.Flags.error = true; + return CONTINUE; + } + for (size_t i = 0; i < argsSize; i++) { + + } return CONTINUE; } CREATELABEL: { diff --git a/src/New/Bytecode.c b/src/New/Bytecode.c index c8733d2..470e9f3 100644 --- a/src/New/Bytecode.c +++ b/src/New/Bytecode.c @@ -78,10 +78,10 @@ static inline void doLabels(GroundProgram* program, GroundState* state) { static inline GroundSize doOffsets(GroundProgram* gp, GroundState* state, GroundBytecodeProgram* gbp) { GroundSize size = 0; - // Add size of state + // Add size of state and assign offsets to pre-existing variables GroundVariable *s, *tmp; HASH_ITER(hh, state->variables, s, tmp) { - size++; + s->_offset = size++; } for (GroundSize i = 0; i < gp->len; i++) { @@ -175,6 +175,61 @@ GroundBytecode _GroundNewBytecode(GroundProgram* program, GroundState* state) { return bytecode; } + // Add core types to state + for (unsigned int i = 0; i < (unsigned int)GroundType_Object; i++) { + GroundVariable* var = malloc(sizeof(GroundVariable)); + if (var == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Bytecode"); + Ground.Flags.error = true; + return bytecode; + } + var->value = (GroundValue) { + .type = {GroundType_CoreType}, + .as.CoreType = (enum GroundTypeType) i + }; + + switch ((enum GroundTypeType) i) { + case GroundType_Int: { + sprintf(var->name, "int"); + break; + } + case GroundType_Double: { + sprintf(var->name, "double"); + break; + } + case GroundType_Char: { + sprintf(var->name, "char"); + break; + } + case GroundType_Bool: { + sprintf(var->name, "bool"); + break; + } + case GroundType_String: { + sprintf(var->name, "string"); + break; + } + case GroundType_List: { + sprintf(var->name, "list"); + break; + } + case GroundType_Function: { + sprintf(var->name, "function"); + break; + } + case GroundType_Struct: { + sprintf(var->name, "struct"); + break; + } + default: break; // unreachable (in theory) + } + + HASH_ADD_STR(state->variables, name, var); + + } + + state->_size += (unsigned int)GroundType_Object + 1; + // Precompute some really cool stuff doLabels(program, state); if (Ground.Flags.error) return bytecode;