Misc stuff, probably crashes

This commit is contained in:
2026-07-02 11:35:56 +10:00
parent 9bb083a6f8
commit c78426ef88
16 changed files with 474 additions and 134 deletions

View File

@@ -20,6 +20,12 @@ typedef struct GroundInstruction GroundInstruction;
typedef struct GroundProgram GroundProgram; typedef struct GroundProgram GroundProgram;
typedef struct GroundState GroundState; typedef struct GroundState GroundState;
typedef struct GroundBytecodeValue GroundBytecodeValue;
typedef struct GroundBytecodeList GroundBytecodeList;
typedef struct GroundBytecodeFunction GroundBytecodeFunction;
typedef struct GroundBytecodeStruct GroundBytecodeStruct;
typedef struct GroundBytecodeObject GroundBytecodeObject;
typedef struct GroundBytecodeError GroundBytecodeError;
typedef struct GroundBytecodeProgram GroundBytecodeProgram; typedef struct GroundBytecodeProgram GroundBytecodeProgram;
typedef struct GroundBytecodeInstruction GroundBytecodeInstruction; typedef struct GroundBytecodeInstruction GroundBytecodeInstruction;
typedef struct GroundBytecodeHeap GroundBytecodeHeap; typedef struct GroundBytecodeHeap GroundBytecodeHeap;
@@ -261,6 +267,49 @@ struct GroundIdentifier {
GroundSize referenceCount; GroundSize referenceCount;
}; };
struct GroundBytecodeList {
GroundSize capacity;
GroundSize count;
GroundBytecodeValue* at;
};
struct GroundBytecodeFunction {
struct {
GroundSize capacity;
GroundSize count;
GroundFunctionArg* at;
} args;
bool isNativeFunction;
union {
void* native;
GroundBytecodeProgram* ground;
} program;
GroundBytecodeHeap* closure;
GroundSize _requiredSize;
};
struct GroundBytecodeStruct {};
struct GroundBytecodeObject {};
struct GroundBytecodeValue {
union {
GroundInt Int;
GroundDouble Double;
GroundChar Char;
GroundBool Bool;
GroundString String;
GroundBytecodeList List;
GroundBytecodeFunction Function;
GroundBytecodeStruct Struct;
GroundBytecodeObject Object;
} as;
GroundType type;
};
struct GroundBytecodeProgram { struct GroundBytecodeProgram {
GroundBytecodeInstruction* at; GroundBytecodeInstruction* at;
GroundSize capacity; GroundSize capacity;
@@ -277,7 +326,7 @@ struct GroundBytecodeInstruction {
}; };
struct GroundBytecodeHeap { struct GroundBytecodeHeap {
GroundValue* heap; GroundBytecodeValue* heap;
GroundSize capacity; GroundSize capacity;
GroundSize len; GroundSize len;
}; };
@@ -340,7 +389,8 @@ struct _Ground {
GroundIdentifier* (*Identifier) (const char* id); GroundIdentifier* (*Identifier) (const char* id);
GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state); GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state);
GroundBytecodeValue (*BytecodeValue) (GroundValue value);
} New; } New;
@@ -359,6 +409,8 @@ struct _Ground {
void (*State) (GroundState* state); void (*State) (GroundState* state);
void (*Identifier) (GroundIdentifier* identifier); void (*Identifier) (GroundIdentifier* identifier);
void (*BytecodeValue) (GroundBytecodeValue* value);
} Free; } Free;
// Creates a copy of the memory held by the specified struct // Creates a copy of the memory held by the specified struct
@@ -388,8 +440,9 @@ struct _Ground {
} Instruction; } Instruction;
struct { struct {
void (*append) (GroundProgram* program, GroundInstruction instruction); void (*append) (GroundProgram* program, GroundInstruction instruction);
void (*execute) (GroundProgram* program, GroundState* state); void (*execute) (GroundProgram* program, GroundState* state);
GroundProgram (*preprocess) (GroundProgram* program, GroundState* state);
} Program; } Program;
struct { struct {
@@ -447,6 +500,8 @@ struct _Ground {
char* (*Program)(GroundProgram* program); char* (*Program)(GroundProgram* program);
char* (*String)(GroundString* string); char* (*String)(GroundString* string);
char* (*Value)(GroundValue* value); char* (*Value)(GroundValue* value);
char* (*BytecodeValue)(GroundBytecodeValue* value);
} Stringify; } Stringify;
}; };

