diff --git a/README.md b/README.md index 2197142..f5207f7 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,11 @@ Install dependencies (uthash, libffi) then: meson setup builddir meson compile -C builddir ``` + +Install with: + +```sh +meson install -C builddir +``` + +You may need to run `ldconfig` or reboot to update your ld cache. diff --git a/include/ground.h b/include/ground.h index 653280b..6fd9e24 100644 --- a/include/ground.h +++ b/include/ground.h @@ -74,6 +74,8 @@ struct GroundFunction { } program; GroundState* closure; + + size_t _requiredSize; }; struct GroundStruct { @@ -144,6 +146,8 @@ struct GroundArg { const char* ref; GroundValue value; } as; + + size_t _offset; }; enum GroundInstructionType { @@ -219,6 +223,8 @@ struct GroundVariable { char name[2048]; GroundValue value; UT_hash_handle hh; + + size_t _offset; }; struct GroundLabel { @@ -237,6 +243,8 @@ struct GroundState { GroundVariable* variables; GroundLabel* labels; GroundCatch* catches; + + size_t _size; }; // @@ -344,6 +352,29 @@ struct _Ground { struct { void (*addField) (GroundStruct* gs, const char* id, GroundValue value); } Struct; + + struct { + GroundValue* (*findVariable) (GroundState* state, const char* id); + size_t* (*findLabel) (GroundState* state, const char* id); + GroundCatch* (*findCatch) (GroundState* state, const char* id); + } State; + + struct { + void (*run)(GroundProgram* program, GroundState* state); + void (*giveUpAndCry)(); + } Internal; + + struct { + void (*Error) (const char* message); + void (*Warning) (const char* message); + + void (*printErrors)(); + + char* errors[4096]; + size_t errorCount; + char* warnings[4096]; + size_t warningCount; + } Log; }; extern struct _Ground Ground; diff --git a/meson.build b/meson.build index be010fc..7b82d26 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,7 @@ project('ground', 'c', version : '0.1.0') +pkg = import('pkgconfig') + sources = files( 'src/Copy/Arg.c', 'src/Copy/Function.c', @@ -25,10 +27,17 @@ sources = files( 'src/Instruction/append.c', 'src/Instruction/execute.c', + 'src/Internal/giveUpAndCry.c', + 'src/Internal/run.c', + 'src/libmain.c', 'src/List/append.c', + 'src/Log/Error.c', + 'src/Log/printErrors.c', + 'src/Log/Warning.c', + 'src/New/Arg/DirectRef.c', 'src/New/Arg/FunctionRef.c', 'src/New/Arg/LabelRef.c', @@ -63,6 +72,10 @@ sources = files( 'src/Program/append.c', 'src/Program/execute.c', + 'src/State/findCatch.c', + 'src/State/findLabel.c', + 'src/State/findVariable.c', + 'src/Struct/addField.c' ) @@ -70,4 +83,12 @@ incdir = include_directories('include') libffi = dependency('libffi', version : '>=3.0.0') -lib = library('ground', sources, include_directories : incdir, dependencies : libffi) +install_headers('include/ground.h') + +lib = shared_library('ground', sources, include_directories : incdir, dependencies : libffi, install : true) + +pkg.generate(lib, + name : 'ground', + version : meson.project_version(), + description : 'Ground virtual machine', +) diff --git a/src/Copy/Function.c b/src/Copy/Function.c index ce378cb..af9130b 100644 --- a/src/Copy/Function.c +++ b/src/Copy/Function.c @@ -9,6 +9,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) { newFunction.program.ground = malloc(sizeof(GroundProgram)); if (newFunction.program.ground == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Function()"); Ground.Flags.error = true; return newFunction; } @@ -17,6 +18,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) { newFunction.closure = malloc(sizeof(GroundState)); if (newFunction.closure == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Function()"); Ground.Flags.error = true; return newFunction; } @@ -28,6 +30,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) { size_t len = strlen(in->args.at[i].as.id); newFunction.args.at = malloc(sizeof(char) * (len + 1)); if (newFunction.args.at == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Function()"); Ground.Flags.error = true; return newFunction; } diff --git a/src/Copy/Instruction.c b/src/Copy/Instruction.c index 7e0060d..73b3d65 100644 --- a/src/Copy/Instruction.c +++ b/src/Copy/Instruction.c @@ -7,6 +7,7 @@ GroundInstruction _GroundCopyInstruction(GroundInstruction* in) { instruction.args.at = malloc(sizeof(GroundArg) * in->args.capacity); if (instruction.args.at == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Instruction()"); Ground.Flags.error = true; return instruction; } diff --git a/src/Copy/Object.c b/src/Copy/Object.c index 5be9f17..c59cef2 100644 --- a/src/Copy/Object.c +++ b/src/Copy/Object.c @@ -15,6 +15,7 @@ GroundObject _GroundCopyObject(GroundObject* in) { item = malloc(sizeof(GroundObjectField)); if (item == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Object()"); Ground.Flags.error = true; return object; } diff --git a/src/Copy/State.c b/src/Copy/State.c index cb5a7e8..bad1ae6 100644 --- a/src/Copy/State.c +++ b/src/Copy/State.c @@ -16,6 +16,7 @@ GroundState _GroundCopyState(GroundState* in) { HASH_ITER(hh, in->variables, s, tmp) { new = malloc(sizeof(GroundVariable)); if (new == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.State()"); Ground.Flags.error = true; return state; } @@ -34,6 +35,7 @@ GroundState _GroundCopyState(GroundState* in) { HASH_ITER(hh, in->labels, s, tmp) { new = malloc(sizeof(GroundVariable)); if (new == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.State()"); Ground.Flags.error = true; return state; } @@ -52,6 +54,7 @@ GroundState _GroundCopyState(GroundState* in) { HASH_ITER(hh, in->catches, s, tmp) { new = malloc(sizeof(GroundVariable)); if (new == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.State()"); Ground.Flags.error = true; return state; } diff --git a/src/Copy/Struct.c b/src/Copy/Struct.c index ac167cb..cd0fb30 100644 --- a/src/Copy/Struct.c +++ b/src/Copy/Struct.c @@ -14,6 +14,7 @@ GroundStruct _GroundCopyStruct(GroundStruct* in) { item = malloc(sizeof(GroundObjectField)); if (item == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Struct()"); Ground.Flags.error = true; return gs; } diff --git a/src/Function/appendArg.c b/src/Function/appendArg.c index cce71d8..84855d9 100644 --- a/src/Function/appendArg.c +++ b/src/Function/appendArg.c @@ -3,12 +3,14 @@ void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) { if (function->isNativeFunction) { + Ground.Log.Error("Cannot add arg to native function in Ground.Function.appendArg()"); 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.Log.Error("malloc failed in Ground.Function.appendArg()"); Ground.Flags.error = true; return; } @@ -20,6 +22,7 @@ void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) { 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.Log.Error("malloc failed in Ground.Function.appendArg()"); Ground.Flags.error = true; return; } diff --git a/src/Function/appendInstruction.c b/src/Function/appendInstruction.c index 6a447ec..2d4d571 100644 --- a/src/Function/appendInstruction.c +++ b/src/Function/appendInstruction.c @@ -2,6 +2,7 @@ void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction) { if (function->isNativeFunction) { + Ground.Log.Error("Cannot add instruction to native function in Ground.Function.appendInstruction()"); Ground.Flags.error = true; return; } diff --git a/src/Instruction/append.c b/src/Instruction/append.c index 82df2fd..2b62ea0 100644 --- a/src/Instruction/append.c +++ b/src/Instruction/append.c @@ -4,6 +4,7 @@ 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.Log.Error("malloc failed in Ground.Instruction.append()"); Ground.Flags.error = true; return; } diff --git a/src/Instruction/execute.c b/src/Instruction/execute.c index 84864d8..7fa34de 100644 --- a/src/Instruction/execute.c +++ b/src/Instruction/execute.c @@ -1,5 +1,116 @@ #include "../../include/ground.h" +#define handle(instruction) handle##instruction##(instruction, state); break; + void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state) { - // Stub + 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; + } } diff --git a/src/Internal/giveUpAndCry.c b/src/Internal/giveUpAndCry.c new file mode 100644 index 0000000..f8a0839 --- /dev/null +++ b/src/Internal/giveUpAndCry.c @@ -0,0 +1,7 @@ +#include +#include + +void _GroundInternalGiveUpAndCry() { + printf("Ground has crashed and cannot recover. If you believe this to be a bug, please report this to the repo on Chookspace (https://chookspace.com/ground/ground2)\n"); + exit(1); +} diff --git a/src/Internal/run.c b/src/Internal/run.c new file mode 100644 index 0000000..ed29d9a --- /dev/null +++ b/src/Internal/run.c @@ -0,0 +1,117 @@ +#include "../../include/ground.h" + +#include +#include +#include + +void doLabels(GroundProgram* program, GroundState* state) { + + for (size_t i = 0; i < program->len; i++) { + for (size_t j = 0; j < program->len; j++) { + GroundArg* arg = &program->at[i].args.at[j]; + if (arg->type == GroundArg_Label) { + GroundLabel* label = NULL; + HASH_FIND_STR(state->labels, arg->as.ref, label); + + if (label == NULL) { + label = malloc(sizeof(GroundLabel)); + if (label == NULL) { + Ground.Log.Error("malloc failed in Ground.Internal.run()"); + Ground.Flags.error = true; + return; + } + label->lineNum = i; + HASH_ADD_STR(state->labels, name, label); + } + } + } + } + + for (size_t 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); + 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, i); + Ground.Log.Error(buf); + Ground.Flags.error = true; + return; + } + + } else if (instruction->type == GroundInstruction_IF) { + GroundArg* arg = &instruction->args.at[1]; + size_t* line = Ground.State.findLabel(state, arg->as.ref); + 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, i); + Ground.Log.Error(buf); + Ground.Flags.error = true; + return; + } + + } else if (instruction->type == GroundInstruction_CATCH) { + GroundArg* arg = &instruction->args.at[1]; + size_t* line = Ground.State.findLabel(state, arg->as.ref); + 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, i); + Ground.Log.Error(buf); + Ground.Flags.error = true; + return; + } + + } + } + +} + +/* + * Assigns an offset to each variable referenced. + */ +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++) { + GroundArg* arg = &program->at[i].args.at[j]; + + if ( + arg->type == GroundArg_Value || + arg->type == GroundArg_Label || + arg->type == GroundArg_LineRef + ) continue; + + GroundVariable* item = NULL; + HASH_FIND_STR(state->variables, arg->as.ref, item); + + if (item == NULL) { + item = malloc(sizeof(GroundVariable)); + if (item == NULL) { + Ground.Log.Error("malloc failed in Ground.Internal.run()"); + Ground.Flags.error = true; + return 0; + } + item->value = Ground.New.Value.Int(0); + strncpy(item->name, arg->as.ref, 2047); + item->_offset = size++; + HASH_ADD_STR(state->variables, name, item); + } + + arg->_offset = item->_offset; + size++; + } + } + return size; +} + +void _GroundInternalRun(GroundProgram* program, GroundState* state) { + + // Precompute some really cool stuff + doLabels(program, state); + if (Ground.Flags.error) return; + + size_t size = doOffsets(program, state); + if (Ground.Flags.error) return; + +} diff --git a/src/List/append.c b/src/List/append.c index e67047c..488150e 100644 --- a/src/List/append.c +++ b/src/List/append.c @@ -4,6 +4,7 @@ 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.Log.Error("malloc failed in Ground.List.Append()"); Ground.Flags.error = true; return; } diff --git a/src/Log/Error.c b/src/Log/Error.c new file mode 100644 index 0000000..f7ebcdb --- /dev/null +++ b/src/Log/Error.c @@ -0,0 +1,16 @@ +#include "../../include/ground.h" + +void _GroundLogError(const char* message) { + if (Ground.Log.errorCount >= 4096) { + Ground.Internal.giveUpAndCry(); + } + + char* copy = malloc(sizeof(char) * (strlen(message) + 1)); + if (copy == NULL) { + Ground.Internal.giveUpAndCry(); + } + + strcpy(copy, message); + Ground.Log.errors[Ground.Log.errorCount] = copy; + Ground.Log.errorCount++; +} diff --git a/src/Log/Warning.c b/src/Log/Warning.c new file mode 100644 index 0000000..f08aa76 --- /dev/null +++ b/src/Log/Warning.c @@ -0,0 +1,16 @@ +#include "../../include/ground.h" + +void _GroundLogWarning(const char* message) { + if (Ground.Log.warningCount >= 4096) { + Ground.Internal.giveUpAndCry(); + } + + char* copy = malloc(sizeof(char) * (strlen(message) + 1)); + if (copy == NULL) { + Ground.Internal.giveUpAndCry(); + } + + strcpy(copy, message); + Ground.Log.warnings[Ground.Log.warningCount] = copy; + Ground.Log.warningCount++; +} diff --git a/src/Log/printErrors.c b/src/Log/printErrors.c new file mode 100644 index 0000000..432746d --- /dev/null +++ b/src/Log/printErrors.c @@ -0,0 +1,16 @@ +#include "../../include/ground.h" + +void _GroundLogPrintErrors() { + if (Ground.Log.errorCount != 0) { + printf("%zu errors:\n", Ground.Log.errorCount); + for (size_t 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++) { + printf(" \e[0;33m%zu: %s\n\e[0m", Ground.Log.warningCount, Ground.Log.warnings[i]); + } + } +} diff --git a/src/New/Arg/DirectRef.c b/src/New/Arg/DirectRef.c index 6d8be4d..03e60ed 100644 --- a/src/New/Arg/DirectRef.c +++ b/src/New/Arg/DirectRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgDirectRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.DirectRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Arg/FunctionRef.c b/src/New/Arg/FunctionRef.c index bb2b633..4855fba 100644 --- a/src/New/Arg/FunctionRef.c +++ b/src/New/Arg/FunctionRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgFunctionRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.FunctionRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Arg/LabelRef.c b/src/New/Arg/LabelRef.c index 8763243..d371eca 100644 --- a/src/New/Arg/LabelRef.c +++ b/src/New/Arg/LabelRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgLabelRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.LabelRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Arg/LineRef.c b/src/New/Arg/LineRef.c index f27d7cb..dc21833 100644 --- a/src/New/Arg/LineRef.c +++ b/src/New/Arg/LineRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgLineRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.LineRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Arg/TypeRef.c b/src/New/Arg/TypeRef.c index d248a62..a98f4f4 100644 --- a/src/New/Arg/TypeRef.c +++ b/src/New/Arg/TypeRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgTypeRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.TypeRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Arg/Value.c b/src/New/Arg/Value.c index b866e70..0939647 100644 --- a/src/New/Arg/Value.c +++ b/src/New/Arg/Value.c @@ -2,7 +2,7 @@ GroundArg _GroundNewArgValue(GroundValue value) { return (GroundArg) { - .type = GroundArg_DirectRef, + .type = GroundArg_Value, .as.value = Ground.Copy.Value(&value) }; } diff --git a/src/New/Arg/ValueRef.c b/src/New/Arg/ValueRef.c index 3e871bd..557ffed 100644 --- a/src/New/Arg/ValueRef.c +++ b/src/New/Arg/ValueRef.c @@ -8,6 +8,7 @@ GroundArg _GroundNewArgValueRef(const char* ref) { char* copy = malloc(len + 1); if (copy == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Arg.ValueRef()"); Ground.Flags.error = true; return (GroundArg) { .type = GroundArg_DirectRef, diff --git a/src/New/Error.c b/src/New/Error.c index 9423a88..7faf748 100644 --- a/src/New/Error.c +++ b/src/New/Error.c @@ -6,6 +6,7 @@ GroundError _GroundNewError(GroundValue* in) { }; if (error.value == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Error()"); Ground.Flags.error = true; return error; } diff --git a/src/New/Instruction.c b/src/New/Instruction.c index 06ccd4e..a951a42 100644 --- a/src/New/Instruction.c +++ b/src/New/Instruction.c @@ -11,6 +11,7 @@ GroundInstruction _GroundNewInstruction(enum GroundInstructionType type) { }; if (instruction.args.at == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Instruction()"); Ground.Flags.error = true; } return instruction; diff --git a/src/New/List.c b/src/New/List.c index 4fa5fa8..8981430 100644 --- a/src/New/List.c +++ b/src/New/List.c @@ -8,6 +8,7 @@ GroundList _GroundNewList(size_t len, GroundValue* contents) { }; if (list.at == NULL) { + Ground.Log.Error("malloc failed in Ground.New.List()"); Ground.Flags.error = true; } diff --git a/src/New/NativeFunction.c b/src/New/NativeFunction.c index cd42d71..a26b810 100644 --- a/src/New/NativeFunction.c +++ b/src/New/NativeFunction.c @@ -16,6 +16,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { for (size_t 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()"); Ground.Flags.error = true; return gf; } @@ -23,6 +24,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { if (type.type == GroundType_Object) { // WIP Ground.Flags.error = true; + Ground.Log.Error("[WIP] Cannot pass object to native function in Ground.New.NativeFunction()"); return gf; } @@ -30,6 +32,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) { if (gf.args.count + 1 >= gf.args.capacity) { GroundFunctionArg* tmp = realloc(gf.args.at, sizeof(GroundFunctionArg) * gf.args.capacity * 2); if (tmp == NULL) { + Ground.Log.Error("malloc failed in Ground.New.NativeFunction()"); Ground.Flags.error = true; return gf; } diff --git a/src/New/Object.c b/src/New/Object.c index 9c3b97c..085f0c3 100644 --- a/src/New/Object.c +++ b/src/New/Object.c @@ -15,6 +15,7 @@ GroundObject _GroundNewObject(GroundStruct* in) { item = malloc(sizeof(GroundObjectField)); if (item == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Object()"); Ground.Flags.error = true; return object; } diff --git a/src/New/Program.c b/src/New/Program.c index 099f359..0f9abfd 100644 --- a/src/New/Program.c +++ b/src/New/Program.c @@ -8,6 +8,7 @@ GroundProgram _GroundNewProgram() { }; if (newProgram.at == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Program()"); Ground.Flags.error = true; } return newProgram; diff --git a/src/New/String.c b/src/New/String.c index 26d2232..48a617c 100644 --- a/src/New/String.c +++ b/src/New/String.c @@ -10,6 +10,7 @@ GroundString _GroundNewString(const char* in) { }; if (string.cstr == NULL) { + Ground.Log.Error("malloc failed in Ground.New.String()"); Ground.Flags.error = true; string.len = 0; return string; diff --git a/src/Program/append.c b/src/Program/append.c index 7a132ca..e73ff8d 100644 --- a/src/Program/append.c +++ b/src/Program/append.c @@ -4,6 +4,7 @@ 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.Log.Error("malloc failed in Ground.Program.append()"); Ground.Flags.error = true; return; } diff --git a/src/Program/execute.c b/src/Program/execute.c index c22c858..e869774 100644 --- a/src/Program/execute.c +++ b/src/Program/execute.c @@ -1,5 +1,11 @@ #include "../../include/ground.h" void _GroundProgramExecute(GroundProgram* program, GroundState* state) { - // stub + + // TODO: + // - Preprocess functions + // - Preprocess structs + // - Add them to state + + Ground.Internal.run(program, state); } diff --git a/src/State/findCatch.c b/src/State/findCatch.c new file mode 100644 index 0000000..b993249 --- /dev/null +++ b/src/State/findCatch.c @@ -0,0 +1,12 @@ +#include "../../include/ground.h" + +GroundCatch* _GroundStateFindCatch(GroundState* state, char* id) { + GroundCatch* item = NULL; + HASH_FIND_STR(state->catches, id, item); + + if (item == NULL) { + return NULL; + } + + return item; +} diff --git a/src/State/findLabel.c b/src/State/findLabel.c new file mode 100644 index 0000000..68987e4 --- /dev/null +++ b/src/State/findLabel.c @@ -0,0 +1,12 @@ +#include "../../include/ground.h" + +size_t* _GroundStateFindLabel(GroundState* state, char* id) { + GroundLabel* item = NULL; + HASH_FIND_STR(state->labels, id, item); + + if (item == NULL) { + return NULL; + } + + return &item->lineNum; +} diff --git a/src/State/findVariable.c b/src/State/findVariable.c new file mode 100644 index 0000000..2577dc4 --- /dev/null +++ b/src/State/findVariable.c @@ -0,0 +1,12 @@ +#include "../../include/ground.h" + +GroundValue* _GroundStateFindVariable (GroundState* state, const char* id) { + GroundVariable* item = NULL; + HASH_FIND_STR(state->variables, id, item); + + if (item == NULL) { + return NULL; + } + + return &item->value; +} diff --git a/src/Struct/addField.c b/src/Struct/addField.c index 4ca5f93..3a5ea69 100644 --- a/src/Struct/addField.c +++ b/src/Struct/addField.c @@ -13,12 +13,14 @@ void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value) field = malloc(sizeof(GroundObjectField)); if (field == NULL) { + Ground.Log.Error("malloc failed in Ground.Struct.addField()"); Ground.Flags.error = true; return; } field->value = malloc(sizeof(GroundValue)); if (field->value == NULL) { + Ground.Log.Error("malloc failed in Ground.Struct.addField()"); Ground.Flags.error = true; return; } diff --git a/src/libmain.c b/src/libmain.c index 4268b4a..2a28ed0 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -70,6 +70,21 @@ void _GroundFunctionAppendArg(GroundFunction* function, const char* argName); void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value); +GroundValue* _GroundStateFindVariable(GroundState* state, const char* id); +size_t* _GroundStateFindLabel(GroundState* state, const char* id); +GroundCatch* _GroundStateFindCatch(GroundState* state, const char* id); + + +void _GroundInternalRun(GroundProgram* program, GroundState* state); + + +void _GroundLogError(const char* message); +void _GroundLogWarning(const char* message); +void _GroundLogPrintErrors(); + + + + struct _Ground Ground = { .Flags = { @@ -157,4 +172,22 @@ struct _Ground Ground = { .Struct = { .addField = _GroundStructAddField, }, + + .State = { + .findCatch = _GroundStateFindCatch, + .findLabel = _GroundStateFindLabel, + .findVariable = _GroundStateFindVariable, + }, + + .Internal = { + .run = _GroundInternalRun + }, + + .Log = { + .Error = _GroundLogError, + .Warning = _GroundLogWarning, + .printErrors = _GroundLogPrintErrors, + .errors = NULL, + .warnings = NULL, + }, }; diff --git a/test/test b/test/test new file mode 100755 index 0000000..173b36e Binary files /dev/null and b/test/test differ diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..5ba51c0 --- /dev/null +++ b/test/test.c @@ -0,0 +1,15 @@ +#include + +int main() { + GroundProgram program = Ground.New.Program(); + printf(Ground.Flags.error ? "true\n" : "false\n"); + GroundState state = {NULL, NULL, NULL}; + GroundInstruction instruction = Ground.New.Instruction(GroundInstruction_ADD); + printf(Ground.Flags.error ? "true\n" : "false\n"); + Ground.Instruction.append(&instruction, Ground.New.Arg.Value(Ground.New.Value.Int(2))); + printf(Ground.Flags.error ? "true\n" : "false\n"); + Ground.Instruction.append(&instruction, Ground.New.Arg.Value(Ground.New.Value.Int(2))); + printf(Ground.Flags.error ? "true\n" : "false\n"); + Ground.Program.execute(&program, &state); + printf(Ground.Flags.error ? "true\n" : "false\n"); +}