diff --git a/include/ground.h b/include/ground.h index 691d8c0..0bcbabf 100644 --- a/include/ground.h +++ b/include/ground.h @@ -567,6 +567,7 @@ struct _Ground { char* (*Value)(GroundValue* value); char* (*BytecodeValue)(GroundBytecodeValue* value); + char* (*Bytecode)(GroundBytecode* bytecode); } Stringify; struct { diff --git a/meson.build b/meson.build index 23ec346..491038a 100644 --- a/meson.build +++ b/meson.build @@ -115,6 +115,7 @@ sources = files( 'src/Stringify/Value.c', 'src/Stringify/BytecodeValue.c', + 'src/Stringify/Bytecode.c', 'src/Struct/addField.c', diff --git a/src/Bytecode/Instruction/execute.c b/src/Bytecode/Instruction/execute.c index 42da74d..d54b33f 100644 --- a/src/Bytecode/Instruction/execute.c +++ b/src/Bytecode/Instruction/execute.c @@ -1097,6 +1097,7 @@ struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeIns break; } case 3: { + printf("fard\n"); GroundBytecodeFunction* function = &gbs->values[offset].as.Function; if (function->closure == NULL) { function->closure = malloc(sizeof(GroundBytecodeHeap)); diff --git a/src/Stringify/Bytecode.c b/src/Stringify/Bytecode.c new file mode 100644 index 0000000..4e402a3 --- /dev/null +++ b/src/Stringify/Bytecode.c @@ -0,0 +1,316 @@ +#include "../../include/ground.h" +#include "../include/estr.h" + +char* _GroundStringifyBytecode(GroundBytecode* bytecode) { + Estr estr = CREATE_ESTR(""); + + APPEND_ESTR(estr, "Bytecode Heap:\n") + + for (GroundSize i = 0; i < bytecode->heap.len; i++) { + char buf[32]; + snprintf(buf, 32, "%zu", i); + + char* bv = Ground.Stringify.BytecodeValue(&bytecode->heap.heap[i]); + + APPEND_ESTR(estr, " ") + APPEND_ESTR(estr, buf); + APPEND_ESTR(estr, ": "); + APPEND_ESTR(estr, bv); + APPEND_ESTR(estr, "\n"); + + free(bv); + } + + + APPEND_ESTR(estr, "Program:\n"); + for (GroundSize i = 0; i < bytecode->program.len; i++) { + GroundBytecodeInstruction* instruction = &bytecode->program.at[i]; + + char buf[32]; + snprintf(buf, 32, "%zu", i); + APPEND_ESTR(estr, " ") + APPEND_ESTR(estr, buf); + APPEND_ESTR(estr, ": "); + + switch (instruction->type) { + + case GroundInstruction_IF: { + APPEND_ESTR(estr, "IF "); + break; + } + + case GroundInstruction_JUMP: { + APPEND_ESTR(estr, "JUMP "); + break; + } + + case GroundInstruction_END: { + APPEND_ESTR(estr, "END "); + break; + } + + case GroundInstruction_INPUT: { + APPEND_ESTR(estr, "INPUT "); + break; + } + + case GroundInstruction_PRINT: { + APPEND_ESTR(estr, "PRINT "); + break; + } + + case GroundInstruction_PRINTLN: { + APPEND_ESTR(estr, "PRINTLN "); + break; + } + + case GroundInstruction_SET: { + APPEND_ESTR(estr, "SET "); + break; + } + + case GroundInstruction_GETTYPE: { + APPEND_ESTR(estr, "GETTYPE "); + break; + } + + case GroundInstruction_EXISTS: { + APPEND_ESTR(estr, "EXISTS "); + break; + } + + case GroundInstruction_SETLIST: { + APPEND_ESTR(estr, "SETLIST "); + break; + } + + case GroundInstruction_SETLISTAT: { + APPEND_ESTR(estr, "SETLISTAT "); + break; + } + + case GroundInstruction_GETLISTAT: { + APPEND_ESTR(estr, "GETLISTAT "); + break; + } + + case GroundInstruction_GETLISTSIZE: { + APPEND_ESTR(estr, "GETLISTSIZE "); + break; + } + + case GroundInstruction_LISTAPPEND: { + APPEND_ESTR(estr, "LISTAPPEND "); + break; + } + + case GroundInstruction_GETSTRSIZE: { + APPEND_ESTR(estr, "GETSTRSIZE "); + break; + } + + case GroundInstruction_GETSTRCHARAT: { + APPEND_ESTR(estr, "GETSTRCHARAT "); + break; + } + + case GroundInstruction_ADD: { + APPEND_ESTR(estr, "ADD "); + break; + } + + case GroundInstruction_SUBTRACT: { + APPEND_ESTR(estr, "SUBTRACT "); + break; + } + + case GroundInstruction_MULTIPLY: { + APPEND_ESTR(estr, "MULTIPLY "); + break; + } + + case GroundInstruction_DIVIDE: { + APPEND_ESTR(estr, "DIVIDE "); + break; + } + + case GroundInstruction_EQUAL: { + APPEND_ESTR(estr, "EQUAL "); + break; + } + + case GroundInstruction_INEQUAL: { + APPEND_ESTR(estr, "INEQUAL "); + break; + } + + case GroundInstruction_NOT: { + APPEND_ESTR(estr, "NOT "); + break; + } + + case GroundInstruction_GREATER: { + APPEND_ESTR(estr, "GREATER "); + break; + } + + case GroundInstruction_LESSER: { + APPEND_ESTR(estr, "LESSER "); + break; + } + + case GroundInstruction_AND: { + APPEND_ESTR(estr, "AND "); + break; + } + + case GroundInstruction_OR: { + APPEND_ESTR(estr, "OR "); + break; + } + + case GroundInstruction_XOR: { + APPEND_ESTR(estr, "XOR "); + break; + } + + case GroundInstruction_NEG: { + APPEND_ESTR(estr, "NEG "); + break; + } + + case GroundInstruction_SHIFT: { + APPEND_ESTR(estr, "SHIFT "); + break; + } + + case GroundInstruction_STOI: { + APPEND_ESTR(estr, "STOI "); + break; + } + + case GroundInstruction_STOD: { + APPEND_ESTR(estr, "STOD "); + break; + } + + case GroundInstruction_ITOC: { + APPEND_ESTR(estr, "ITOC "); + break; + } + + case GroundInstruction_CTOI: { + APPEND_ESTR(estr, "CTOI "); + break; + } + + case GroundInstruction_TOSTRING: { + APPEND_ESTR(estr, "TOSTRING "); + break; + } + + case GroundInstruction_FUN: { + APPEND_ESTR(estr, "FUN "); + break; + } + + case GroundInstruction_RETURN: { + APPEND_ESTR(estr, "RETURN "); + break; + } + + case GroundInstruction_ENDFUN: { + APPEND_ESTR(estr, "ENDFUN "); + break; + } + + case GroundInstruction_CALL: { + APPEND_ESTR(estr, "CALL "); + break; + } + + case GroundInstruction_CALLMETHOD: { + APPEND_ESTR(estr, "CALLMETHOD "); + break; + } + + case GroundInstruction_STRUCT: { + APPEND_ESTR(estr, "STRUCT "); + break; + } + + case GroundInstruction_ENDSTRUCT: { + APPEND_ESTR(estr, "ENDSTRUCT "); + break; + } + + case GroundInstruction_INIT: { + APPEND_ESTR(estr, "INIT "); + break; + } + + case GroundInstruction_GETFIELD: { + APPEND_ESTR(estr, "GETFIELD "); + break; + } + + case GroundInstruction_SETFIELD: { + APPEND_ESTR(estr, "SETFIELD "); + break; + } + + case GroundInstruction_USE: { + APPEND_ESTR(estr, "USE "); + break; + } + + case GroundInstruction_EXTERN: { + APPEND_ESTR(estr, "EXTERN "); + break; + } + + case GroundInstruction_CREATELABEL: { + APPEND_ESTR(estr, "CREATELABEL "); + break; + } + + case GroundInstruction_PAUSE: { + APPEND_ESTR(estr, "PAUSE "); + break; + } + + case GroundInstruction_DROP: { + APPEND_ESTR(estr, "DROP "); + break; + } + + case GroundInstruction_LICENSE: { + APPEND_ESTR(estr, "LICENSE "); + break; + } + + case GroundInstruction_ERROR: { + APPEND_ESTR(estr, "ERROR "); + break; + } + + case GroundInstruction_THROW: { + APPEND_ESTR(estr, "THROW "); + break; + } + + case GroundInstruction_CATCH: { + APPEND_ESTR(estr, "CATCH "); + break; + } + } + for (GroundSize j = 0; j < instruction->args.len; j++) { + char buf[32]; + snprintf(buf, 32, "%zu", instruction->args.at[i]); + APPEND_ESTR(estr, buf); + APPEND_ESTR(estr, " "); + } + APPEND_ESTR(estr, "\n"); + } + return estr.str; +} diff --git a/src/Stringify/BytecodeValue.c b/src/Stringify/BytecodeValue.c index 8bbfbd9..d1b39b7 100644 --- a/src/Stringify/BytecodeValue.c +++ b/src/Stringify/BytecodeValue.c @@ -51,7 +51,14 @@ char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value) { // TODO implement list stringification } case GroundType_Function: { - // TODO implement function stringification + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; } case GroundType_Struct: { Estr str = CREATE_ESTR(""); return str.str; } + case GroundType_CoreType: { + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; + } + case GroundType_Undefined: { + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; + } } diff --git a/src/Stringify/Instruction.c b/src/Stringify/Instruction.c index d521b65..7e224fa 100644 --- a/src/Stringify/Instruction.c +++ b/src/Stringify/Instruction.c @@ -291,8 +291,13 @@ char* _GroundStringifyInstruction(GroundInstruction* instruction) { } APPEND_ESTR(estr, arg); + APPEND_ESTR(estr, " "); free(arg); } + if (!estr.shouldBeFreed) { + char* result = strdup(estr.str); + return result; + } return estr.str; } diff --git a/src/Stringify/Program.c b/src/Stringify/Program.c index d9894b5..ce6d144 100644 --- a/src/Stringify/Program.c +++ b/src/Stringify/Program.c @@ -16,7 +16,7 @@ char* _GroundStringifyProgram(GroundProgram* program) { } APPEND_ESTR(estr, arg); - APPEND_ESTR(estr, " "); + APPEND_ESTR(estr, "\n"); free(arg); } diff --git a/src/Stringify/Value.c b/src/Stringify/Value.c index e0da102..87109c2 100644 --- a/src/Stringify/Value.c +++ b/src/Stringify/Value.c @@ -50,7 +50,14 @@ char* _GroundStringifyValue(GroundValue* value) { // TODO implement list stringification } case GroundType_Function: { - // TODO implement function stringification + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; } case GroundType_Struct: { // TODO implement struct stringification @@ -58,6 +65,26 @@ char* _GroundStringifyValue(GroundValue* value) { case GroundType_Object: { // TODO implement object stringification } + case GroundType_CoreType: { + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; + } + case GroundType_Undefined: { + char* buf = malloc(sizeof("")); + if (buf == NULL) { + Ground.Flags.error = true; + Ground.Log.Error("malloc failed in Ground.Stringify.Value"); + return NULL; + } + sprintf(buf, ""); + return buf; + } } diff --git a/src/cli/main.c b/src/cli/main.c index 0312556..e181973 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -81,8 +81,21 @@ int main(int argc, char** argv) { break; } case ARGS_DISASSEMBLE: { - fprintf(stderr, "Not yet implemented"); - + 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"); + Ground.Log.printErrors(); + return 1; + } + + char* str = Ground.Stringify.Bytecode(&bc); + printf("%s", str); + free(str); break; } case ARGS_HELP: { diff --git a/src/libmain.c b/src/libmain.c index 507045c..82acf34 100644 --- a/src/libmain.c +++ b/src/libmain.c @@ -121,6 +121,7 @@ char* _GroundStringifyString(GroundString* string); char* _GroundStringifyValue(GroundValue* value); char* _GroundStringifyBytecodeValue(GroundBytecodeValue* value); +char* _GroundStringifyBytecode(GroundBytecode* value); void* _GroundFFIOpenSharedObject(char* id); void* _GroundFFIGetFunction(void* handle, char* id); @@ -274,6 +275,7 @@ struct _Ground Ground = { .Value = _GroundStringifyValue, .BytecodeValue = _GroundStringifyBytecodeValue, + .Bytecode= _GroundStringifyBytecode, }, .FFI = {