View File

@@ -39,6 +39,8 @@ sources = files(
'src/Free/Identifier.c', 'src/Free/Identifier.c',
'src/Free/BytecodeValue.c',
'src/Function/appendInstruction.c', 'src/Function/appendInstruction.c',
'src/Function/appendArg.c', 'src/Function/appendArg.c',
@@ -74,6 +76,7 @@ sources = files(
'src/New/Identifier.c', 'src/New/Identifier.c',
'src/New/Bytecode.c', 'src/New/Bytecode.c',
'src/New/BytecodeValue.c',
'src/New/NativeFunction.c', 'src/New/NativeFunction.c',
@@ -93,6 +96,7 @@ sources = files(
'src/Program/append.c', 'src/Program/append.c',
'src/Program/execute.c', 'src/Program/execute.c',
'src/Program/preprocess.c',
'src/State/findCatch.c', 'src/State/findCatch.c',
'src/State/findLabel.c', 'src/State/findLabel.c',
@@ -105,6 +109,8 @@ sources = files(
'src/Stringify/String.c', 'src/Stringify/String.c',
'src/Stringify/Value.c', 'src/Stringify/Value.c',
'src/Stringify/BytecodeValue.c',
'src/Struct/addField.c', 'src/Struct/addField.c',

View File

@@ -1,5 +1,5 @@
#include "../../../include/ground.h" #include "../../../include/ground.h"
GroundValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) { GroundBytecodeValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) {
return &heap->heap[idx]; return &heap->heap[idx];
} }

View File

@@ -1,5 +1,5 @@
#include "../../../include/ground.h" #include "../../../include/ground.h"
void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundValue value) { void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundBytecodeValue value) {
heap->heap[idx] = value; heap->heap[idx] = value;
} }

View File

