From 284b08b12aff399f49dc4f259f14b8377003b0a8 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 13 Jun 2026 19:45:36 +1000 Subject: [PATCH] Initial commit --- .clangd | 2 + .gitignore | 1 + README.md | 8 + include/ground.h | 351 +++++++++++++++++++++++++++++++ meson.build | 73 +++++++ src/Copy/Arg.c | 10 + src/Copy/Function.c | 39 ++++ src/Copy/Instruction.c | 19 ++ src/Copy/List.c | 17 ++ src/Copy/Object.c | 35 +++ src/Copy/Program.c | 17 ++ src/Copy/State.c | 68 ++++++ src/Copy/String.c | 14 ++ src/Copy/Struct.c | 33 +++ src/Copy/Value.c | 33 +++ src/Free/Function.c | 19 ++ src/Free/List.c | 9 + src/Free/Object.c | 15 ++ src/Free/String.c | 8 + src/Free/Struct.c | 15 ++ src/Free/Value.c | 30 +++ src/Function/appendArg.c | 29 +++ src/Function/appendInstruction.c | 9 + src/Instruction/append.c | 17 ++ src/Instruction/execute.c | 5 + src/List/append.c | 17 ++ src/New/Arg/DirectRef.c | 24 +++ src/New/Arg/FunctionRef.c | 24 +++ src/New/Arg/LabelRef.c | 25 +++ src/New/Arg/LineRef.c | 24 +++ src/New/Arg/TypeRef.c | 25 +++ src/New/Arg/Value.c | 8 + src/New/Arg/ValueRef.c | 25 +++ src/New/Error.c | 15 ++ src/New/Function.c | 23 ++ src/New/Instruction.c | 17 ++ src/New/List.c | 15 ++ src/New/NativeFunction.c | 49 +++++ src/New/Object.c | 34 +++ src/New/Program.c | 14 ++ src/New/String.c | 20 ++ src/New/Struct.c | 7 + src/New/Type.c | 17 ++ src/New/Value/Bool.c | 8 + src/New/Value/Char.c | 8 + src/New/Value/Double.c | 8 + src/New/Value/Function.c | 8 + src/New/Value/Int.c | 8 + src/New/Value/List.c | 8 + src/New/Value/Object.c | 8 + src/New/Value/String.c | 9 + src/New/Value/Struct.c | 9 + src/Program/append.c | 17 ++ src/Program/execute.c | 5 + src/Struct/addField.c | 31 +++ src/libmain.c | 160 ++++++++++++++ 56 files changed, 1546 insertions(+) create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 README.md create mode 100644 include/ground.h create mode 100644 meson.build create mode 100644 src/Copy/Arg.c create mode 100644 src/Copy/Function.c create mode 100644 src/Copy/Instruction.c create mode 100644 src/Copy/List.c create mode 100644 src/Copy/Object.c create mode 100644 src/Copy/Program.c create mode 100644 src/Copy/State.c create mode 100644 src/Copy/String.c create mode 100644 src/Copy/Struct.c create mode 100644 src/Copy/Value.c create mode 100644 src/Free/Function.c create mode 100644 src/Free/List.c create mode 100644 src/Free/Object.c create mode 100644 src/Free/String.c create mode 100644 src/Free/Struct.c create mode 100644 src/Free/Value.c create mode 100644 src/Function/appendArg.c create mode 100644 src/Function/appendInstruction.c create mode 100644 src/Instruction/append.c create mode 100644 src/Instruction/execute.c create mode 100644 src/List/append.c create mode 100644 src/New/Arg/DirectRef.c create mode 100644 src/New/Arg/FunctionRef.c create mode 100644 src/New/Arg/LabelRef.c create mode 100644 src/New/Arg/LineRef.c create mode 100644 src/New/Arg/TypeRef.c create mode 100644 src/New/Arg/Value.c create mode 100644 src/New/Arg/ValueRef.c create mode 100644 src/New/Error.c create mode 100644 src/New/Function.c create mode 100644 src/New/Instruction.c create mode 100644 src/New/List.c create mode 100644 src/New/NativeFunction.c create mode 100644 src/New/Object.c create mode 100644 src/New/Program.c create mode 100644 src/New/String.c create mode 100644 src/New/Struct.c create mode 100644 src/New/Type.c create mode 100644 src/New/Value/Bool.c create mode 100644 src/New/Value/Char.c create mode 100644 src/New/Value/Double.c create mode 100644 src/New/Value/Function.c create mode 100644 src/New/Value/Int.c create mode 100644 src/New/Value/List.c create mode 100644 src/New/Value/Object.c create mode 100644 src/New/Value/String.c create mode 100644 src/New/Value/Struct.c create mode 100644 src/Program/append.c create mode 100644 src/Program/execute.c create mode 100644 src/Struct/addField.c create mode 100644 src/libmain.c diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..91e78fc --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [-Iinclude] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a57078d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +builddir diff --git a/README.md b/README.md new file mode 100644 index 0000000..2197142 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Building + +Install dependencies (uthash, libffi) then: + +```sh +meson setup builddir +meson compile -C builddir +``` diff --git a/include/ground.h b/include/ground.h new file mode 100644 index 0000000..653280b --- /dev/null +++ b/include/ground.h @@ -0,0 +1,351 @@ +#ifndef GROUND_H +#define GROUND_H + +#include +#include +#include +#include +#include + +// +// TYPES +// + +// --- Program structure types --- + +typedef struct GroundType GroundType; +typedef struct GroundValue GroundValue; +typedef struct GroundArg GroundArg; +typedef struct GroundInstruction GroundInstruction; +typedef struct GroundProgram GroundProgram; +typedef struct GroundState GroundState; + +// --- Literal types --- + +typedef int64_t GroundInt; +typedef double GroundDouble; +typedef char GroundChar; +typedef bool GroundBool; + +// --- Complex types --- + +typedef struct GroundList GroundList; +typedef struct GroundString GroundString; +typedef struct GroundFunction GroundFunction; +typedef struct GroundStruct GroundStruct; +typedef struct GroundObject GroundObject; +typedef struct GroundError GroundError; + +// --- Helper types --- + +typedef struct GroundFunctionArg GroundFunctionArg; + +typedef struct GroundObjectField GroundObjectField; + +typedef struct GroundVariable GroundVariable; +typedef struct GroundLabel GroundLabel; +typedef struct GroundCatch GroundCatch; + +// --- Complex types definitions --- + +struct GroundString { + char* cstr; + size_t len; +}; + +struct GroundList { + size_t capacity; + size_t count; + GroundValue* at; +}; + +struct GroundFunction { + struct { + size_t capacity; + size_t count; + GroundFunctionArg* at; + } args; + + bool isNativeFunction; + + union { + void* native; + GroundProgram* ground; + } program; + + GroundState* closure; +}; + +struct GroundStruct { + GroundObjectField* fields; +}; + +struct GroundObjectField { + char name[2048]; + GroundValue* value; + UT_hash_handle hh; +}; + +struct GroundObject { + GroundObjectField* fields; + GroundStruct* type; +}; + +struct GroundError { + GroundValue* value; + +}; + +// --- Program structure types definitions --- + +enum GroundTypeType { + GroundType_Int, GroundType_Double, GroundType_Char, GroundType_Bool, + GroundType_String, GroundType_List, + GroundType_Function, GroundType_Struct, GroundType_Object +}; + +struct GroundType { + enum GroundTypeType type; + GroundStruct complexType; +}; + +struct GroundFunctionArg { + union { + char* id; + GroundType type; + } as; +}; + +struct GroundValue { + union { + GroundInt Int; + GroundDouble Double; + GroundChar Char; + GroundBool Bool; + GroundString String; + GroundList List; + GroundFunction Function; + GroundStruct Struct; + GroundObject Object; + } as; + + GroundType type; +}; + +enum GroundArgType { + GroundArg_Value, GroundArg_ValueRef, GroundArg_DirectRef, + GroundArg_LineRef, GroundArg_Label, + GroundArg_FunctionRef, GroundArg_TypeRef +}; + +struct GroundArg { + enum GroundArgType type; + union { + const char* ref; + GroundValue value; + } as; +}; + +enum GroundInstructionType { + // Control flow + GroundInstruction_IF, GroundInstruction_JUMP, GroundInstruction_END, + + // I/O + GroundInstruction_INPUT, GroundInstruction_PRINT, GroundInstruction_PRINTLN, + + // Variable manipulation + GroundInstruction_SET, GroundInstruction_GETTYPE, GroundInstruction_EXISTS, + + // List manipulation + GroundInstruction_SETLIST, GroundInstruction_SETLISTAT, GroundInstruction_GETLISTAT, + GroundInstruction_GETLISTSIZE, GroundInstruction_LISTAPPEND, + + // String manipulation + GroundInstruction_GETSTRSIZE, GroundInstruction_GETSTRCHARAT, + + // Math + GroundInstruction_ADD, GroundInstruction_SUBTRACT, GroundInstruction_MULTIPLY, GroundInstruction_DIVIDE, + + // Comparison + GroundInstruction_EQUAL, GroundInstruction_INEQUAL, GroundInstruction_NOT, + GroundInstruction_GREATER, GroundInstruction_LESSER, + + // Bitwise operations + GroundInstruction_AND, GroundInstruction_OR, GroundInstruction_XOR, + GroundInstruction_NEG, GroundInstruction_SHIFT, + + // Conversions + GroundInstruction_STOI, GroundInstruction_STOD, GroundInstruction_ITOC, GroundInstruction_CTOI, GroundInstruction_TOSTRING, + + // Functions + GroundInstruction_FUN, GroundInstruction_RETURN, GroundInstruction_ENDFUN, + + // Calling functions + GroundInstruction_CALL, GroundInstruction_CALLMETHOD, + + // Structs + GroundInstruction_STRUCT, GroundInstruction_ENDSTRUCT, GroundInstruction_INIT, + GroundInstruction_GETFIELD, GroundInstruction_SETFIELD, + + // Libraries + GroundInstruction_USE, GroundInstruction_EXTERN, + + // Create labels + GroundInstruction_CREATELABEL, + + // Utility + GroundInstruction_PAUSE, GroundInstruction_DROP, GroundInstruction_LICENSE, + + // Error + GroundInstruction_ERROR, GroundInstruction_THROW, GroundInstruction_CATCH +}; + +struct GroundInstruction { + enum GroundInstructionType type; + struct { + size_t len; + size_t capacity; + GroundArg* at; + } args; +}; + +struct GroundProgram { + size_t len; + size_t capacity; + GroundInstruction* at; +}; + +struct GroundVariable { + char name[2048]; + GroundValue value; + UT_hash_handle hh; +}; + +struct GroundLabel { + char name[2048]; + size_t lineNum; + UT_hash_handle hh; +}; + +struct GroundCatch { + char name[2048]; + GroundType type; + UT_hash_handle hh; +}; + +struct GroundState { + GroundVariable* variables; + GroundLabel* labels; + GroundCatch* catches; +}; + +// +// INTERFACE +// + +struct _Ground { + + struct { + bool error; + } Flags; + + struct { + + // Creates a new value of the specified type. + // Returns a GroundValue + struct { + GroundValue (*Int) (GroundInt in); + GroundValue (*Double) (GroundDouble in); + GroundValue (*Char) (GroundChar in); + GroundValue (*Bool) (GroundBool in); + + GroundValue (*List) (GroundList in); + GroundValue (*String) (GroundString in); + GroundValue (*Function) (GroundFunction in); + GroundValue (*Struct) (GroundStruct in); + GroundValue (*Object) (GroundObject in); + } Value; + + struct { + GroundArg (*Value) (GroundValue value); + + GroundArg (*ValueRef) (const char* ref); + GroundArg (*DirectRef) (const char* ref); + GroundArg (*LineRef) (const char* ref); + GroundArg (*LabelRef) (const char* ref); + GroundArg (*FunctionRef) (const char* ref); + GroundArg (*TypeRef) (const char* ref); + } Arg; + + GroundList (*List) (); + GroundString (*String) (const char* in); + GroundFunction (*Function) (GroundState* state); + GroundStruct (*Struct) (); + GroundObject (*Object) (GroundStruct* in); + GroundError (*Error) (GroundValue* in); + + GroundFunction (*NativeFunction) (void* function, size_t argc, ...); + + GroundInstruction (*Instruction) (enum GroundInstructionType type); + GroundProgram (*Program) (); + GroundType (*Type) (enum GroundTypeType type, ...); + + } New; + + // Frees the memory held by the specified struct + struct { + void (*Value) (GroundValue* in); + void (*List) (GroundList* in); + void (*String) (GroundString* in); + void (*Function) (GroundFunction* in); + void (*Struct) (GroundStruct* in); + void (*Object) (GroundObject* in); + + void (*Arg) (GroundArg* in); + void (*Instruction) (GroundInstruction* in); + void (*Program) (GroundProgram* in); + void (*State) (GroundState* state); + } Free; + + // Creates a copy of the memory held by the specified struct + struct { + GroundValue (*Value) (GroundValue* in); + GroundList (*List) (GroundList* in); + GroundString (*String) (GroundString* in); + GroundFunction (*Function) (GroundFunction* in); + GroundStruct (*Struct) (GroundStruct* in); + GroundObject (*Object) (GroundObject* in); + + GroundArg (*Arg) (GroundArg* in); + GroundInstruction (*Instruction) (GroundInstruction* in); + GroundProgram (*Program) (GroundProgram* in); + GroundState (*State) (GroundState* in); + } Copy; + + struct { + void (*append) (GroundList* list, GroundValue value); + } List; + + struct { + void (*append) (GroundInstruction* instruction, GroundArg arg); + void (*execute) (GroundInstruction* instruction, GroundState* state); + } Instruction; + + struct { + void (*append) (GroundProgram* program, GroundInstruction instruction); + void (*execute) (GroundProgram* program, GroundState* state); + } Program; + + struct { + void (*appendInstruction) (GroundFunction* function, GroundInstruction instruction); + void (*appendArg) (GroundFunction* function, const char* argName); + } Function; + + struct { + void (*addField) (GroundStruct* gs, const char* id, GroundValue value); + } Struct; +}; + +extern struct _Ground Ground; + +#endif diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..be010fc --- /dev/null +++ b/meson.build @@ -0,0 +1,73 @@ +project('ground', 'c', version : '0.1.0') + +sources = files( + 'src/Copy/Arg.c', + 'src/Copy/Function.c', + 'src/Copy/Instruction.c', + 'src/Copy/List.c', + 'src/Copy/Object.c', + 'src/Copy/Program.c', + 'src/Copy/State.c', + 'src/Copy/String.c', + 'src/Copy/Struct.c', + 'src/Copy/Value.c', + + 'src/Free/Function.c', + 'src/Free/List.c', + 'src/Free/Object.c', + 'src/Free/String.c', + 'src/Free/Struct.c', + 'src/Free/Value.c', + + 'src/Function/appendInstruction.c', + 'src/Function/appendArg.c', + + 'src/Instruction/append.c', + 'src/Instruction/execute.c', + + 'src/libmain.c', + + 'src/List/append.c', + + 'src/New/Arg/DirectRef.c', + 'src/New/Arg/FunctionRef.c', + 'src/New/Arg/LabelRef.c', + 'src/New/Arg/LineRef.c', + 'src/New/Arg/TypeRef.c', + 'src/New/Arg/Value.c', + 'src/New/Arg/ValueRef.c', + + 'src/New/Error.c', + 'src/New/Function.c', + 'src/New/List.c', + 'src/New/Object.c', + 'src/New/String.c', + 'src/New/Struct.c', + + 'src/New/NativeFunction.c', + + 'src/New/Instruction.c', + 'src/New/Program.c', + 'src/New/Type.c', + + 'src/New/Value/Bool.c', + 'src/New/Value/Char.c', + 'src/New/Value/Double.c', + 'src/New/Value/Function.c', + 'src/New/Value/Int.c', + 'src/New/Value/List.c', + 'src/New/Value/Object.c', + 'src/New/Value/String.c', + 'src/New/Value/Struct.c', + + 'src/Program/append.c', + 'src/Program/execute.c', + + 'src/Struct/addField.c' +) + +incdir = include_directories('include') + +libffi = dependency('libffi', version : '>=3.0.0') + +lib = library('ground', sources, include_directories : incdir, dependencies : libffi) diff --git a/src/Copy/Arg.c b/src/Copy/Arg.c new file mode 100644 index 0000000..ab55340 --- /dev/null +++ b/src/Copy/Arg.c @@ -0,0 +1,10 @@ +#include "../../include/ground.h" + +GroundArg _GroundCopyArg(GroundArg* in) { + GroundArg arg = *in; + if (in->type == GroundArg_Value) { + arg.as.value = Ground.Copy.Value(&in->as.value); + } + + return arg; +} diff --git a/src/Copy/Function.c b/src/Copy/Function.c new file mode 100644 index 0000000..ce378cb --- /dev/null +++ b/src/Copy/Function.c @@ -0,0 +1,39 @@ +#include "../../include/ground.h" + +#include + +GroundFunction _GroundCopyFunction(GroundFunction* in) { + GroundFunction newFunction = *in; + + if (in->isNativeFunction) return newFunction; + + newFunction.program.ground = malloc(sizeof(GroundProgram)); + if (newFunction.program.ground == NULL) { + Ground.Flags.error = true; + return newFunction; + } + + *newFunction.program.ground = Ground.Copy.Program(in->program.ground); + + newFunction.closure = malloc(sizeof(GroundState)); + if (newFunction.closure == NULL) { + Ground.Flags.error = true; + return newFunction; + } + + *newFunction.closure = Ground.Copy.State(in->closure); + + newFunction.args.at = malloc(sizeof(char*) * in->args.capacity); + for (size_t i = 0; i < in->args.count; i++) { + size_t len = strlen(in->args.at[i].as.id); + newFunction.args.at = malloc(sizeof(char) * (len + 1)); + if (newFunction.args.at == NULL) { + Ground.Flags.error = true; + return newFunction; + } + + strcpy(newFunction.args.at[i].as.id, in->args.at[i].as.id); + } + + return newFunction; +} diff --git a/src/Copy/Instruction.c b/src/Copy/Instruction.c new file mode 100644 index 0000000..7e0060d --- /dev/null +++ b/src/Copy/Instruction.c @@ -0,0 +1,19 @@ +#include "../../include/ground.h" + +#include + +GroundInstruction _GroundCopyInstruction(GroundInstruction* in) { + GroundInstruction instruction = *in; + + instruction.args.at = malloc(sizeof(GroundArg) * in->args.capacity); + if (instruction.args.at == NULL) { + Ground.Flags.error = true; + return instruction; + } + + for (size_t i = 0; i < in->args.len; i++) { + instruction.args.at[i] = Ground.Copy.Arg(&in->args.at[i]); + } + + return instruction; +} diff --git a/src/Copy/List.c b/src/Copy/List.c new file mode 100644 index 0000000..f1234ad --- /dev/null +++ b/src/Copy/List.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +GroundList _GroundCopyList(GroundList* in) { + GroundList list = *in; + + list.at = malloc(sizeof(GroundValue) * in->capacity); + if (list.at == NULL) { + Ground.Flags.error = false; + return list; + } + + for (size_t i = 0; i < in->count; i++) { + list.at[i] = Ground.Copy.Value(&in->at[i]); + } + + return list; +} diff --git a/src/Copy/Object.c b/src/Copy/Object.c new file mode 100644 index 0000000..5be9f17 --- /dev/null +++ b/src/Copy/Object.c @@ -0,0 +1,35 @@ +#include "../../include/ground.h" + +GroundObject _GroundCopyObject(GroundObject* in) { + + GroundObject object = { + .fields = NULL, + .type = in->type + }; + + GroundObjectField* src = in->fields; + + GroundObjectField *s, *tmp, *item; + + HASH_ITER(hh, src, s, tmp) { + + item = malloc(sizeof(GroundObjectField)); + if (item == NULL) { + Ground.Flags.error = true; + return object; + } + + strncpy(item->name, s->name, 2047); + + *item->value = Ground.Copy.Value(s->value); + + if (Ground.Flags.error) { + return object; + } + + HASH_ADD_STR(object.fields, name, item); + } + + return object; +} + diff --git a/src/Copy/Program.c b/src/Copy/Program.c new file mode 100644 index 0000000..b7220bd --- /dev/null +++ b/src/Copy/Program.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +GroundProgram _GroundCopyProgram(GroundProgram* in) { + GroundProgram program = *in; + + program.at = malloc(sizeof(GroundInstruction) * in->capacity); + if (program.at == NULL) { + Ground.Flags.error = false; + return program; + } + + for (size_t i = 0; i < in->len; i++) { + program.at[i] = Ground.Copy.Instruction(&in->at[i]); + } + + return program; +} diff --git a/src/Copy/State.c b/src/Copy/State.c new file mode 100644 index 0000000..cb5a7e8 --- /dev/null +++ b/src/Copy/State.c @@ -0,0 +1,68 @@ +#include "../../include/ground.h" + +#include +#include + +GroundState _GroundCopyState(GroundState* in) { + GroundState state = { + .variables = NULL, + .labels = NULL, + .catches = NULL, + }; + + { + GroundVariable *s, *tmp, *new; + + HASH_ITER(hh, in->variables, s, tmp) { + new = malloc(sizeof(GroundVariable)); + if (new == NULL) { + Ground.Flags.error = true; + return state; + } + + strncpy(new->name, s->name, 2047); + + new->value = Ground.Copy.Value(&s->value); + + HASH_ADD_STR(state.variables, name, new); + } + } + + { + GroundLabel *s, *tmp, *new; + + HASH_ITER(hh, in->labels, s, tmp) { + new = malloc(sizeof(GroundVariable)); + if (new == NULL) { + Ground.Flags.error = true; + return state; + } + + strncpy(new->name, s->name, 2047); + + new->lineNum = s->lineNum; + + HASH_ADD_STR(state.labels, name, new); + } + } + + { + GroundCatch *s, *tmp, *new; + + HASH_ITER(hh, in->catches, s, tmp) { + new = malloc(sizeof(GroundVariable)); + if (new == NULL) { + Ground.Flags.error = true; + return state; + } + + strncpy(new->name, s->name, 2047); + + new->type = s->type; + + HASH_ADD_STR(state.catches, name, new); + } + } + + return state; +} diff --git a/src/Copy/String.c b/src/Copy/String.c new file mode 100644 index 0000000..95b1598 --- /dev/null +++ b/src/Copy/String.c @@ -0,0 +1,14 @@ +#include "../../include/ground.h" + +GroundString _GroundCopyString(GroundString* in) { + GroundString string = *in; + + string.cstr = malloc(sizeof(char) * in->len); + if (string.cstr == NULL) { + Ground.Flags.error = false; + return string; + } + + strcpy(string.cstr, in->cstr); + return string; +} diff --git a/src/Copy/Struct.c b/src/Copy/Struct.c new file mode 100644 index 0000000..ac167cb --- /dev/null +++ b/src/Copy/Struct.c @@ -0,0 +1,33 @@ +#include "../../include/ground.h" + +GroundStruct _GroundCopyStruct(GroundStruct* in) { + + GroundStruct gs = { + .fields = NULL + }; + + GroundObjectField* src = in->fields; + + GroundObjectField *s, *tmp, *item; + + HASH_ITER(hh, src, s, tmp) { + + item = malloc(sizeof(GroundObjectField)); + if (item == NULL) { + Ground.Flags.error = true; + return gs; + } + + strncpy(item->name, s->name, 2047); + + *item->value = Ground.Copy.Value(s->value); + + if (Ground.Flags.error) { + return gs; + } + + HASH_ADD_STR(gs.fields, name, item); + } + + return gs; +} diff --git a/src/Copy/Value.c b/src/Copy/Value.c new file mode 100644 index 0000000..89efa6a --- /dev/null +++ b/src/Copy/Value.c @@ -0,0 +1,33 @@ +#include "../../include/ground.h" + +GroundValue _GroundCopyValue(GroundValue* in) { + GroundValue newValue = *in; + + switch (in->type.type) { + case GroundType_String: { + newValue.as.String = Ground.Copy.String(&in->as.String); + break; + } + case GroundType_List: { + newValue.as.List = Ground.Copy.List(&in->as.List); + break; + } + case GroundType_Function: { + newValue.as.Function = Ground.Copy.Function(&in->as.Function); + break; + } + case GroundType_Struct: { + newValue.as.Struct = Ground.Copy.Struct(&in->as.Struct); + break; + } + case GroundType_Object: { + newValue.as.Object = Ground.Copy.Object(&in->as.Object); + break; + } + default: { + break; + } + } + + return newValue; +} diff --git a/src/Free/Function.c b/src/Free/Function.c new file mode 100644 index 0000000..38c0d02 --- /dev/null +++ b/src/Free/Function.c @@ -0,0 +1,19 @@ +#include "../../include/ground.h" + +void _GroundFreeFunction(GroundFunction* in) { + if (!in->isNativeFunction) { + Ground.Free.Program(in->program.ground); + free(in->program.ground); + + for (size_t i = 0; i < in->args.count; i++) { + free(in->args.at[i].as.id); + } + } + + Ground.Free.State(in->closure); + free(in->closure); + + free(in->args.at); + in->args.count = 0; + in->args.capacity = 0; +} diff --git a/src/Free/List.c b/src/Free/List.c new file mode 100644 index 0000000..a711c51 --- /dev/null +++ b/src/Free/List.c @@ -0,0 +1,9 @@ +#include "../../include/ground.h" + +#include + +void _GroundFreeList(GroundList* in) { + free(in->at); + in->capacity = 0; + in->count = 0; +} diff --git a/src/Free/Object.c b/src/Free/Object.c new file mode 100644 index 0000000..bd95458 --- /dev/null +++ b/src/Free/Object.c @@ -0,0 +1,15 @@ +#include "../../include/ground.h" + +#include + +void _GroundFreeObject(GroundObject* in) { + GroundObjectField *s, *tmp; + + HASH_ITER(hh, in->fields, s, tmp) { + + HASH_DEL(in->fields, s); + + Ground.Free.Value(s->value); + free(s->value); + } +} diff --git a/src/Free/String.c b/src/Free/String.c new file mode 100644 index 0000000..c537028 --- /dev/null +++ b/src/Free/String.c @@ -0,0 +1,8 @@ +#include "../../include/ground.h" + +#include + +void _GroundFreeString(GroundString* in) { + free(in->cstr); + in->len = 0; +} diff --git a/src/Free/Struct.c b/src/Free/Struct.c new file mode 100644 index 0000000..c43230b --- /dev/null +++ b/src/Free/Struct.c @@ -0,0 +1,15 @@ +#include "../../include/ground.h" + +#include + +void _GroundFreeStruct(GroundStruct* in) { + GroundObjectField *s, *tmp; + + HASH_ITER(hh, in->fields, s, tmp) { + + HASH_DEL(in->fields, s); + + Ground.Free.Value(s->value); + free(s->value); + } +} diff --git a/src/Free/Value.c b/src/Free/Value.c new file mode 100644 index 0000000..9270c76 --- /dev/null +++ b/src/Free/Value.c @@ -0,0 +1,30 @@ +#include "../../include/ground.h" + +void _GroundFreeValue(GroundValue* in) { + switch (in->type.type) { + case GroundType_String: { + Ground.Free.String(&in->as.String); + break; + } + case GroundType_List: { + Ground.Free.List(&in->as.List); + break; + } + case GroundType_Function: { + Ground.Free.Function(&in->as.Function); + break; + } + case GroundType_Struct: { + Ground.Free.Struct(&in->as.Struct); + break; + } + case GroundType_Object: { + Ground.Free.Object(&in->as.Object); + break; + } + + default: { + break; + } + } +} diff --git a/src/Function/appendArg.c b/src/Function/appendArg.c new file mode 100644 index 0000000..cce71d8 --- /dev/null +++ b/src/Function/appendArg.c @@ -0,0 +1,29 @@ +#include "../../include/ground.h" +#include + +void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) { + if (function->isNativeFunction) { + Ground.Flags.error = true; + return; + } + if (function->args.count + 1 >= function->args.capacity) { + GroundFunctionArg* tmp = realloc(function->args.at, sizeof(GroundFunctionArg) * function->args.capacity * 2); + if (tmp == NULL) { + Ground.Flags.error = true; + return; + } + + function->args.at = tmp; + function->args.capacity *= 2; + } + + size_t len = strlen(argName); + function->args.at[function->args.count].as.id = malloc(sizeof(char) * (len + 1)); + if (function->args.at[function->args.count].as.id == NULL) { + Ground.Flags.error = true; + return; + } + + strcpy(function->args.at[function->args.count].as.id, argName); + function->args.count++; +} diff --git a/src/Function/appendInstruction.c b/src/Function/appendInstruction.c new file mode 100644 index 0000000..6a447ec --- /dev/null +++ b/src/Function/appendInstruction.c @@ -0,0 +1,9 @@ +#include "../../include/ground.h" + +void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction) { + if (function->isNativeFunction) { + Ground.Flags.error = true; + return; + } + Ground.Program.append(function->program.ground, instruction); +} diff --git a/src/Instruction/append.c b/src/Instruction/append.c new file mode 100644 index 0000000..82df2fd --- /dev/null +++ b/src/Instruction/append.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +void _GroundInstructionAppend(GroundInstruction* instruction, GroundArg arg) { + if (instruction->args.len + 1 >= instruction->args.capacity) { + GroundArg* tmp = realloc(instruction->args.at, sizeof(GroundArg) * instruction->args.capacity * 2); + if (tmp == NULL) { + Ground.Flags.error = true; + return; + } + + instruction->args.at = tmp; + instruction->args.capacity *= 2; + } + + instruction->args.at[instruction->args.len] = Ground.Copy.Arg(&arg); + instruction->args.len++; +} diff --git a/src/Instruction/execute.c b/src/Instruction/execute.c new file mode 100644 index 0000000..84864d8 --- /dev/null +++ b/src/Instruction/execute.c @@ -0,0 +1,5 @@ +#include "../../include/ground.h" + +void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state) { + // Stub +} diff --git a/src/List/append.c b/src/List/append.c new file mode 100644 index 0000000..e67047c --- /dev/null +++ b/src/List/append.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +void _GroundListAppend(GroundList* list, GroundValue value) { + if (list->count + 1 >= list->capacity) { + GroundValue* tmp = realloc(list->at, sizeof(GroundValue) * list->capacity * 2); + if (tmp == NULL) { + Ground.Flags.error = true; + return; + } + + list->at = tmp; + list->capacity *= 2; + } + + list->at[list->count] = Ground.Copy.Value(&value); + list->count++; +} diff --git a/src/New/Arg/DirectRef.c b/src/New/Arg/DirectRef.c new file mode 100644 index 0000000..6d8be4d --- /dev/null +++ b/src/New/Arg/DirectRef.c @@ -0,0 +1,24 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgDirectRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = copy + }; +} diff --git a/src/New/Arg/FunctionRef.c b/src/New/Arg/FunctionRef.c new file mode 100644 index 0000000..bb2b633 --- /dev/null +++ b/src/New/Arg/FunctionRef.c @@ -0,0 +1,24 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgFunctionRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_FunctionRef, + .as.ref = copy + }; +} diff --git a/src/New/Arg/LabelRef.c b/src/New/Arg/LabelRef.c new file mode 100644 index 0000000..8763243 --- /dev/null +++ b/src/New/Arg/LabelRef.c @@ -0,0 +1,25 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgLabelRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_Label, + .as.ref = copy + }; +} + diff --git a/src/New/Arg/LineRef.c b/src/New/Arg/LineRef.c new file mode 100644 index 0000000..f27d7cb --- /dev/null +++ b/src/New/Arg/LineRef.c @@ -0,0 +1,24 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgLineRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_LineRef, + .as.ref = copy + }; +} diff --git a/src/New/Arg/TypeRef.c b/src/New/Arg/TypeRef.c new file mode 100644 index 0000000..d248a62 --- /dev/null +++ b/src/New/Arg/TypeRef.c @@ -0,0 +1,25 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgTypeRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_TypeRef, + .as.ref = copy + }; +} + diff --git a/src/New/Arg/Value.c b/src/New/Arg/Value.c new file mode 100644 index 0000000..b866e70 --- /dev/null +++ b/src/New/Arg/Value.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundArg _GroundNewArgValue(GroundValue value) { + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.value = Ground.Copy.Value(&value) + }; +} diff --git a/src/New/Arg/ValueRef.c b/src/New/Arg/ValueRef.c new file mode 100644 index 0000000..3e871bd --- /dev/null +++ b/src/New/Arg/ValueRef.c @@ -0,0 +1,25 @@ +#include "../../../include/ground.h" + +#include +#include + +GroundArg _GroundNewArgValueRef(const char* ref) { + size_t len = strlen(ref); + char* copy = malloc(len + 1); + + if (copy == NULL) { + Ground.Flags.error = true; + return (GroundArg) { + .type = GroundArg_DirectRef, + .as.ref = "" + }; + } + + strcpy(copy, ref); + + return (GroundArg) { + .type = GroundArg_ValueRef, + .as.ref = copy + }; +} + diff --git a/src/New/Error.c b/src/New/Error.c new file mode 100644 index 0000000..9423a88 --- /dev/null +++ b/src/New/Error.c @@ -0,0 +1,15 @@ +#include "../../include/ground.h" + +GroundError _GroundNewError(GroundValue* in) { + GroundError error = { + .value = malloc(sizeof(GroundValue)) + }; + + if (error.value == NULL) { + Ground.Flags.error = true; + return error; + } + + *error.value = Ground.Copy.Value(in); + return error; +} diff --git a/src/New/Function.c b/src/New/Function.c new file mode 100644 index 0000000..4b4f5fc --- /dev/null +++ b/src/New/Function.c @@ -0,0 +1,23 @@ +#include "../../include/ground.h" + +GroundFunction _GroundNewFunction(GroundState* state) { + GroundFunction function = { + .args.at = malloc(sizeof(char*) * 16), + .args.count = 0, + .args.capacity = 0, + + .closure = malloc(sizeof(GroundState)), + .isNativeFunction = false, + .program.ground = malloc(sizeof(GroundProgram)), + }; + + if (function.closure == NULL || function.program.ground == NULL) { + Ground.Flags.error = true; + return function; + } + + *function.closure = Ground.Copy.State(state); + *function.program.ground = Ground.New.Program(); + + return function; +} diff --git a/src/New/Instruction.c b/src/New/Instruction.c new file mode 100644 index 0000000..06ccd4e --- /dev/null +++ b/src/New/Instruction.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +GroundInstruction _GroundNewInstruction(enum GroundInstructionType type) { + GroundInstruction instruction = { + .type = type, + .args = { + .capacity = 8, + .len = 0, + .at = malloc(sizeof(GroundArg) * 8) + } + }; + + if (instruction.args.at == NULL) { + Ground.Flags.error = true; + } + return instruction; +} diff --git a/src/New/List.c b/src/New/List.c new file mode 100644 index 0000000..4fa5fa8 --- /dev/null +++ b/src/New/List.c @@ -0,0 +1,15 @@ +#include "../../include/ground.h" + +GroundList _GroundNewList(size_t len, GroundValue* contents) { + GroundList list = { + .capacity = 16, + .count = 0, + .at = malloc(sizeof(GroundValue) * 16) + }; + + if (list.at == NULL) { + Ground.Flags.error = true; + } + + return list; +} diff --git a/src/New/NativeFunction.c b/src/New/NativeFunction.c new file mode 100644 index 0000000..cd42d71 --- /dev/null +++ b/src/New/NativeFunction.c @@ -0,0 +1,49 @@ +#include "../../include/ground.h" +#include +#include + +GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { + + GroundState state = {NULL, NULL, NULL}; + GroundFunction gf = Ground.New.Function(&state); + + gf.isNativeFunction = true; + gf.program.native = function; + + va_list args; + va_start(args, argc); + + for (size_t i = 0; i < argc; i++) { + GroundType type = va_arg(args, GroundType); + if (type.type == GroundType_Struct) { + Ground.Flags.error = true; + return gf; + } + + if (type.type == GroundType_Object) { + // WIP + Ground.Flags.error = true; + return gf; + } + + + if (gf.args.count + 1 >= gf.args.capacity) { + GroundFunctionArg* tmp = realloc(gf.args.at, sizeof(GroundFunctionArg) * gf.args.capacity * 2); + if (tmp == NULL) { + Ground.Flags.error = true; + return gf; + } + + gf.args.at = tmp; + gf.args.capacity *= 2; + } + + gf.args.at[gf.args.count].as.type = va_arg(args, GroundType); + gf.args.count++; + + } + + + return gf; + +} diff --git a/src/New/Object.c b/src/New/Object.c new file mode 100644 index 0000000..9c3b97c --- /dev/null +++ b/src/New/Object.c @@ -0,0 +1,34 @@ +#include "../../include/ground.h" + +GroundObject _GroundNewObject(GroundStruct* in) { + + GroundObject object = { + .fields = NULL, + .type = in + }; + + GroundObjectField* src = in->fields; + + GroundObjectField *s, *tmp, *item; + + HASH_ITER(hh, src, s, tmp) { + + item = malloc(sizeof(GroundObjectField)); + if (item == NULL) { + Ground.Flags.error = true; + return object; + } + + strncpy(item->name, s->name, 2047); + + *item->value = Ground.Copy.Value(s->value); + + if (Ground.Flags.error) { + return object; + } + + HASH_ADD_STR(object.fields, name, item); + } + + return object; +} diff --git a/src/New/Program.c b/src/New/Program.c new file mode 100644 index 0000000..099f359 --- /dev/null +++ b/src/New/Program.c @@ -0,0 +1,14 @@ +#include "../../include/ground.h" + +GroundProgram _GroundNewProgram() { + GroundProgram newProgram = { + .capacity = 16, + .len = 0, + .at = malloc(sizeof(GroundInstruction) * 16) + }; + + if (newProgram.at == NULL) { + Ground.Flags.error = true; + } + return newProgram; +} diff --git a/src/New/String.c b/src/New/String.c new file mode 100644 index 0000000..26d2232 --- /dev/null +++ b/src/New/String.c @@ -0,0 +1,20 @@ +#include "../../include/ground.h" + +GroundString _GroundNewString(const char* in) { + + size_t len = strlen(in); + + GroundString string = { + .len = len, + .cstr = malloc(sizeof(len) + 1) + }; + + if (string.cstr == NULL) { + Ground.Flags.error = true; + string.len = 0; + return string; + } + + strcpy(string.cstr, in); + return string; +} diff --git a/src/New/Struct.c b/src/New/Struct.c new file mode 100644 index 0000000..9e7a9b8 --- /dev/null +++ b/src/New/Struct.c @@ -0,0 +1,7 @@ +#include "../../include/ground.h" + +GroundStruct _GroundNewStruct() { + return (GroundStruct) { + .fields = NULL + }; +} diff --git a/src/New/Type.c b/src/New/Type.c new file mode 100644 index 0000000..df58b0b --- /dev/null +++ b/src/New/Type.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" +#include + +GroundType _GroundNewType(enum GroundTypeType type, ...) { + va_list args; + + GroundType gt = { + .type = type + }; + + if (type == GroundType_Object) { + va_start(args, type); + gt.complexType = va_arg(args, GroundStruct); + }; + + return gt; +} diff --git a/src/New/Value/Bool.c b/src/New/Value/Bool.c new file mode 100644 index 0000000..981fca7 --- /dev/null +++ b/src/New/Value/Bool.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueBool(GroundBool in) { + return (GroundValue) { + .as.Bool = in, + .type = Ground.New.Type(GroundType_Bool) + }; +} diff --git a/src/New/Value/Char.c b/src/New/Value/Char.c new file mode 100644 index 0000000..625a33d --- /dev/null +++ b/src/New/Value/Char.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueChar(GroundChar in) { + return (GroundValue) { + .as.Char = in, + .type = Ground.New.Type(GroundType_Char) + }; +} diff --git a/src/New/Value/Double.c b/src/New/Value/Double.c new file mode 100644 index 0000000..07fe31f --- /dev/null +++ b/src/New/Value/Double.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueDouble(GroundDouble in) { + return (GroundValue) { + .as.Double = in, + .type = Ground.New.Type(GroundType_Double) + }; +} diff --git a/src/New/Value/Function.c b/src/New/Value/Function.c new file mode 100644 index 0000000..70fdc91 --- /dev/null +++ b/src/New/Value/Function.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueFunction(GroundFunction in) { + return (GroundValue) { + .as.Function = in, + .type = Ground.New.Type(GroundType_Function) + }; +} diff --git a/src/New/Value/Int.c b/src/New/Value/Int.c new file mode 100644 index 0000000..ee0b540 --- /dev/null +++ b/src/New/Value/Int.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueInt(GroundInt in) { + return (GroundValue) { + .as.Int = in, + .type = Ground.New.Type(GroundType_Int) + }; +} diff --git a/src/New/Value/List.c b/src/New/Value/List.c new file mode 100644 index 0000000..03582a4 --- /dev/null +++ b/src/New/Value/List.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueList(GroundList in) { + return (GroundValue) { + .as.List = in, + .type = Ground.New.Type(GroundType_List) + }; +} diff --git a/src/New/Value/Object.c b/src/New/Value/Object.c new file mode 100644 index 0000000..326cf8e --- /dev/null +++ b/src/New/Value/Object.c @@ -0,0 +1,8 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueObject(GroundObject in) { + return (GroundValue) { + .as.Object = in, + .type = Ground.New.Type(GroundType_Object, *in.type) + }; +} diff --git a/src/New/Value/String.c b/src/New/Value/String.c new file mode 100644 index 0000000..847744d --- /dev/null +++ b/src/New/Value/String.c @@ -0,0 +1,9 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueString(GroundString in) { + return (GroundValue) { + .as.String = in, + .type = Ground.New.Type(GroundType_String) + }; +} + diff --git a/src/New/Value/Struct.c b/src/New/Value/Struct.c new file mode 100644 index 0000000..1d87072 --- /dev/null +++ b/src/New/Value/Struct.c @@ -0,0 +1,9 @@ +#include "../../../include/ground.h" + +GroundValue _GroundNewValueStruct(GroundStruct in) { + return (GroundValue) { + .as.Struct = in, + .type = Ground.New.Type(GroundType_Struct) + }; +} + diff --git a/src/Program/append.c b/src/Program/append.c new file mode 100644 index 0000000..7a132ca --- /dev/null +++ b/src/Program/append.c @@ -0,0 +1,17 @@ +#include "../../include/ground.h" + +void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction) { + if (program->len + 1 >= program->capacity) { + GroundInstruction* tmp = realloc(program->at, sizeof(GroundInstruction) * program->capacity * 2); + if (tmp == NULL) { + Ground.Flags.error = true; + return; + } + + program->at = tmp; + program->capacity *= 2; + } + + program->at[program->len] = Ground.Copy.Instruction(&instruction); + program->len++; +} diff --git a/src/Program/execute.c b/src/Program/execute.c new file mode 100644 index 0000000..c22c858 --- /dev/null +++ b/src/Program/execute.c @@ -0,0 +1,5 @@ +#include "../../include/ground.h" + +void _GroundProgramExecute(GroundProgram* program, GroundState* state) { + // stub +} diff --git a/src/Struct/addField.c b/src/Struct/addField.c new file mode 100644 index 0000000..4ca5f93 --- /dev/null +++ b/src/Struct/addField.c @@ -0,0 +1,31 @@ +#include "../../include/ground.h" + +void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value) { + GroundObjectField* field; + HASH_FIND_STR(gs->fields, id, field); + + if (field != NULL) { + Ground.Free.Value(field->value); + *field->value = Ground.Copy.Value(&value); + + strncpy(field->name, id, 2047); + } else { + field = malloc(sizeof(GroundObjectField)); + + if (field == NULL) { + Ground.Flags.error = true; + return; + } + + field->value = malloc(sizeof(GroundValue)); + if (field->value == NULL) { + Ground.Flags.error = true; + return; + } + + *field->value = Ground.Copy.Value(&value); + strncpy(field->name, id, 2047); + + } + +} diff --git a/src/libmain.c b/src/libmain.c new file mode 100644 index 0000000..4268b4a --- /dev/null +++ b/src/libmain.c @@ -0,0 +1,160 @@ +#include "../include/ground.h" + +GroundValue _GroundNewValueInt(GroundInt in); +GroundValue _GroundNewValueDouble(GroundDouble in); +GroundValue _GroundNewValueChar(GroundChar in); +GroundValue _GroundNewValueBool(GroundBool in); +GroundValue _GroundNewValueList(GroundList in); +GroundValue _GroundNewValueString(GroundString in); +GroundValue _GroundNewValueFunction(GroundFunction in); +GroundValue _GroundNewValueStruct(GroundStruct in); +GroundValue _GroundNewValueObject(GroundObject in); + +GroundArg _GroundNewArgValue(GroundValue value); +GroundArg _GroundNewArgValueRef(const char* ref); +GroundArg _GroundNewArgDirectRef(const char* ref); +GroundArg _GroundNewArgLineRef(const char* ref); +GroundArg _GroundNewArgLabelRef(const char* ref); +GroundArg _GroundNewArgFunctionRef(const char* ref); +GroundArg _GroundNewArgTypeRef(const char* ref); + +GroundList _GroundNewList(); +GroundString _GroundNewString(const char* in); +GroundFunction _GroundNewFunction(GroundState* state); +GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...); +GroundStruct _GroundNewStruct(); +GroundObject _GroundNewObject(GroundStruct* in); +GroundError _GroundNewError(GroundValue* in); + +GroundInstruction _GroundNewInstruction(enum GroundInstructionType type); +GroundProgram _GroundNewProgram(); +GroundType _GroundNewType(enum GroundTypeType type, ...); + + +void _GroundFreeValue(GroundValue* in); +void _GroundFreeList(GroundList* in); +void _GroundFreeString(GroundString* in); +void _GroundFreeFunction(GroundFunction* in); +void _GroundFreeStruct(GroundStruct* in); +void _GroundFreeObject(GroundObject* in); + + +GroundValue _GroundCopyValue(GroundValue* in); +GroundList _GroundCopyList(GroundList* in); +GroundString _GroundCopyString(GroundString* in); +GroundFunction _GroundCopyFunction(GroundFunction* in); +GroundStruct _GroundCopyStruct(GroundStruct* in); +GroundObject _GroundCopyObject(GroundObject* in); + +GroundArg _GroundCopyArg(GroundArg* in); +GroundInstruction _GroundCopyInstruction(GroundInstruction* in); +GroundProgram _GroundCopyProgram(GroundProgram* in); +GroundState _GroundCopyState(GroundState* in); + + +void _GroundListAppend(GroundList* list, GroundValue value); + + +void _GroundInstructionAppend(GroundInstruction* instruction, GroundArg arg); +void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state); + + +void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction); +void _GroundProgramExecute(GroundProgram* program, GroundState* state); + + +void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction); +void _GroundFunctionAppendArg(GroundFunction* function, const char* argName); + + +void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value); + + +struct _Ground Ground = { + + .Flags = { + .error = false + }, + + .New = { + .Value = { + .Int = _GroundNewValueInt, + .Double = _GroundNewValueDouble, + .Char = _GroundNewValueChar, + .Bool = _GroundNewValueBool, + .List = _GroundNewValueList, + .String = _GroundNewValueString, + .Function = _GroundNewValueFunction, + .Struct = _GroundNewValueStruct, + .Object = _GroundNewValueObject, + }, + .Arg = { + .Value = _GroundNewArgValue, + .ValueRef = _GroundNewArgValueRef, + .DirectRef = _GroundNewArgDirectRef, + .LineRef = _GroundNewArgLineRef, + .LabelRef = _GroundNewArgLabelRef, + .FunctionRef = _GroundNewArgFunctionRef, + .TypeRef = _GroundNewArgTypeRef, + }, + .List = _GroundNewList, + .String = _GroundNewString, + .Function = _GroundNewFunction, + .Struct = _GroundNewStruct, + .Object = _GroundNewObject, + .Error = _GroundNewError, + + .NativeFunction = _GroundNewNativeFunction, + + .Instruction = _GroundNewInstruction, + .Program = _GroundNewProgram, + .Type = _GroundNewType, + }, + + .Free = { + .Value = _GroundFreeValue, + .List = _GroundFreeList, + .String = _GroundFreeString, + .Function = _GroundFreeFunction, + .Struct = _GroundFreeStruct, + .Object = _GroundFreeObject, + }, + + .Copy = { + .Value = _GroundCopyValue, + .List = _GroundCopyList, + .String = _GroundCopyString, + .Function = _GroundCopyFunction, + .Struct = _GroundCopyStruct, + .Object = _GroundCopyObject, + + .Arg = _GroundCopyArg, + .Instruction = _GroundCopyInstruction, + .Program = _GroundCopyProgram, + .State = _GroundCopyState, + + }, + + .List = { + .append = _GroundListAppend, + }, + + .Instruction = { + .append = _GroundInstructionAppend, + .execute = _GroundInstructionExecute, + }, + + .Program = { + .append = _GroundProgramAppend, + .execute = _GroundProgramExecute, + }, + + .Function = { + .appendInstruction = _GroundFunctionAppendInstruction, + .appendArg = _GroundFunctionAppendArg, + }, + + .Struct = { + .addField = _GroundStructAddField, + }, +};