diff --git a/src/Bytecode/Instruction/execute.c b/src/Bytecode/Instruction/execute.c index 10f4224..26e8220 100644 --- a/src/Bytecode/Instruction/execute.c +++ b/src/Bytecode/Instruction/execute.c @@ -1,6 +1,33 @@ #include "../../../include/ground.h" #include #include +#include + +#define HEAP_GET(heap, idx) (&(heap)->heap[(idx)]) +#define HEAP_SET(heap, idx, val) ((heap)->heap[(idx)] = (val)) + +static void printValue(GroundValue* val) { + switch (val->type.type) { + case GroundType_Int: + printf("%" PRId64, val->as.Int); + break; + case GroundType_Double: + printf("%f", val->as.Double); + break; + case GroundType_Bool: + printf(val->as.Bool ? "true" : "false"); + break; + case GroundType_Char: + printf("%c", val->as.Char); + break; + case GroundType_String: + printf("%s", val->as.String.cstr); + break; + default: + printf(""); + break; + } +} int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction, GroundBytecodeHeap* heap) { @@ -20,11 +47,10 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction &&PAUSE, &&DROP, &&LICENSE, &&ERRORCMD, &&THROW, &&CATCH }; - // Jump to the spot goto *jumpTable[instruction->type]; IF: { - GroundValue* cond = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); + GroundValue* cond = HEAP_GET(heap, instruction->args.at[0]); if (cond->as.Bool) { return instruction->args.at[1]; } @@ -41,69 +67,19 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } PRINT: { for (GroundSize i = 0; i < instruction->args.len; i++) { - GroundValue* val = Ground.Bytecode.Heap.get(heap, instruction->args.at[i]); - switch (val->type.type) { - case GroundType_Int: - printf("%" PRId64, val->as.Int); - break; - - case GroundType_Double: - printf("%f", val->as.Double); - break; - - case GroundType_Bool: - printf(val->as.Bool ? "true" : "false"); - break; - - case GroundType_Char: - printf("%c", val->as.Char); - break; - - case GroundType_String: - printf("%s", val->as.String.cstr); - break; - - default: - printf(""); - break; - } + printValue(HEAP_GET(heap, instruction->args.at[i])); } return -1; } PRINTLN: { for (GroundSize i = 0; i < instruction->args.len; i++) { - GroundValue* val = Ground.Bytecode.Heap.get(heap, instruction->args.at[i]); - switch (val->type.type) { - case GroundType_Int: - printf("%" PRId64, val->as.Int); - break; - - case GroundType_Double: - printf("%f", val->as.Double); - break; - - case GroundType_Bool: - printf(val->as.Bool ? "true" : "false"); - break; - - case GroundType_Char: - printf("%c", val->as.Char); - break; - - case GroundType_String: - printf("%s", val->as.String.cstr); - break; - - default: - printf(""); - break; - } + printValue(HEAP_GET(heap, instruction->args.at[i])); } printf("\n"); return -1; } SET: { - Ground.Bytecode.Heap.set(heap, instruction->args.at[0], *Ground.Bytecode.Heap.get(heap, instruction->args.at[1])); + HEAP_SET(heap, instruction->args.at[0], *HEAP_GET(heap, instruction->args.at[1])); return -1; } GETTYPE: { @@ -136,9 +112,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } ADD: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -180,7 +156,8 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction case GroundType_String: { switch (right->type.type) { case GroundType_String: { - char* buf = malloc(sizeof(char) * (left->as.String.len + right->as.String.len + 1)); + GroundSize total = left->as.String.len + right->as.String.len; + char* buf = malloc(total + 1); if (buf == NULL) { Ground.Log.Error("malloc failed (instruction ADD{string, string, dirref}) in Ground.Instruction.execute()"); Ground.Flags.error = true; @@ -206,9 +183,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } SUBTRACT: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -256,9 +233,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } MULTIPLY: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -306,9 +283,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } DIVIDE: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -356,9 +333,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } EQUAL: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -413,14 +390,13 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } case GroundType_String: { if (right->type.type == GroundType_String) { - *final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr)); + *final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) == 0); } else { *final = Ground.New.Value.Bool(false); } break; } default: { - // FIXME implement for complex types *final = Ground.New.Value.Bool(false); break; } @@ -428,9 +404,9 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } INEQUAL: { - GroundValue* final = Ground.Bytecode.Heap.get(heap, instruction->args.at[2]); - GroundValue* left = Ground.Bytecode.Heap.get(heap, instruction->args.at[0]); - GroundValue* right = Ground.Bytecode.Heap.get(heap, instruction->args.at[1]); + 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]); switch (left->type.type) { case GroundType_Int: { @@ -485,14 +461,13 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction } case GroundType_String: { if (right->type.type == GroundType_String) { - *final = Ground.New.Value.Bool(!strcmp(left->as.String.cstr, right->as.String.cstr)); + *final = Ground.New.Value.Bool(strcmp(left->as.String.cstr, right->as.String.cstr) != 0); } else { *final = Ground.New.Value.Bool(true); } break; } default: { - // FIXME implement for complex types *final = Ground.New.Value.Bool(false); break; } @@ -500,7 +475,7 @@ int64_t _GroundBytecodeInstructionExecute(GroundBytecodeInstruction* instruction return -1; } NOT: { - Ground.Bytecode.Heap.set(heap, instruction->args.at[1], Ground.New.Value.Bool(!Ground.Bytecode.Heap.get(heap, instruction->args.at[0])->as.Bool)); + HEAP_SET(heap, instruction->args.at[1], Ground.New.Value.Bool(!HEAP_GET(heap, instruction->args.at[0])->as.Bool)); return -1; } GREATER: { diff --git a/src/Bytecode/Program/execute.c b/src/Bytecode/Program/execute.c index eb0a10a..c7e5ac6 100644 --- a/src/Bytecode/Program/execute.c +++ b/src/Bytecode/Program/execute.c @@ -2,14 +2,15 @@ #include void _GroundBytecodeProgramExecute(GroundBytecodeProgram* program, GroundBytecodeHeap* heap) { - for (GroundSize i = 0; i < program->len; i++) { + GroundSize i = 0; + while (i < program->len) { int64_t status = Ground.Bytecode.Instruction.execute(&program->at[i], heap); if (Ground.Flags.error) { return; } switch (status) { - case -1: break; + case -1: i++; break; case -2: return; default: i = status; break; } diff --git a/src/Bytecode/Program/optimise.c b/src/Bytecode/Program/optimise.c index 9df305f..371cddf 100644 --- a/src/Bytecode/Program/optimise.c +++ b/src/Bytecode/Program/optimise.c @@ -1,5 +1,16 @@ #include "../../../include/ground.h" void _GroundBytecodeProgramOptimise(GroundBytecodeProgram* program) { - // TODO: Implement optimisation + + for (GroundSize i = 0; i < program->len; i++) { + if (program->at[i].type == GroundInstruction_JUMP) { + GroundSize target = program->at[i].args.at[0]; + + while (target < program->len && program->at[target].type == GroundInstruction_JUMP) { + target = program->at[target].args.at[0]; + } + + program->at[i].args.at[0] = target; + } + } } diff --git a/src/Copy/Object.c b/src/Copy/Object.c index c59cef2..a384a57 100644 --- a/src/Copy/Object.c +++ b/src/Copy/Object.c @@ -21,7 +21,14 @@ GroundObject _GroundCopyObject(GroundObject* in) { } strncpy(item->name, s->name, 2047); - + + item->value = malloc(sizeof(GroundValue)); + if (item->value == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Object()"); + Ground.Flags.error = true; + return object; + } + *item->value = Ground.Copy.Value(s->value); if (Ground.Flags.error) { diff --git a/src/Copy/State.c b/src/Copy/State.c index bad1ae6..4f26281 100644 --- a/src/Copy/State.c +++ b/src/Copy/State.c @@ -33,7 +33,7 @@ GroundState _GroundCopyState(GroundState* in) { GroundLabel *s, *tmp, *new; HASH_ITER(hh, in->labels, s, tmp) { - new = malloc(sizeof(GroundVariable)); + new = malloc(sizeof(GroundLabel)); if (new == NULL) { Ground.Log.Error("malloc failed in Ground.Copy.State()"); Ground.Flags.error = true; @@ -52,7 +52,7 @@ GroundState _GroundCopyState(GroundState* in) { GroundCatch *s, *tmp, *new; HASH_ITER(hh, in->catches, s, tmp) { - new = malloc(sizeof(GroundVariable)); + new = malloc(sizeof(GroundCatch)); if (new == NULL) { Ground.Log.Error("malloc failed in Ground.Copy.State()"); Ground.Flags.error = true; diff --git a/src/Copy/String.c b/src/Copy/String.c index 95b1598..d42446a 100644 --- a/src/Copy/String.c +++ b/src/Copy/String.c @@ -3,7 +3,7 @@ GroundString _GroundCopyString(GroundString* in) { GroundString string = *in; - string.cstr = malloc(sizeof(char) * in->len); + string.cstr = malloc(in->len + 1); if (string.cstr == NULL) { Ground.Flags.error = false; return string; diff --git a/src/Copy/Struct.c b/src/Copy/Struct.c index cd0fb30..7e2bf80 100644 --- a/src/Copy/Struct.c +++ b/src/Copy/Struct.c @@ -20,7 +20,14 @@ GroundStruct _GroundCopyStruct(GroundStruct* in) { } strncpy(item->name, s->name, 2047); - + + item->value = malloc(sizeof(GroundValue)); + if (item->value == NULL) { + Ground.Log.Error("malloc failed in Ground.Copy.Struct()"); + Ground.Flags.error = true; + return gs; + } + *item->value = Ground.Copy.Value(s->value); if (Ground.Flags.error) { diff --git a/src/Free/State.c b/src/Free/State.c index 820aee3..8275afd 100644 --- a/src/Free/State.c +++ b/src/Free/State.c @@ -12,14 +12,14 @@ void _GroundFreeState(GroundState* in) { { GroundCatch *s, *tmp; HASH_ITER(hh, in->catches, s, tmp) { - HASH_DEL(in->variables, s); + HASH_DEL(in->catches, s); free(s); } } { GroundLabel *s, *tmp; HASH_ITER(hh, in->labels, s, tmp) { - HASH_DEL(in->variables, s); + HASH_DEL(in->labels, s); free(s); } } diff --git a/src/Log/printErrors.c b/src/Log/printErrors.c index bb9ca60..a95d85e 100644 --- a/src/Log/printErrors.c +++ b/src/Log/printErrors.c @@ -4,13 +4,13 @@ void _GroundLogPrintErrors() { if (Ground.Log.errorCount != 0) { printf("%zu errors:\n", Ground.Log.errorCount); for (GroundSize i = 0; i < Ground.Log.errorCount; i++) { - printf(" \e[0;31m%zu: %s\n\e[0m", Ground.Log.errorCount, Ground.Log.errors[i]); + printf(" \e[0;31m%zu: %s\n\e[0m", i, Ground.Log.errors[i]); } } if (Ground.Log.warningCount != 0) { printf("%zu warnings:\n", Ground.Log.warningCount); for (GroundSize i = 0; i < Ground.Log.warningCount; i++) { - printf(" \e[0;33m%zu: %s\n\e[0m", Ground.Log.warningCount, Ground.Log.warnings[i]); + printf(" \e[0;33m%zu: %s\n\e[0m", i, Ground.Log.warnings[i]); } } } diff --git a/src/New/Function.c b/src/New/Function.c index 4b4f5fc..4ae39b3 100644 --- a/src/New/Function.c +++ b/src/New/Function.c @@ -2,9 +2,9 @@ GroundFunction _GroundNewFunction(GroundState* state) { GroundFunction function = { - .args.at = malloc(sizeof(char*) * 16), + .args.at = malloc(sizeof(GroundFunctionArg) * 16), .args.count = 0, - .args.capacity = 0, + .args.capacity = 16, .closure = malloc(sizeof(GroundState)), .isNativeFunction = false, diff --git a/src/New/Object.c b/src/New/Object.c index 085f0c3..21a8f2e 100644 --- a/src/New/Object.c +++ b/src/New/Object.c @@ -21,7 +21,14 @@ GroundObject _GroundNewObject(GroundStruct* in) { } strncpy(item->name, s->name, 2047); - + + item->value = malloc(sizeof(GroundValue)); + if (item->value == NULL) { + Ground.Log.Error("malloc failed in Ground.New.Object()"); + Ground.Flags.error = true; + return object; + } + *item->value = Ground.Copy.Value(s->value); if (Ground.Flags.error) { diff --git a/src/New/String.c b/src/New/String.c index 12dc5a1..3a62ff5 100644 --- a/src/New/String.c +++ b/src/New/String.c @@ -6,7 +6,7 @@ GroundString _GroundNewString(const char* in) { GroundString string = { .len = len, - .cstr = malloc(sizeof(len) + 1) + .cstr = malloc(len + 1) }; if (string.cstr == NULL) { diff --git a/src/cli/main.c b/src/cli/main.c index 49ad4e2..62eadd3 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -30,7 +30,7 @@ Args parseArgs(int argc, char** argv) { args.action = ARGS_DEBUG; } else if (strcmp(arg, "-a") == 0 || strcmp(arg, "--assemble") == 0) { args.action = ARGS_ASSEMBLE; - if (i + i < argc) { + if (i + 1 < argc) { i++; args.outputFile = argv[i]; } @@ -50,13 +50,13 @@ Args parseArgs(int argc, char** argv) { int main(int argc, char** argv) { Args args = parseArgs(argc, argv); - if (args.inputFile == NULL) { - fprintf(stderr, "Please specify a bytecode file\n"); - return 1; - } - switch (args.action) { case ARGS_EXECUTE: { + if (args.inputFile == NULL) { + fprintf(stderr, "Please specify a bytecode file\n"); + return 1; + } + GroundBytecode bc = Ground.Bytecode.load(args.inputFile); if (Ground.Flags.error) { fprintf(stderr, "Failed to load bytecode, printing errors...\n");