Initial commit

This commit is contained in:
2026-06-13 19:45:36 +10:00
commit 284b08b12a
56 changed files with 1546 additions and 0 deletions

2
.clangd Normal file
View File

@@ -0,0 +1,2 @@
CompileFlags:
Add: [-Iinclude]

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
builddir

8
README.md Normal file
View File

@@ -0,0 +1,8 @@
# Building
Install dependencies (uthash, libffi) then:
```sh
meson setup builddir
meson compile -C builddir
```

351
include/ground.h Normal file
View File

@@ -0,0 +1,351 @@
#ifndef GROUND_H
#define GROUND_H
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <uthash.h>
//
// 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

73
meson.build Normal file
View File

@@ -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)

10
src/Copy/Arg.c Normal file
View File

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

39
src/Copy/Function.c Normal file
View File

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

19
src/Copy/Instruction.c Normal file
View File

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

17
src/Copy/List.c Normal file
View File

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

35
src/Copy/Object.c Normal file
View File

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

17
src/Copy/Program.c Normal file
View File

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

68
src/Copy/State.c Normal file
View File

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

14
src/Copy/String.c Normal file
View File

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

33
src/Copy/Struct.c Normal file
View File

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

33
src/Copy/Value.c Normal file
View File

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

19
src/Free/Function.c Normal file
View File

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

9
src/Free/List.c Normal file
View File

@@ -0,0 +1,9 @@
#include "../../include/ground.h"
#include <stdlib.h>
void _GroundFreeList(GroundList* in) {
free(in->at);
in->capacity = 0;
in->count = 0;
}

15
src/Free/Object.c Normal file
View File

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

8
src/Free/String.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../include/ground.h"
#include <stdlib.h>
void _GroundFreeString(GroundString* in) {
free(in->cstr);
in->len = 0;
}

15
src/Free/Struct.c Normal file
View File

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

30
src/Free/Value.c Normal file
View File

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

29
src/Function/appendArg.c Normal file
View File

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

View File

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

17
src/Instruction/append.c Normal file
View File

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

View File

@@ -0,0 +1,5 @@
#include "../../include/ground.h"
void _GroundInstructionExecute(GroundInstruction* instruction, GroundState* state) {
// Stub
}

17
src/List/append.c Normal file
View File

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

24
src/New/Arg/DirectRef.c Normal file
View File

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

24
src/New/Arg/FunctionRef.c Normal file
View File

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

25
src/New/Arg/LabelRef.c Normal file
View File

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

24
src/New/Arg/LineRef.c Normal file
View File

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

25
src/New/Arg/TypeRef.c Normal file
View File

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

8
src/New/Arg/Value.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundArg _GroundNewArgValue(GroundValue value) {
return (GroundArg) {
.type = GroundArg_DirectRef,
.as.value = Ground.Copy.Value(&value)
};
}

25
src/New/Arg/ValueRef.c Normal file
View File

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

15
src/New/Error.c Normal file
View File

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

23
src/New/Function.c Normal file
View File

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

17
src/New/Instruction.c Normal file
View File

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

15
src/New/List.c Normal file
View File

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

49
src/New/NativeFunction.c Normal file
View File

@@ -0,0 +1,49 @@
#include "../../include/ground.h"
#include <ffi.h>
#include <stdarg.h>
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;
}

34
src/New/Object.c Normal file
View File

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

14
src/New/Program.c Normal file
View File

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

20
src/New/String.c Normal file
View File

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

7
src/New/Struct.c Normal file
View File

@@ -0,0 +1,7 @@
#include "../../include/ground.h"
GroundStruct _GroundNewStruct() {
return (GroundStruct) {
.fields = NULL
};
}

17
src/New/Type.c Normal file
View File

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

8
src/New/Value/Bool.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueBool(GroundBool in) {
return (GroundValue) {
.as.Bool = in,
.type = Ground.New.Type(GroundType_Bool)
};
}

8
src/New/Value/Char.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueChar(GroundChar in) {
return (GroundValue) {
.as.Char = in,
.type = Ground.New.Type(GroundType_Char)
};
}

8
src/New/Value/Double.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueDouble(GroundDouble in) {
return (GroundValue) {
.as.Double = in,
.type = Ground.New.Type(GroundType_Double)
};
}

8
src/New/Value/Function.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueFunction(GroundFunction in) {
return (GroundValue) {
.as.Function = in,
.type = Ground.New.Type(GroundType_Function)
};
}

8
src/New/Value/Int.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueInt(GroundInt in) {
return (GroundValue) {
.as.Int = in,
.type = Ground.New.Type(GroundType_Int)
};
}

8
src/New/Value/List.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueList(GroundList in) {
return (GroundValue) {
.as.List = in,
.type = Ground.New.Type(GroundType_List)
};
}

8
src/New/Value/Object.c Normal file
View File

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

9
src/New/Value/String.c Normal file
View File

@@ -0,0 +1,9 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueString(GroundString in) {
return (GroundValue) {
.as.String = in,
.type = Ground.New.Type(GroundType_String)
};
}

9
src/New/Value/Struct.c Normal file
View File

@@ -0,0 +1,9 @@
#include "../../../include/ground.h"
GroundValue _GroundNewValueStruct(GroundStruct in) {
return (GroundValue) {
.as.Struct = in,
.type = Ground.New.Type(GroundType_Struct)
};
}

17
src/Program/append.c Normal file
View File

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

5
src/Program/execute.c Normal file
View File

@@ -0,0 +1,5 @@
#include "../../include/ground.h"
void _GroundProgramExecute(GroundProgram* program, GroundState* state) {
// stub
}

31
src/Struct/addField.c Normal file
View File

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

160
src/libmain.c Normal file
View File

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