@@ -9,7 +9,7 @@
#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)]) #define HEAP_GET(heap, idx) (&(heap)->heap[(idx)])
#define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val)) #define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val))
static void printValue(GroundValue* val) { static void printValue(GroundBytecodeValue* val) {
switch (val->type.type) { switch (val->type.type) {
case GroundType_Int: case GroundType_Int:
printf("%" PRId64, val->as.Int); printf("%" PRId64, val->as.Int);
@@ -53,7 +53,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
goto *jumpTable[instruction->type]; goto *jumpTable[instruction->type];
IF: { IF: {
GroundValue* cond = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]);
if (cond->as.Bool) { if (cond->as.Bool) {
return instruction->args.at[1]; return instruction->args.at[1];
} }
@@ -67,7 +67,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
} }
INPUT: { INPUT: {
char* input = linenoise(""); char* input = linenoise("");
HEAP_SET(heap, instruction->args.at[0], Ground.New.Value.String(Ground.New.String(input))); HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input))));
free(input); free(input);
return -1; return -1;
} }
@@ -118,19 +118,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
ADD: { ADD: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int + right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int + right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int + right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int + right->as.Double));
break; break;
} }
default: { default: {
@@ -144,11 +144,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double + right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double + right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double + right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double + right->as.Double));
break; break;
} }
default: { default: {
@@ -170,7 +170,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
break; break;
} }
sprintf(buf, "%s%s", left->as.String.cstr, right->as.String.cstr); sprintf(buf, "%s%s", left->as.String.cstr, right->as.String.cstr);
*final = Ground.New.Value.String(Ground.New.String(buf)); *final = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
break; break;
} }
default: { default: {
@@ -189,19 +189,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
SUBTRACT: { SUBTRACT: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int - right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int - right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int - right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int - right->as.Double));
break; break;
} }
default: { default: {
@@ -215,11 +215,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double - right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double - right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double - right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double - right->as.Double));
break; break;
} }
default: { default: {
@@ -239,19 +239,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
MULTIPLY: { MULTIPLY: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int * right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int * right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int * right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int * right->as.Double));
break; break;
} }
default: { default: {
@@ -265,11 +265,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double * right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double * right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double * right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double * right->as.Double));
break; break;
} }
default: { default: {
@@ -289,19 +289,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
DIVIDE: { DIVIDE: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Int(left->as.Int / right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Int(left->as.Int / right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Int / right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Int / right->as.Double));
break; break;
} }
default: { default: {
@@ -315,11 +315,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Double(left->as.Double / right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double / right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Double(left->as.Double / right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(left->as.Double / right->as.Double));
break; break;
} }
default: { default: {
@@ -339,23 +339,23 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
EQUAL: { EQUAL: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int == right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int == right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int == right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int == right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
@@ -364,15 +364,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double == right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double == right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double == right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double == right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
@@ -380,53 +380,53 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
} }
case GroundType_Char: { case GroundType_Char: {
if (right->type.type == GroundType_Char) { if (right->type.type == GroundType_Char) {
*final = Ground.New.Value.Bool(left->as.Char == right->as.Char); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Char == right->as.Char));
} else { } else {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
} }
break; break;
} }
case GroundType_Bool: { case GroundType_Bool: {
if (right->type.type == GroundType_Bool) { if (right->type.type == GroundType_Bool) {
*final = Ground.New.Value.Bool(left->as.Bool == right->as.Bool); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool == right->as.Bool));
} else { } else {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
} }
break; break;
} }
case GroundType_String: { case GroundType_String: {
if (right->type.type == GroundType_String) { if (right->type.type == GroundType_String) {
*final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) == 0); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) == 0));
} else { } else {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
} }
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
return -1; return -1;
} }
INEQUAL: { INEQUAL: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int != right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int != right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int != right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int != right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
@@ -435,15 +435,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double != right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double != right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double != right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double != right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
@@ -451,57 +451,57 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
} }
case GroundType_Char: { case GroundType_Char: {
if (right->type.type == GroundType_Char) { if (right->type.type == GroundType_Char) {
*final = Ground.New.Value.Bool(left->as.Char != right->as.Char); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Char != right->as.Char));
} else { } else {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
} }
break; break;
} }
case GroundType_Bool: { case GroundType_Bool: {
if (right->type.type == GroundType_Bool) { if (right->type.type == GroundType_Bool) {
*final = Ground.New.Value.Bool(left->as.Bool != right->as.Bool); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool != right->as.Bool));
} else { } else {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
} }
break; break;
} }
case GroundType_String: { case GroundType_String: {
if (right->type.type == GroundType_String) { if (right->type.type == GroundType_String) {
*final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) != 0); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) != 0));
} else { } else {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
} }
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
return -1; return -1;
} }
NOT: { NOT: {
HEAP_SET(heap, instruction->args.at[1], Ground.New.Value.Bool(!HEAP_GET(heap, instruction->args.at[0])->as.Bool)); HEAP_SET(heap, instruction->args.at[1], Ground.New.BytecodeValue(Ground.New.Value.Bool(!HEAP_GET(heap, instruction->args.at[0])->as.Bool)));
return -1; return -1;
} }
GREATER: { GREATER: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int > right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int > right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int > right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int > right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
@@ -510,45 +510,45 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double > right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double > right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double > right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double > right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
return -1; return -1;
} }
LESSER: { LESSER: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
switch (left->type.type) { switch (left->type.type) {
case GroundType_Int: { case GroundType_Int: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Int < right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int < right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Int < right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Int < right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
@@ -557,51 +557,51 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
case GroundType_Double: { case GroundType_Double: {
switch (right->type.type) { switch (right->type.type) {
case GroundType_Int: { case GroundType_Int: {
*final = Ground.New.Value.Bool(left->as.Double < right->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double < right->as.Int));
break; break;
} }
case GroundType_Double: { case GroundType_Double: {
*final = Ground.New.Value.Bool(left->as.Double < right->as.Double); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Double < right->as.Double));
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(true); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true));
break; break;
} }
} }
break; break;
} }
default: { default: {
*final = Ground.New.Value.Bool(false); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break; break;
} }
} }
return -1; return -1;
} }
AND: { AND: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool && right->as.Bool); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool && right->as.Bool));
return -1; return -1;
} }
OR: { OR: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool || right->as.Bool); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool || right->as.Bool));
return -1; return -1;
} }
XOR: { XOR: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]);
GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]);
GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]);
*final = Ground.New.Value.Bool(left->as.Bool != right->as.Bool); *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(left->as.Bool != right->as.Bool));
return -1; return -1;
} }
@@ -612,12 +612,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
STOI: { STOI: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
char* status = NULL; char* status = NULL;
*final = Ground.New.Value.Int(strtoll(in->as.String.cstr, &status, 0)); *final = Ground.New.BytecodeValue(Ground.New.Value.Int(strtoll(in->as.String.cstr, &status, 0)));
if (status != in->as.String.cstr) { if (status != in->as.String.cstr) {
Ground.Flags.error = true; Ground.Flags.error = true;
@@ -627,12 +627,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
STOD: { STOD: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
char* status = NULL; char* status = NULL;
*final = Ground.New.Value.Double(strtod(in->as.String.cstr, &status)); *final = Ground.New.BytecodeValue(Ground.New.Value.Double(strtod(in->as.String.cstr, &status)));
if (status != in->as.String.cstr) { if (status != in->as.String.cstr) {
Ground.Flags.error = true; Ground.Flags.error = true;
@@ -642,24 +642,24 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
ITOC: { ITOC: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
*final = Ground.New.Value.Char((char)in->as.Int); *final = Ground.New.BytecodeValue(Ground.New.Value.Char((char)in->as.Int));
return -1; return -1;
} }
CTOI: { CTOI: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
*final = Ground.New.Value.Int((int64_t)in->as.Char); *final = Ground.New.BytecodeValue(Ground.New.Value.Int((int64_t)in->as.Char));
return -1; return -1;
} }
TOSTRING: { TOSTRING: {
GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]);
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
char buf[4096]; char buf[4096];
@@ -681,7 +681,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
break; break;
} }
case GroundType_String: { case GroundType_String: {
*in = Ground.New.Value.String(final->as.String); *in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String));
return -1; return -1;
} }
@@ -692,7 +692,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
} }
} }
*in = Ground.New.Value.String(Ground.New.String(buf)); *in = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(buf)));
return -1; return -1;
} }
@@ -744,9 +744,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction
return -1; return -1;
} }
DROP: { DROP: {
GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]);
Ground.Free.Value(in); Ground.Free.BytecodeValue(in);
*in = Ground.New.Value.Int(0); *in = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
return -1; return -1;
} }
LICENSE: { LICENSE: {

View File

@@ -2,8 +2,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static GroundValue readValue(FILE* f) { static GroundBytecodeValue readValue(FILE* f) {
GroundValue v = {0}; GroundBytecodeValue v = {0};
uint8_t tag; uint8_t tag;
if (fread(&tag, 1, 1, f) != 1) { if (fread(&tag, 1, 1, f) != 1) {
Ground.Log.Error("failed to read value type in Ground.Bytecode.load"); Ground.Log.Error("failed to read value type in Ground.Bytecode.load");

View File

@@ -1,7 +1,7 @@
#include "../../include/ground.h" #include "../../include/ground.h"
#include <stdio.h> #include <stdio.h>
static void writeValue(FILE* f, GroundValue* v) { static void writeValue(FILE* f, GroundBytecodeValue* v) {
switch (v->type.type) { switch (v->type.type) {
case GroundType_Int: { case GroundType_Int: {
uint8_t tag = 0; uint8_t tag = 0;

33
src/Free/BytecodeValue.c Normal file
View File

@@ -0,0 +1,33 @@
#include "../../include/ground.h"
void _GroundFreeBytecodeValue(GroundBytecodeValue* in) {
// TODO: Implement all this
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;
}
}
}

View File

@@ -196,7 +196,7 @@ GroundBytecode _GroundNewBytecode(GroundProgram* program, GroundState* state) {
// Copy constants into heap at their assigned offsets // Copy constants into heap at their assigned offsets
HASH_ITER(hh, state->variables, s, tmp) { HASH_ITER(hh, state->variables, s, tmp) {
bytecode.heap.heap[s->_offset] = Ground.Copy.Value(&s->value); bytecode.heap.heap[s->_offset] = Ground.New.BytecodeValue(Ground.Copy.Value(&s->value));
if (Ground.Flags.error) return bytecode; if (Ground.Flags.error) return bytecode;
} }

50
src/New/BytecodeValue.c Normal file
View File

@@ -0,0 +1,50 @@
#include "../../include/ground.h"
GroundBytecodeValue _GroundNewBytecodeValue(GroundValue value) {
GroundBytecodeValue bv = {
.type = value.type
};
switch (value.type.type) {
// Literal values, no need for compilcated copy
case GroundType_Int: {
bv.as.Int = value.as.Int;
break;
}
case GroundType_Double: {
bv.as.Double = value.as.Double;
break;
}
case GroundType_Bool: {
bv.as.Bool = value.as.Bool;
break;
}
case GroundType_Char: {
bv.as.Char = value.as.Char;
break;
}
case GroundType_String: {
bv.as.String = Ground.Copy.String(&value.as.String);
break;
}
case GroundType_Function: {
// TODO - convert to bytecode function
break;
}
case GroundType_List: {
// TODO - convert to bytecode list
break;
}
case GroundType_Struct: {
// TODO - convert to bytecode struct
break;
}
case GroundType_Object: {
// TODO - convert to bytecode object
break;
}
}
return bv;
}

View File

@@ -1,11 +1,14 @@
#include "../../include/ground.h" #include "../../include/ground.h"
void _GroundProgramExecute(GroundProgram* program, GroundState* state) { void _GroundProgramExecute(GroundProgram* program, GroundState* state) {
// Preprocess program, then run
// TODO: GroundProgram pp = Ground.Program.preprocess(program, state);
// - Preprocess functions if (Ground.Flags.error) {
// - Preprocess structs return;
// - Add them to state }
Ground.Internal.run(&pp, state);
Ground.Internal.run(program, state); if (Ground.Flags.error) {
return;
}
Ground.Free.Program(&pp);
} }

113
src/Program/preprocess.c Normal file
View File

@@ -0,0 +1,113 @@
#include "../../include/ground.h"
GroundProgram _GroundProgramPreprocess(GroundProgram* program, GroundState* state) {
GroundProgram newProgram = Ground.New.Program();
for (GroundSize i = 0; i < program->len; i++) {
switch (program->at[i].type) {
case GroundInstruction_FUN: {
GroundFunction function = Ground.New.Function(state);
// Parse signature
GroundInstruction* sig = &program->at[i];
char* id = sig->args.at[0].as.ref->string;
for (GroundSize j = 1; i < sig->args.len - 1; i++) {
GroundArg* arg = &sig->args.at[j];
// Ignore type annotations, this can be taken care of in another function
if (arg->type == GroundArg_TypeRef) {
continue;
}
char* argId = arg->as.ref->string;
Ground.Function.appendArg(&function, argId);
}
// Add instructions to function
GroundSize funCount = 1;
GroundSize structCount = 0;
for (;;) {
i++;
if (i >= program->len) {
Ground.Flags.error = true;
Ground.Log.Error("expecting ENDFUN instruction, reached end of program in Ground.Program.Preprocess");
return newProgram;
}
GroundInstruction* inst = &program->at[i];
switch (inst->type) {
case GroundInstruction_FUN: {
funCount++;
break;
}
case GroundInstruction_ENDFUN: {
if (funCount < 1) {
Ground.Flags.error = true;
Ground.Log.Error("extra ENDFUN instruction (expecting ENDSTRUCT before) in Ground.Program.Preprocess");
return newProgram;
}
funCount--;
break;
}
case GroundInstruction_STRUCT: {
structCount++;
break;
}
case GroundInstruction_ENDSTRUCT: {
if (structCount < 1) {
Ground.Flags.error = true;
Ground.Log.Error("extra ENDSTRUCT instruction (expecting ENDFUN before) in Ground.Program.Preprocess");
return newProgram;
}
structCount--;
break;
}
default: break;
}
if (funCount == 0 && structCount == 0) {
// We done
break;
}
Ground.Function.appendInstruction(&function, *inst);
}
// Preprocess function's body
GroundProgram functionBody = Ground.Program.preprocess(function.program.ground, function.closure);
if (Ground.Flags.error) {
return newProgram;
}
Ground.Free.Program(function.program.ground);
*function.program.ground = functionBody;
GroundVariable* var = malloc(sizeof(GroundVariable));
if (var == NULL) {
Ground.Flags.error = true;
Ground.Log.Error("malloc failed in Ground.Program.Preprocess");
return newProgram;
}
snprintf(var->name, 2047, "%s", id);
var->value = Ground.New.Value.Function(function);
HASH_ADD_STR(state->variables, name, var);
break;
}
case GroundInstruction_STRUCT: {
// TODO: Preprocess structs
break;
}
default: {
Ground.Program.append(&newProgram, program->at[i]);
}
}
}
return newProgram;
}

View File

@@ -0,0 +1,67 @@
#include "../../include/ground.h"
#include <inttypes.h>
char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value) {
switch (value->type.type) {
case GroundType_Int: {
char* buf = malloc(snprintf(NULL, 0, "%" PRId64, value->as.Int) + 1);
if (buf == NULL) {
Ground.Flags.error = true;
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
return NULL;
}
sprintf(buf, "%" PRId64, value->as.Int);
return buf;
}
case GroundType_Double: {
char* buf = malloc(snprintf(NULL, 0, "%f", value->as.Double) + 1);
if (buf == NULL) {
Ground.Flags.error = true;
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
return NULL;
}
sprintf(buf, "%f", value->as.Double);
return buf;
}
case GroundType_Char: {
char* buf = malloc(snprintf(NULL, 0, "%c", value->as.Char) + 1);
if (buf == NULL) {
Ground.Flags.error = true;
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
return NULL;
}
sprintf(buf, "%c", value->as.Char);
return buf;
}
case GroundType_Bool: {
char* buf = malloc(6); // max(len(true), len(false)) + 1
if (buf == NULL) {
Ground.Flags.error = true;
Ground.Log.Error("malloc failed in Ground.Stringify.Value");
return NULL;
}
sprintf(buf, value->as.Bool ? "true" : "false");
return buf;
}
case GroundType_String: {
return Ground.Stringify.String(&value->as.String);
}
case GroundType_List: {
// TODO implement list stringification
}
case GroundType_Function: {
// TODO implement function stringification
}
case GroundType_Struct: {
// TODO implement struct stringification
}
case GroundType_Object: {
// TODO implement object stringification
}
}
Ground.Flags.error = true;
Ground.Log.Error("FIXME implement all cases in Ground.Stringify.Value");
return NULL;
}

View File

@@ -7,7 +7,7 @@ char* _GroundStringifyHeap(GroundBytecodeHeap* heap) {
Estr heapString = CREATE_ESTR(""); Estr heapString = CREATE_ESTR("");
for (GroundSize i = 0; i < heap->len; i++) { for (GroundSize i = 0; i < heap->len; i++) {
char* string = Ground.Stringify.Value(&heap->heap[i]); char* string = Ground.Stringify.BytecodeValue(&heap->heap[i]);
if (Ground.Flags.error) { if (Ground.Flags.error) {
return NULL; return NULL;
} }

View File

@@ -82,6 +82,7 @@ int main(int argc, char** argv) {
} }
case ARGS_DISASSEMBLE: { case ARGS_DISASSEMBLE: {
fprintf(stderr, "Not yet implemented"); fprintf(stderr, "Not yet implemented");
break; break;
} }
case ARGS_HELP: { case ARGS_HELP: {

View File

@@ -33,6 +33,7 @@ GroundType _GroundNewType(enum GroundTypeType type, ...);
GroundIdentifier* _GroundNewIdentifier(const char* id); GroundIdentifier* _GroundNewIdentifier(const char* id);
GroundBytecode _GroundNewBytecode (GroundProgram* program, GroundState* state); GroundBytecode _GroundNewBytecode (GroundProgram* program, GroundState* state);
GroundBytecodeValue _GroundNewBytecodeValue(GroundValue value);
void _GroundFreeValue(GroundValue* in); void _GroundFreeValue(GroundValue* in);
void _GroundFreeList(GroundList* in); void _GroundFreeList(GroundList* in);
@@ -48,6 +49,8 @@ void _GroundFreeState(GroundState* in);
void _GroundFreeIdentifier(GroundIdentifier* identifier); void _GroundFreeIdentifier(GroundIdentifier* identifier);
void _GroundFreeBytecodeValue(GroundBytecodeValue* in);
GroundValue _GroundCopyValue(GroundValue* in); GroundValue _GroundCopyValue(GroundValue* in);
GroundList _GroundCopyList(GroundList* in); GroundList _GroundCopyList(GroundList* in);
@@ -73,6 +76,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h
void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction); void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction);
void _GroundProgramExecute(GroundProgram* program, GroundState* state); void _GroundProgramExecute(GroundProgram* program, GroundState* state);
GroundProgram _GroundProgramPreprocess(GroundProgram* program, GroundState* state);
void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction); void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction);
@@ -114,6 +118,8 @@ char* _GroundStringifyProgram(GroundProgram* program);
char* _GroundStringifyString(GroundString* string); char* _GroundStringifyString(GroundString* string);
char* _GroundStringifyValue(GroundValue* value); char* _GroundStringifyValue(GroundValue* value);
char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value);
struct _Ground Ground = { struct _Ground Ground = {
@@ -158,6 +164,7 @@ struct _Ground Ground = {
.Identifier = _GroundNewIdentifier, .Identifier = _GroundNewIdentifier,
.Bytecode = _GroundNewBytecode, .Bytecode = _GroundNewBytecode,
.BytecodeValue = _GroundNewBytecodeValue,
}, },
.Free = { .Free = {
@@ -174,6 +181,8 @@ struct _Ground Ground = {
.State = _GroundFreeState, .State = _GroundFreeState,
.Identifier = _GroundFreeIdentifier, .Identifier = _GroundFreeIdentifier,
.BytecodeValue = _GroundFreeBytecodeValue,
}, },
.Copy = { .Copy = {
@@ -204,6 +213,7 @@ struct _Ground Ground = {
.Program = { .Program = {
.append = _GroundProgramAppend, .append = _GroundProgramAppend,
.execute = _GroundProgramExecute, .execute = _GroundProgramExecute,
.preprocess = _GroundProgramPreprocess,
}, },
.Function = { .Function = {
@@ -256,5 +266,7 @@ struct _Ground Ground = {
.Program = _GroundStringifyProgram, .Program = _GroundStringifyProgram,
.String = _GroundStringifyString, .String = _GroundStringifyString,
.Value = _GroundStringifyValue, .Value = _GroundStringifyValue,
.BytecodeValue = _GroundStringifyBytecodeValue,
}, },
}; };