From b1b747b23444a8e9a941a460612ceaf6a47c021c Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sat, 2 Jan 2021 13:42:07 +0900 Subject: [PATCH] Some improvements to debug output before I move on to a marshalling format --- chunk.c | 17 +++++++++++++++-- chunk.h | 11 ++++++++++- compiler.c | 14 +++++++++++++- debug.c | 23 ++++++++++++++++------- debug.h | 1 + value.c | 1 + vm.c | 2 +- 7 files changed, 57 insertions(+), 12 deletions(-) diff --git a/chunk.c b/chunk.c index 380d335..51d4e79 100644 --- a/chunk.c +++ b/chunk.c @@ -6,21 +6,34 @@ void krk_initChunk(KrkChunk * chunk) { chunk->count = 0; chunk->capacity = 0; chunk->code = NULL; + + chunk->linesCount = 0; + chunk->linesCapacity = 0; chunk->lines = NULL; chunk->filename = NULL; krk_initValueArray(&chunk->constants); } +static void addLine(KrkChunk * chunk, size_t line) { + if (chunk->linesCount && chunk->lines[chunk->linesCount-1].line == line) return; + if (chunk->linesCapacity < chunk->linesCount + 1) { + int old = chunk->linesCapacity; + chunk->linesCapacity = GROW_CAPACITY(old); + chunk->lines = GROW_ARRAY(KrkLineMap, chunk->lines, old, chunk->linesCapacity); + } + chunk->lines[chunk->linesCount] = (KrkLineMap){chunk->count, line}; + chunk->linesCount++; +} + void krk_writeChunk(KrkChunk * chunk, uint8_t byte, size_t line) { if (chunk->capacity < chunk->count + 1) { int old = chunk->capacity; chunk->capacity = GROW_CAPACITY(old); chunk->code = GROW_ARRAY(uint8_t, chunk->code, old, chunk->capacity); - chunk->lines = GROW_ARRAY(size_t, chunk->lines, old, chunk->capacity); } chunk->code[chunk->count] = byte; - chunk->lines[chunk->count] = line; + addLine(chunk, line); chunk->count++; } diff --git a/chunk.h b/chunk.h index 7e2fa2b..f9844ec 100644 --- a/chunk.h +++ b/chunk.h @@ -89,6 +89,11 @@ typedef enum { OP_INLINE_FUNCTION, } KrkOpCode; +typedef struct { + size_t startOffset; + size_t line; +} KrkLineMap; + /** * Bytecode chunks */ @@ -96,7 +101,11 @@ typedef struct { size_t count; size_t capacity; uint8_t * code; - size_t * lines; + + size_t linesCount; + size_t linesCapacity; + KrkLineMap * lines; + KrkString * filename; KrkValueArray constants; } KrkChunk; diff --git a/compiler.c b/compiler.c index 15e75bd..d7d3aa9 100644 --- a/compiler.c +++ b/compiler.c @@ -312,7 +312,19 @@ static KrkFunction * endCompiler() { KrkFunction * function = current->function; #ifdef ENABLE_DISASSEMBLY if ((vm.flags & KRK_ENABLE_DISASSEMBLY) && !parser.hadError) { - krk_disassembleChunk(currentChunk(), function->name != NULL ? function->name->chars : ""); + krk_disassembleChunk(currentChunk(), function->name ? function->name->chars : ""); + fprintf(stderr, "Function metadata: requiredArgs=%d defaultArgs=%d upvalueCount=%d\n", + function->requiredArgs, function->defaultArgs, (int)function->upvalueCount); + fprintf(stderr, "__doc__: \"%s\"\n", function->docstring ? function->docstring->chars : ""); + fprintf(stderr, "Constants: "); + for (size_t i = 0; i < currentChunk()->constants.count; ++i) { + fprintf(stderr, "%d: ", (int)i); + krk_printValueSafe(stderr, currentChunk()->constants.values[i]); + if (i != currentChunk()->constants.count - 1) { + fprintf(stderr, ", "); + } + } + fprintf(stderr, "\n"); } #endif diff --git a/debug.c b/debug.c index a76b05d..af989a1 100644 --- a/debug.c +++ b/debug.c @@ -4,7 +4,7 @@ #include "vm.h" void krk_disassembleChunk(KrkChunk * chunk, const char * name) { - fprintf(stderr, "[%s]\n", name); + fprintf(stderr, "[%s from %s]\n", name, chunk->filename->chars); for (size_t offset = 0; offset < chunk->count;) { offset = krk_disassembleInstruction(chunk, offset); } @@ -12,16 +12,16 @@ void krk_disassembleChunk(KrkChunk * chunk, const char * name) { #define SIMPLE(opc) case opc: fprintf(stderr, "%s\n", #opc); return offset + 1; #define CONSTANT(opc,more) case opc: { size_t constant = chunk->code[offset + 1]; \ - fprintf(stderr, "%-16s %4d '", #opc, (int)constant); \ + fprintf(stderr, "%-16s %4d ", #opc, (int)constant); \ krk_printValueSafe(stderr, chunk->constants.values[constant]); \ - fprintf(stderr,"' (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \ + fprintf(stderr," (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \ more; \ return offset + 2; } \ case opc ## _LONG: { size_t constant = (chunk->code[offset + 1] << 16) | \ (chunk->code[offset + 2] << 8) | (chunk->code[offset + 3]); \ - fprintf(stderr, "%-16s %4d '", #opc "_LONG", (int)constant); \ + fprintf(stderr, "%-16s %4d ", #opc "_LONG", (int)constant); \ krk_printValueSafe(stderr, chunk->constants.values[constant]); \ - fprintf(stderr,"' (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \ + fprintf(stderr," (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \ more; \ return offset + 4; } #define OPERANDB(opc) case opc: { uint32_t operand = chunk->code[offset + 1]; \ @@ -46,12 +46,21 @@ void krk_disassembleChunk(KrkChunk * chunk, const char * name) { (int)offset - 2, isLocal ? "local" : "upvalue", index); \ } +size_t krk_lineNumber(KrkChunk * chunk, size_t offset) { + size_t line = 0; + for (size_t i = 0; i < chunk->linesCount; ++i) { + if (chunk->lines[i].startOffset > offset) break; + line = chunk->lines[i].line; + } + return line; +} + size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) { fprintf(stderr, "%04u ", (unsigned int)offset); - if (offset > 0 && chunk->lines[offset] == chunk->lines[offset - 1]) { + if (offset > 0 && krk_lineNumber(chunk, offset) == krk_lineNumber(chunk, offset - 1)) { fprintf(stderr, " | "); } else { - fprintf(stderr, "%4d ", (int)chunk->lines[offset]); + fprintf(stderr, "%4d ", (int)krk_lineNumber(chunk, offset)); } uint8_t opcode = chunk->code[offset]; diff --git a/debug.h b/debug.h index dbfe28e..5c2d13f 100644 --- a/debug.h +++ b/debug.h @@ -4,3 +4,4 @@ extern void krk_disassembleChunk(KrkChunk * chunk, const char * name); extern size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset); +extern size_t krk_lineNumber(KrkChunk * chunk, size_t offset); diff --git a/value.c b/value.c index 9cc9aa9..fca9ada 100644 --- a/value.c +++ b/value.c @@ -59,6 +59,7 @@ void krk_printValueSafe(FILE * f, KrkValue printable) { fprintf(f, "\"%s\"", AS_CSTRING(printable)); } else { switch (AS_OBJECT(printable)->type) { + case OBJ_FUNCTION: fprintf(f, "", AS_FUNCTION(printable)->name ? AS_FUNCTION(printable)->name->chars : "?"); break; case OBJ_CLASS: fprintf(f, "", AS_CLASS(printable)->name ? AS_CLASS(printable)->name->chars : "?"); break; case OBJ_INSTANCE: fprintf(f, "", AS_INSTANCE(printable)->_class->name->chars); break; case OBJ_NATIVE: fprintf(f, "", ((KrkNative*)AS_OBJECT(printable))->name); break; diff --git a/vm.c b/vm.c index 8adfa4b..c3befdf 100644 --- a/vm.c +++ b/vm.c @@ -51,7 +51,7 @@ static void dumpTraceback() { size_t instruction = frame->ip - function->chunk.code - 1; fprintf(stderr, " File \"%s\", line %d, in %s\n", (function->chunk.filename ? function->chunk.filename->chars : "?"), - (int)function->chunk.lines[instruction], + (int)krk_lineNumber(&function->chunk, instruction), (function->name ? function->name->chars : "(unnamed)")); }