From c78426ef88480f26c0428804359e323323abc93d Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Thu, 2 Jul 2026 11:35:56 +1000 Subject: [PATCH] Misc stuff, probably crashes --- include/ground.h | 63 +++++++- meson.build | 6 + src/Bytecode/Heap/get.c | 2 +- src/Bytecode/Heap/set.c | 2 +- src/Bytecode/Instruction/execute.c | 232 ++++++++++++++--------------- src/Bytecode/load.c | 4 +- src/Bytecode/save.c | 2 +- src/Free/BytecodeValue.c | 33 ++++ src/New/Bytecode.c | 2 +- src/New/BytecodeValue.c | 50 +++++++ src/Program/execute.c | 17 ++- src/Program/preprocess.c | 113 ++++++++++++++ src/Stringify/BytecodeValue.c | 67 +++++++++ src/Stringify/Heap.c | 2 +- src/cli/main.c | 1 + src/libmain.c | 12 ++ 16 files changed, 474 insertions(+), 134 deletions(-) create mode 100644 src/Free/BytecodeValue.c create mode 100644 src/New/BytecodeValue.c create mode 100644 src/Program/preprocess.c create mode 100644 src/Stringify/BytecodeValue.c diff --git a/include/ground.h b/include/ground.h index 75f22f8..753a553 100644 --- a/include/ground.h +++ b/include/ground.h @@ -20,6 +20,12 @@ typedef struct GroundInstruction GroundInstruction; typedef struct GroundProgram GroundProgram; 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 GroundBytecodeInstruction GroundBytecodeInstruction; typedef struct GroundBytecodeHeap GroundBytecodeHeap; @@ -261,6 +267,49 @@ struct GroundIdentifier { 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 { GroundBytecodeInstruction* at; GroundSize capacity; @@ -277,7 +326,7 @@ struct GroundBytecodeInstruction { }; struct GroundBytecodeHeap { - GroundValue* heap; + GroundBytecodeValue* heap; GroundSize capacity; GroundSize len; }; @@ -340,7 +389,8 @@ struct _Ground { GroundIdentifier* (*Identifier) (const char* id); - GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state); + GroundBytecode (*Bytecode) (GroundProgram* program, GroundState* state); + GroundBytecodeValue (*BytecodeValue) (GroundValue value); } New; @@ -359,6 +409,8 @@ struct _Ground { void (*State) (GroundState* state); void (*Identifier) (GroundIdentifier* identifier); + + void (*BytecodeValue) (GroundBytecodeValue* value); } Free; // Creates a copy of the memory held by the specified struct @@ -388,8 +440,9 @@ struct _Ground { } Instruction; struct { - void (*append) (GroundProgram* program, GroundInstruction instruction); - void (*execute) (GroundProgram* program, GroundState* state); + void (*append) (GroundProgram* program, GroundInstruction instruction); + void (*execute) (GroundProgram* program, GroundState* state); + GroundProgram (*preprocess) (GroundProgram* program, GroundState* state); } Program; struct { @@ -447,6 +500,8 @@ struct _Ground { char* (*Program)(GroundProgram* program); char* (*String)(GroundString* string); char* (*Value)(GroundValue* value); + + char* (*BytecodeValue)(GroundBytecodeValue* value); } Stringify; }; diff --git a/meson.build b/meson.build index 5910251..e2bbb59 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,8 @@ sources = files( 'src/Free/Identifier.c', + 'src/Free/BytecodeValue.c', + 'src/Function/appendInstruction.c', 'src/Function/appendArg.c', @@ -74,6 +76,7 @@ sources = files( 'src/New/Identifier.c', 'src/New/Bytecode.c', + 'src/New/BytecodeValue.c', 'src/New/NativeFunction.c', @@ -93,6 +96,7 @@ sources = files( 'src/Program/append.c', 'src/Program/execute.c', + 'src/Program/preprocess.c', 'src/State/findCatch.c', 'src/State/findLabel.c', @@ -105,6 +109,8 @@ sources = files( 'src/Stringify/String.c', 'src/Stringify/Value.c', + 'src/Stringify/BytecodeValue.c', + 'src/Struct/addField.c', diff --git a/src/Bytecode/Heap/get.c b/src/Bytecode/Heap/get.c index e0faaca..937f815 100644 --- a/src/Bytecode/Heap/get.c +++ b/src/Bytecode/Heap/get.c @@ -1,5 +1,5 @@ #include "../../../include/ground.h" -GroundValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) { +GroundBytecodeValue* _GroundBytecodeHeapGet(GroundBytecodeHeap* heap, GroundSize idx) { return &heap->heap[idx]; } diff --git a/src/Bytecode/Heap/set.c b/src/Bytecode/Heap/set.c index f7ce37d..fa9e850 100644 --- a/src/Bytecode/Heap/set.c +++ b/src/Bytecode/Heap/set.c @@ -1,5 +1,5 @@ #include "../../../include/ground.h" -void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundValue value) { +void _GroundBytecodeHeapSet(GroundBytecodeHeap* heap, GroundSize idx, GroundBytecodeValue value) { heap->heap[idx] = value; } diff --git a/src/Bytecode/Instruction/execute.c b/src/Bytecode/Instruction/execute.c index 1c770ad..28db9bd 100644 --- a/src/Bytecode/Instruction/execute.c +++ b/src/Bytecode/Instruction/execute.c @@ -9,7 +9,7 @@ #define HEAP_GET(heap, idx) (&(heap)->heap[(idx)]) #define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val)) -static void printValue(GroundValue* val) { +static void printValue(GroundBytecodeValue* val) { switch (val->type.type) { case GroundType_Int: printf("%" PRId64, val->as.Int); @@ -53,7 +53,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction goto *jumpTable[instruction->type]; IF: { - GroundValue* cond = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* cond = HEAP_GET(heap, instruction->args.at[0]); if (cond->as.Bool) { return instruction->args.at[1]; } @@ -67,7 +67,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } INPUT: { 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); return -1; } @@ -118,19 +118,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } ADD: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { @@ -144,11 +144,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { @@ -170,7 +170,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction break; } 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; } default: { @@ -189,19 +189,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } SUBTRACT: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { @@ -215,11 +215,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { @@ -239,19 +239,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } MULTIPLY: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { @@ -265,11 +265,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { @@ -289,19 +289,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } DIVIDE: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { @@ -315,11 +315,11 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { @@ -339,23 +339,23 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } EQUAL: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } @@ -364,15 +364,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } @@ -380,53 +380,53 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } case 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 { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); } break; } case 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 { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); } break; } case 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 { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); } break; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } return -1; } INEQUAL: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } @@ -435,15 +435,15 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } @@ -451,57 +451,57 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } case 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 { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); } break; } case 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 { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); } break; } case 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 { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); } break; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } return -1; } 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; } GREATER: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } @@ -510,45 +510,45 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } break; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } return -1; } LESSER: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* right = HEAP_GET(heap, instruction->args.at[1]); switch (left->type.type) { case GroundType_Int: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } @@ -557,51 +557,51 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_Double: { switch (right->type.type) { 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; } 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; } default: { - *final = Ground.New.Value.Bool(true); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(true)); break; } } break; } default: { - *final = Ground.New.Value.Bool(false); + *final = Ground.New.BytecodeValue(Ground.New.Value.Bool(false)); break; } } return -1; } AND: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + 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; } OR: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + 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; } XOR: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[2]); - GroundValue* left = HEAP_GET(heap, instruction->args.at[0]); - GroundValue* right = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[2]); + GroundBytecodeValue* left = HEAP_GET(heap, instruction->args.at[0]); + 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; } @@ -612,12 +612,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } STOI: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]); 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) { Ground.Flags.error = true; @@ -627,12 +627,12 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } STOD: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]); 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) { Ground.Flags.error = true; @@ -642,24 +642,24 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } ITOC: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]); + 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; } CTOI: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]); + 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; } TOSTRING: { - GroundValue* final = HEAP_GET(heap, instruction->args.at[1]); - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); + GroundBytecodeValue* final = HEAP_GET(heap, instruction->args.at[1]); + GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]); char buf[4096]; @@ -681,7 +681,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction break; } case GroundType_String: { - *in = Ground.New.Value.String(final->as.String); + *in = Ground.New.BytecodeValue(Ground.New.Value.String(final->as.String)); 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; } @@ -744,9 +744,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } DROP: { - GroundValue* in = HEAP_GET(heap, instruction->args.at[0]); - Ground.Free.Value(in); - *in = Ground.New.Value.Int(0); + GroundBytecodeValue* in = HEAP_GET(heap, instruction->args.at[0]); + Ground.Free.BytecodeValue(in); + *in = Ground.New.BytecodeValue(Ground.New.Value.Int(0)); return -1; } LICENSE: { diff --git a/src/Bytecode/load.c b/src/Bytecode/load.c index aca5995..3b2f13e 100644 --- a/src/Bytecode/load.c +++ b/src/Bytecode/load.c @@ -2,8 +2,8 @@ #include #include -static GroundValue readValue(FILE* f) { - GroundValue v = {0}; +static GroundBytecodeValue readValue(FILE* f) { + GroundBytecodeValue v = {0}; uint8_t tag; if (fread(&tag, 1, 1, f) != 1) { Ground.Log.Error("failed to read value type in Ground.Bytecode.load"); diff --git a/src/Bytecode/save.c b/src/Bytecode/save.c index 2dc38bf..b92d2da 100644 --- a/src/Bytecode/save.c +++ b/src/Bytecode/save.c @@ -1,7 +1,7 @@ #include "../../include/ground.h" #include -static void writeValue(FILE* f, GroundValue* v) { +static void writeValue(FILE* f, GroundBytecodeValue* v) { switch (v->type.type) { case GroundType_Int: { uint8_t tag = 0; diff --git a/src/Free/BytecodeValue.c b/src/Free/BytecodeValue.c new file mode 100644 index 0000000..5cbb255 --- /dev/null +++ b/src/Free/BytecodeValue.c @@ -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; + } + } +} diff --git a/src/New/Bytecode.c b/src/New/Bytecode.c index eee7654..c8733d2 100644 --- a/src/New/Bytecode.c +++ b/src/New/Bytecode.c @@ -196,7 +196,7 @@ GroundBytecode _GroundNewBytecode(GroundProgram* program, GroundState* state) { // Copy constants into heap at their assigned offsets 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; } diff --git a/src/New/BytecodeValue.c b/src/New/BytecodeValue.c new file mode 100644 index 0000000..fa555c8 --- /dev/null +++ b/src/New/BytecodeValue.c @@ -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; +} diff --git a/src/Program/execute.c b/src/Program/execute.c index e869774..1c134e4 100644 --- a/src/Program/execute.c +++ b/src/Program/execute.c @@ -1,11 +1,14 @@ #include "../../include/ground.h" void _GroundProgramExecute(GroundProgram* program, GroundState* state) { - - // TODO: - // - Preprocess functions - // - Preprocess structs - // - Add them to state - - Ground.Internal.run(program, state); + // Preprocess program, then run + GroundProgram pp = Ground.Program.preprocess(program, state); + if (Ground.Flags.error) { + return; + } + Ground.Internal.run(&pp, state); + if (Ground.Flags.error) { + return; + } + Ground.Free.Program(&pp); } diff --git a/src/Program/preprocess.c b/src/Program/preprocess.c new file mode 100644 index 0000000..8583bfc --- /dev/null +++ b/src/Program/preprocess.c @@ -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; + +} diff --git a/src/Stringify/BytecodeValue.c b/src/Stringify/BytecodeValue.c new file mode 100644 index 0000000..a8e6deb --- /dev/null +++ b/src/Stringify/BytecodeValue.c @@ -0,0 +1,67 @@ +#include "../../include/ground.h" +#include + +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; +} diff --git a/src/Stringify/Heap.c b/src/Stringify/Heap.c index b4f384c..a026b92 100644 --- a/src/Stringify/Heap.c +++ b/src/Stringify/Heap.c @@ -7,7 +7,7 @@ char* _GroundStringifyHeap(GroundBytecodeHeap* heap) { Estr heapString = CREATE_ESTR(""); 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) { return NULL; } diff --git a/src/cli/main.c b/src/cli/main.c index 62eadd3..0312556 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -82,6 +82,7 @@ int main(int argc, char** argv) { } case ARGS_DISASSEMBLE: { fprintf(stderr, "Not yet implemented"); + break; } case ARGS_HELP: { diff --git a/src/libmain.c b/src/libmain.c index 0d4fd60..28645a5 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -33,6 +33,7 @@ GroundType _GroundNewType(enum GroundTypeType type, ...); GroundIdentifier* _GroundNewIdentifier(const char* id); GroundBytecode _GroundNewBytecode (GroundProgram* program, GroundState* state); +GroundBytecodeValue _GroundNewBytecodeValue(GroundValue value); void _GroundFreeValue(GroundValue* in); void _GroundFreeList(GroundList* in); @@ -48,6 +49,8 @@ void _GroundFreeState(GroundState* in); void _GroundFreeIdentifier(GroundIdentifier* identifier); +void _GroundFreeBytecodeValue(GroundBytecodeValue* in); + GroundValue _GroundCopyValue(GroundValue* in); GroundList _GroundCopyList(GroundList* in); @@ -73,6 +76,7 @@ int64_t _GroundInstructionExecute(GroundInstruction* instruction, GroundValue* h void _GroundProgramAppend(GroundProgram* program, GroundInstruction instruction); void _GroundProgramExecute(GroundProgram* program, GroundState* state); +GroundProgram _GroundProgramPreprocess(GroundProgram* program, GroundState* state); void _GroundFunctionAppendInstruction(GroundFunction* function, GroundInstruction instruction); @@ -114,6 +118,8 @@ char* _GroundStringifyProgram(GroundProgram* program); char* _GroundStringifyString(GroundString* string); char* _GroundStringifyValue(GroundValue* value); +char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value); + struct _Ground Ground = { @@ -158,6 +164,7 @@ struct _Ground Ground = { .Identifier = _GroundNewIdentifier, .Bytecode = _GroundNewBytecode, + .BytecodeValue = _GroundNewBytecodeValue, }, .Free = { @@ -174,6 +181,8 @@ struct _Ground Ground = { .State = _GroundFreeState, .Identifier = _GroundFreeIdentifier, + + .BytecodeValue = _GroundFreeBytecodeValue, }, .Copy = { @@ -204,6 +213,7 @@ struct _Ground Ground = { .Program = { .append = _GroundProgramAppend, .execute = _GroundProgramExecute, + .preprocess = _GroundProgramPreprocess, }, .Function = { @@ -256,5 +266,7 @@ struct _Ground Ground = { .Program = _GroundStringifyProgram, .String = _GroundStringifyString, .Value = _GroundStringifyValue, + + .BytecodeValue = _GroundStringifyBytecodeValue, }, };