cool stuff
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
23
meson.build
23
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',
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
7
src/Internal/giveUpAndCry.c
Normal file
7
src/Internal/giveUpAndCry.c
Normal 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
117
src/Internal/run.c
Normal 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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
16
src/Log/Error.c
Normal file
16
src/Log/Error.c
Normal 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
16
src/Log/Warning.c
Normal 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
16
src/Log/printErrors.c
Normal 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
GroundArg _GroundNewArgValue(GroundValue value) {
|
||||
return (GroundArg) {
|
||||
.type = GroundArg_DirectRef,
|
||||
.type = GroundArg_Value,
|
||||
.as.value = Ground.Copy.Value(&value)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
12
src/State/findCatch.c
Normal file
12
src/State/findCatch.c
Normal 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
12
src/State/findLabel.c
Normal 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
12
src/State/findVariable.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
15
test/test.c
Normal file
15
test/test.c
Normal 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");
|
||||
}
|
||||
Reference in New Issue
Block a user