cool stuff

This commit is contained in:
2026-06-15 20:27:50 +10:00
parent 284b08b12a
commit 80140ed798
41 changed files with 470 additions and 4 deletions

View File

@@ -6,3 +6,11 @@ Install dependencies (uthash, libffi) then:
meson setup builddir meson setup builddir
meson compile -C 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.

View File

@@ -74,6 +74,8 @@ struct GroundFunction {
} program; } program;
GroundState* closure; GroundState* closure;
size_t _requiredSize;
}; };
struct GroundStruct { struct GroundStruct {
@@ -144,6 +146,8 @@ struct GroundArg {
const char* ref; const char* ref;
GroundValue value; GroundValue value;
} as; } as;
size_t _offset;
}; };
enum GroundInstructionType { enum GroundInstructionType {
@@ -219,6 +223,8 @@ struct GroundVariable {
char name[2048]; char name[2048];
GroundValue value; GroundValue value;
UT_hash_handle hh; UT_hash_handle hh;
size_t _offset;
}; };
struct GroundLabel { struct GroundLabel {
@@ -237,6 +243,8 @@ struct GroundState {
GroundVariable* variables; GroundVariable* variables;
GroundLabel* labels; GroundLabel* labels;
GroundCatch* catches; GroundCatch* catches;
size_t _size;
}; };
// //
@@ -344,6 +352,29 @@ struct _Ground {
struct { struct {
void (*addField) (GroundStruct* gs, const char* id, GroundValue value); void (*addField) (GroundStruct* gs, const char* id, GroundValue value);
} Struct; } 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; extern struct _Ground Ground;

View File

@@ -1,5 +1,7 @@
project('ground', 'c', version : '0.1.0') project('ground', 'c', version : '0.1.0')
pkg = import('pkgconfig')
sources = files( sources = files(
'src/Copy/Arg.c', 'src/Copy/Arg.c',
'src/Copy/Function.c', 'src/Copy/Function.c',
@@ -25,10 +27,17 @@ sources = files(
'src/Instruction/append.c', 'src/Instruction/append.c',
'src/Instruction/execute.c', 'src/Instruction/execute.c',
'src/Internal/giveUpAndCry.c',
'src/Internal/run.c',
'src/libmain.c', 'src/libmain.c',
'src/List/append.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/DirectRef.c',
'src/New/Arg/FunctionRef.c', 'src/New/Arg/FunctionRef.c',
'src/New/Arg/LabelRef.c', 'src/New/Arg/LabelRef.c',
@@ -63,6 +72,10 @@ sources = files(
'src/Program/append.c', 'src/Program/append.c',
'src/Program/execute.c', 'src/Program/execute.c',
'src/State/findCatch.c',
'src/State/findLabel.c',
'src/State/findVariable.c',
'src/Struct/addField.c' 'src/Struct/addField.c'
) )
@@ -70,4 +83,12 @@ incdir = include_directories('include')
libffi = dependency('libffi', version : '>=3.0.0') 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',
)

View File

@@ -9,6 +9,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) {
newFunction.program.ground = malloc(sizeof(GroundProgram)); newFunction.program.ground = malloc(sizeof(GroundProgram));
if (newFunction.program.ground == NULL) { if (newFunction.program.ground == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Function()");
Ground.Flags.error = true; Ground.Flags.error = true;
return newFunction; return newFunction;
} }
@@ -17,6 +18,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) {
newFunction.closure = malloc(sizeof(GroundState)); newFunction.closure = malloc(sizeof(GroundState));
if (newFunction.closure == NULL) { if (newFunction.closure == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Function()");
Ground.Flags.error = true; Ground.Flags.error = true;
return newFunction; return newFunction;
} }
@@ -28,6 +30,7 @@ GroundFunction _GroundCopyFunction(GroundFunction* in) {
size_t len = strlen(in->args.at[i].as.id); size_t len = strlen(in->args.at[i].as.id);
newFunction.args.at = malloc(sizeof(char) * (len + 1)); newFunction.args.at = malloc(sizeof(char) * (len + 1));
if (newFunction.args.at == NULL) { if (newFunction.args.at == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Function()");
Ground.Flags.error = true; Ground.Flags.error = true;
return newFunction; return newFunction;
} }

View File

@@ -7,6 +7,7 @@ GroundInstruction _GroundCopyInstruction(GroundInstruction* in) {
instruction.args.at = malloc(sizeof(GroundArg) * in->args.capacity); instruction.args.at = malloc(sizeof(GroundArg) * in->args.capacity);
if (instruction.args.at == NULL) { if (instruction.args.at == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Instruction()");
Ground.Flags.error = true; Ground.Flags.error = true;
return instruction; return instruction;
} }

View File

@@ -15,6 +15,7 @@ GroundObject _GroundCopyObject(GroundObject* in) {
item = malloc(sizeof(GroundObjectField)); item = malloc(sizeof(GroundObjectField));
if (item == NULL) { if (item == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Object()");
Ground.Flags.error = true; Ground.Flags.error = true;
return object; return object;
} }

View File

@@ -16,6 +16,7 @@ GroundState _GroundCopyState(GroundState* in) {
HASH_ITER(hh, in->variables, s, tmp) { HASH_ITER(hh, in->variables, s, tmp) {
new = malloc(sizeof(GroundVariable)); new = malloc(sizeof(GroundVariable));
if (new == NULL) { if (new == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.State()");
Ground.Flags.error = true; Ground.Flags.error = true;
return state; return state;
} }
@@ -34,6 +35,7 @@ GroundState _GroundCopyState(GroundState* in) {
HASH_ITER(hh, in->labels, s, tmp) { HASH_ITER(hh, in->labels, s, tmp) {
new = malloc(sizeof(GroundVariable)); new = malloc(sizeof(GroundVariable));
if (new == NULL) { if (new == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.State()");
Ground.Flags.error = true; Ground.Flags.error = true;
return state; return state;
} }
@@ -52,6 +54,7 @@ GroundState _GroundCopyState(GroundState* in) {
HASH_ITER(hh, in->catches, s, tmp) { HASH_ITER(hh, in->catches, s, tmp) {
new = malloc(sizeof(GroundVariable)); new = malloc(sizeof(GroundVariable));
if (new == NULL) { if (new == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.State()");
Ground.Flags.error = true; Ground.Flags.error = true;
return state; return state;
} }

View File

@@ -14,6 +14,7 @@ GroundStruct _GroundCopyStruct(GroundStruct* in) {
item = malloc(sizeof(GroundObjectField)); item = malloc(sizeof(GroundObjectField));
if (item == NULL) { if (item == NULL) {
Ground.Log.Error("malloc failed in Ground.Copy.Struct()");
Ground.Flags.error = true; Ground.Flags.error = true;
return gs; return gs;
} }

View File

@@ -3,12 +3,14 @@
void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) { void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) {
if (function->isNativeFunction) { if (function->isNativeFunction) {
Ground.Log.Error("Cannot add arg to native function in Ground.Function.appendArg()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }
if (function->args.count + 1 >= function->args.capacity) { if (function->args.count + 1 >= function->args.capacity) {
GroundFunctionArg* tmp = realloc(function->args.at, sizeof(GroundFunctionArg) * function->args.capacity * 2); GroundFunctionArg* tmp = realloc(function->args.at, sizeof(GroundFunctionArg) * function->args.capacity * 2);
if (tmp == NULL) { if (tmp == NULL) {
Ground.Log.Error("malloc failed in Ground.Function.appendArg()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }
@@ -20,6 +22,7 @@ void _GroundFunctionAppendArg(GroundFunction* function, const char* argName) {
size_t len = strlen(argName); size_t len = strlen(argName);
function->args.at[function->args.count].as.id = malloc(sizeof(char) * (len + 1)); function->args.at[function->args.count].as.id = malloc(sizeof(char) * (len + 1));
if (function->args.at[function->args.count].as.id == NULL) { if (function->args.at[function->args.count].as.id == NULL) {
Ground.Log.Error("malloc failed in Ground.Function.appendArg()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

View File

@@ -2,6 +2,7 @@
void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction) { void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction) {
if (function->isNativeFunction) { if (function->isNativeFunction) {
Ground.Log.Error("Cannot add instruction to native function in Ground.Function.appendInstruction()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

View File

@@ -4,6 +4,7 @@ void _GroundInstructionAppend(GroundInstruction* instruction, GroundArg arg) {
if (instruction->args.len + 1 >= instruction->args.capacity) { if (instruction->args.len + 1 >= instruction->args.capacity) {
GroundArg* tmp = realloc(instruction->args.at, sizeof(GroundArg) * instruction->args.capacity * 2); GroundArg* tmp = realloc(instruction->args.at, sizeof(GroundArg) * instruction->args.capacity * 2);
if (tmp == NULL) { if (tmp == NULL) {
Ground.Log.Error("malloc failed in Ground.Instruction.append()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

View File

@@ -1,5 +1,116 @@
#include "../../include/ground.h" #include "../../include/ground.h"
#define handle(instruction) handle##instruction##(instruction, state); break;
void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state) { 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;
}
} }

View File

@@ -0,0 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
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);
}

117
src/Internal/run.c Normal file
View File

@@ -0,0 +1,117 @@
#include "../../include/ground.h"
#include <string.h>
#include <stdlib.h>
#include <uthash.h>
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;
}

View File

@@ -4,6 +4,7 @@ void _GroundListAppend(GroundList* list, GroundValue value) {
if (list->count + 1 >= list->capacity) { if (list->count + 1 >= list->capacity) {
GroundValue* tmp = realloc(list->at, sizeof(GroundValue) * list->capacity * 2); GroundValue* tmp = realloc(list->at, sizeof(GroundValue) * list->capacity * 2);
if (tmp == NULL) { if (tmp == NULL) {
Ground.Log.Error("malloc failed in Ground.List.Append()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

16
src/Log/Error.c Normal file
View File

@@ -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++;
}

16
src/Log/Warning.c Normal file
View File

@@ -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++;
}

16
src/Log/printErrors.c Normal file
View File

@@ -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]);
}
}
}

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgDirectRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.DirectRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgFunctionRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.FunctionRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgLabelRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.LabelRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgLineRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.LineRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgTypeRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.TypeRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -2,7 +2,7 @@
GroundArg _GroundNewArgValue(GroundValue value) { GroundArg _GroundNewArgValue(GroundValue value) {
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_Value,
.as.value = Ground.Copy.Value(&value) .as.value = Ground.Copy.Value(&value)
}; };
} }

View File

@@ -8,6 +8,7 @@ GroundArg _GroundNewArgValueRef(const char* ref) {
char* copy = malloc(len + 1); char* copy = malloc(len + 1);
if (copy == NULL) { if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.ValueRef()");
Ground.Flags.error = true; Ground.Flags.error = true;
return (GroundArg) { return (GroundArg) {
.type = GroundArg_DirectRef, .type = GroundArg_DirectRef,

View File

@@ -6,6 +6,7 @@ GroundError _GroundNewError(GroundValue* in) {
}; };
if (error.value == NULL) { if (error.value == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Error()");
Ground.Flags.error = true; Ground.Flags.error = true;
return error; return error;
} }

View File

@@ -11,6 +11,7 @@ GroundInstruction _GroundNewInstruction(enum GroundInstructionType type) {
}; };
if (instruction.args.at == NULL) { if (instruction.args.at == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Instruction()");
Ground.Flags.error = true; Ground.Flags.error = true;
} }
return instruction; return instruction;

View File

@@ -8,6 +8,7 @@ GroundList _GroundNewList(size_t len, GroundValue* contents) {
}; };
if (list.at == NULL) { if (list.at == NULL) {
Ground.Log.Error("malloc failed in Ground.New.List()");
Ground.Flags.error = true; Ground.Flags.error = true;
} }

View File

@@ -16,6 +16,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) {
for (size_t i = 0; i < argc; i++) { for (size_t i = 0; i < argc; i++) {
GroundType type = va_arg(args, GroundType); GroundType type = va_arg(args, GroundType);
if (type.type == GroundType_Struct) { if (type.type == GroundType_Struct) {
Ground.Log.Error("Cannot pass struct to native function in Ground.New.NativeFunction()");
Ground.Flags.error = true; Ground.Flags.error = true;
return gf; return gf;
} }
@@ -23,6 +24,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) {
if (type.type == GroundType_Object) { if (type.type == GroundType_Object) {
// WIP // WIP
Ground.Flags.error = true; Ground.Flags.error = true;
Ground.Log.Error("[WIP] Cannot pass object to native function in Ground.New.NativeFunction()");
return gf; return gf;
} }
@@ -30,6 +32,7 @@ GroundFunction _GroundNewNativeFunction(void* function, size_t argc, ...) {
if (gf.args.count + 1 >= gf.args.capacity) { if (gf.args.count + 1 >= gf.args.capacity) {
GroundFunctionArg* tmp = realloc(gf.args.at, sizeof(GroundFunctionArg) * gf.args.capacity * 2); GroundFunctionArg* tmp = realloc(gf.args.at, sizeof(GroundFunctionArg) * gf.args.capacity * 2);
if (tmp == NULL) { if (tmp == NULL) {
Ground.Log.Error("malloc failed in Ground.New.NativeFunction()");
Ground.Flags.error = true; Ground.Flags.error = true;
return gf; return gf;
} }

View File

@@ -15,6 +15,7 @@ GroundObject _GroundNewObject(GroundStruct* in) {
item = malloc(sizeof(GroundObjectField)); item = malloc(sizeof(GroundObjectField));
if (item == NULL) { if (item == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Object()");
Ground.Flags.error = true; Ground.Flags.error = true;
return object; return object;
} }

View File

@@ -8,6 +8,7 @@ GroundProgram _GroundNewProgram() {
}; };
if (newProgram.at == NULL) { if (newProgram.at == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Program()");
Ground.Flags.error = true; Ground.Flags.error = true;
} }
return newProgram; return newProgram;

View File

@@ -10,6 +10,7 @@ GroundString _GroundNewString(const char* in) {
}; };
if (string.cstr == NULL) { if (string.cstr == NULL) {
Ground.Log.Error("malloc failed in Ground.New.String()");
Ground.Flags.error = true; Ground.Flags.error = true;
string.len = 0; string.len = 0;
return string; return string;

View File

@@ -4,6 +4,7 @@ void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction)
if (program->len + 1 >= program->capacity) { if (program->len + 1 >= program->capacity) {
GroundInstruction* tmp = realloc(program->at, sizeof(GroundInstruction) * program->capacity * 2); GroundInstruction* tmp = realloc(program->at, sizeof(GroundInstruction) * program->capacity * 2);
if (tmp == NULL) { if (tmp == NULL) {
Ground.Log.Error("malloc failed in Ground.Program.append()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

View File

@@ -1,5 +1,11 @@
#include "../../include/ground.h" #include "../../include/ground.h"
void _GroundProgramExecute(GroundProgram* program, GroundState* state) { void _GroundProgramExecute(GroundProgram* program, GroundState* state) {
// stub
// TODO:
// - Preprocess functions
// - Preprocess structs
// - Add them to state
Ground.Internal.run(program, state);
} }

12
src/State/findCatch.c Normal file
View File

@@ -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;
}

12
src/State/findLabel.c Normal file
View File

@@ -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;
}

12
src/State/findVariable.c Normal file
View File

@@ -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;
}

View File

@@ -13,12 +13,14 @@ void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value)
field = malloc(sizeof(GroundObjectField)); field = malloc(sizeof(GroundObjectField));
if (field == NULL) { if (field == NULL) {
Ground.Log.Error("malloc failed in Ground.Struct.addField()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }
field->value = malloc(sizeof(GroundValue)); field->value = malloc(sizeof(GroundValue));
if (field->value == NULL) { if (field->value == NULL) {
Ground.Log.Error("malloc failed in Ground.Struct.addField()");
Ground.Flags.error = true; Ground.Flags.error = true;
return; return;
} }

View File

@@ -70,6 +70,21 @@ void _GroundFunctionAppendArg(GroundFunction* function, const char* argName);
void _GroundStructAddField(GroundStruct* gs, const char* id, GroundValue value); 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 = { struct _Ground Ground = {
.Flags = { .Flags = {
@@ -157,4 +172,22 @@ struct _Ground Ground = {
.Struct = { .Struct = {
.addField = _GroundStructAddField, .addField = _GroundStructAddField,
}, },
.State = {
.findCatch = _GroundStateFindCatch,
.findLabel = _GroundStateFindLabel,
.findVariable = _GroundStateFindVariable,
},
.Internal = {
.run = _GroundInternalRun
},
.Log = {
.Error = _GroundLogError,
.Warning = _GroundLogWarning,
.printErrors = _GroundLogPrintErrors,
.errors = NULL,
.warnings = NULL,
},
}; };

BIN
test/test Executable file

Binary file not shown.

15
test/test.c Normal file
View File

@@ -0,0 +1,15 @@
#include <ground.h>
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");
}