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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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) {
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
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);
if (copy == NULL) {
Ground.Log.Error("malloc failed in Ground.New.Arg.DirectRef()");
Ground.Flags.error = true;
return (GroundArg) {
.type = GroundArg_DirectRef,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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