Various components are now debuggable without recompiling
This commit is contained in:
parent
40d0f23135
commit
879fec20fe
|
@ -15,14 +15,14 @@
|
|||
import strformat
|
||||
|
||||
# These variables can be tweaked to debug and test various components of the toolchain
|
||||
const debugLexer* {.booldefine.} = false # Print the tokenizer's output
|
||||
const debugParser* {.booldefine.} = false # Print the AST generated by the parser
|
||||
const debugCompiler* {.booldefine.} = false # Disassemble and/or print the code generated by the compiler
|
||||
var debugLexer* = false # Print the tokenizer's output
|
||||
var debugParser* = false # Print the AST generated by the parser
|
||||
var debugCompiler* = false # Disassemble and/or print the code generated by the compiler
|
||||
const debugVM* {.booldefine.} = false # Enable the runtime debugger in the bytecode VM
|
||||
const debugGC* {.booldefine.} = false # Debug the Garbage Collector (extremely verbose)
|
||||
const debugAlloc* {.booldefine.} = false # Trace object allocation (extremely verbose)
|
||||
const debugMem* {.booldefine.} = false # Debug the memory allocator (extremely verbose)
|
||||
const debugSerializer* {.booldefine.} = false # Validate the bytecode serializer's output
|
||||
var debugSerializer* = false # Validate the bytecode serializer's output
|
||||
const debugStressGC* {.booldefine.} = false # Make the GC run a collection at every allocation (VERY SLOW!)
|
||||
const debugMarkGC* {.booldefine.} = false # Trace the marking phase object by object (extremely verbose)
|
||||
const PeonBytecodeMarker* = "PEON_BYTECODE" # Magic value at the beginning of bytecode files
|
||||
|
@ -70,8 +70,11 @@ Options
|
|||
yes/on and no/off
|
||||
--noWarn Disable a specific warning (for example, --noWarn:unusedVariable)
|
||||
--showMismatches Show all mismatches when function dispatching fails (output is really verbose)
|
||||
--backend Select the compilation backend (valid values are: 'c', 'cpp' and 'bytecode'). Note
|
||||
--backend Select the compilation backend (valid values are: 'c' and 'bytecode'). Note
|
||||
that the REPL always uses the bytecode target. Defaults to 'bytecode'
|
||||
-o, --output Rename the output file with this value (with --backend:bytecode, a '.pbc' extension
|
||||
is added if not already present)
|
||||
--debug-dump Debug the bytecode serializer. Only makes sense with --backend:bytecode
|
||||
--debug-lexer Debug the peon lexer
|
||||
--debug-parser Debug the peon parser
|
||||
"""
|
||||
|
|
|
@ -40,7 +40,7 @@ export ast, token, symbols, config, errors
|
|||
type
|
||||
PeonBackend* = enum
|
||||
## An enumeration of the peon backends
|
||||
Bytecode, NativeC, NativeCpp
|
||||
Bytecode, NativeC
|
||||
|
||||
PragmaKind* = enum
|
||||
## An enumeration of pragma types
|
||||
|
|
92
src/main.nim
92
src/main.nim
|
@ -88,7 +88,7 @@ proc repl(warnings: seq[WarningKind] = @[], mismatches: bool = false, mode: Comp
|
|||
tokens = tokenizer.lex(input, "stdin")
|
||||
if tokens.len() == 0:
|
||||
continue
|
||||
when debugLexer:
|
||||
if debugLexer:
|
||||
styledEcho fgCyan, "Tokenization step:"
|
||||
for i, token in tokens:
|
||||
if i == tokens.high():
|
||||
|
@ -99,19 +99,19 @@ proc repl(warnings: seq[WarningKind] = @[], mismatches: bool = false, mode: Comp
|
|||
tree = parser.parse(tokens, "stdin", tokenizer.getLines(), input, persist=true)
|
||||
if tree.len() == 0:
|
||||
continue
|
||||
when debugParser:
|
||||
if debugParser:
|
||||
styledEcho fgCyan, "Parsing step:"
|
||||
for node in tree:
|
||||
styledEcho fgGreen, "\t", $node
|
||||
echo ""
|
||||
compiled = compiler.compile(tree, "stdin", tokenizer.getLines(), input, chunk=compiled, showMismatches=mismatches, disabledWarnings=warnings, mode=mode, incremental=true)
|
||||
when debugCompiler:
|
||||
if debugCompiler:
|
||||
styledEcho fgCyan, "Compilation step:\n"
|
||||
debugger.disassembleChunk(compiled, "stdin")
|
||||
echo ""
|
||||
|
||||
serialized = serializer.loadBytes(serializer.dumpBytes(compiled, "stdin"))
|
||||
when debugSerializer:
|
||||
if debugSerializer:
|
||||
styledEcho fgCyan, "Serialization step: "
|
||||
styledEcho fgBlue, "\t- Peon version: ", fgYellow, &"{serialized.version.major}.{serialized.version.minor}.{serialized.version.patch}", fgBlue, " (commit ", fgYellow, serialized.commit[0..8], fgBlue, ") on branch ", fgYellow, serialized.branch
|
||||
stdout.styledWriteLine(fgBlue, "\t- Compilation date & time: ", fgYellow, fromUnix(serialized.compileDate).format("d/M/yyyy HH:mm:ss"))
|
||||
|
@ -154,7 +154,7 @@ proc repl(warnings: seq[WarningKind] = @[], mismatches: bool = false, mode: Comp
|
|||
quit(0)
|
||||
|
||||
|
||||
proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints: seq[uint64] = @[], dis: bool = false,
|
||||
proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints: seq[uint64] = @[],
|
||||
warnings: seq[WarningKind] = @[], mismatches: bool = false, mode: CompileMode = Debug, run: bool = true,
|
||||
backend: PeonBackend = PeonBackend.Bytecode, output: string) =
|
||||
var
|
||||
|
@ -183,7 +183,7 @@ proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints
|
|||
tokens = tokenizer.lex(input, f)
|
||||
if tokens.len() == 0:
|
||||
return
|
||||
when debugLexer:
|
||||
if debugLexer:
|
||||
styledEcho fgCyan, "Tokenization step:"
|
||||
for i, token in tokens:
|
||||
if i == tokens.high():
|
||||
|
@ -194,7 +194,7 @@ proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints
|
|||
tree = parser.parse(tokens, f, tokenizer.getLines(), input)
|
||||
if tree.len() == 0:
|
||||
return
|
||||
when debugParser:
|
||||
if debugParser:
|
||||
styledEcho fgCyan, "Parsing step:"
|
||||
for node in tree:
|
||||
styledEcho fgGreen, "\t", $node
|
||||
|
@ -202,11 +202,9 @@ proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints
|
|||
case backend:
|
||||
of PeonBackend.Bytecode:
|
||||
compiled = compiler.compile(tree, f, tokenizer.getLines(), input, disabledWarnings=warnings, showMismatches=mismatches, mode=mode)
|
||||
when debugCompiler:
|
||||
if debugCompiler:
|
||||
styledEcho fgCyan, "Compilation step:\n"
|
||||
debugger.disassembleChunk(compiled, f)
|
||||
if dis:
|
||||
debugger.disassembleChunk(compiled, f)
|
||||
var path = splitFile(if output.len() > 0: output else: f).dir
|
||||
if path.len() > 0:
|
||||
path &= "/"
|
||||
|
@ -221,36 +219,35 @@ proc runFile(f: string, fromString: bool = false, dump: bool = true, breakpoints
|
|||
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, "the selected backend is not implemented yet")
|
||||
elif backend == PeonBackend.Bytecode:
|
||||
serialized = serializer.loadFile(f)
|
||||
if backend == PeonBackend.Bytecode:
|
||||
when debugSerializer:
|
||||
styledEcho fgCyan, "Serialization step: "
|
||||
styledEcho fgBlue, "\t- Peon version: ", fgYellow, &"{serialized.version.major}.{serialized.version.minor}.{serialized.version.patch}", fgBlue, " (commit ", fgYellow, serialized.commit[0..8], fgBlue, ") on branch ", fgYellow, serialized.branch
|
||||
stdout.styledWriteLine(fgBlue, "\t- Compilation date & time: ", fgYellow, fromUnix(serialized.compileDate).format("d/M/yyyy HH:mm:ss"))
|
||||
stdout.styledWrite(fgBlue, &"\t- Constants segment: ")
|
||||
if serialized.chunk.consts == compiled.consts:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, &"\t- Code segment: ")
|
||||
if serialized.chunk.code == compiled.code:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Line info segment: ")
|
||||
if serialized.chunk.lines == compiled.lines:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Functions segment: ")
|
||||
if serialized.chunk.functions == compiled.functions:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Modules segment: ")
|
||||
if serialized.chunk.modules == compiled.modules:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
if backend == PeonBackend.Bytecode and debugSerializer:
|
||||
styledEcho fgCyan, "Serialization step: "
|
||||
styledEcho fgBlue, "\t- Peon version: ", fgYellow, &"{serialized.version.major}.{serialized.version.minor}.{serialized.version.patch}", fgBlue, " (commit ", fgYellow, serialized.commit[0..8], fgBlue, ") on branch ", fgYellow, serialized.branch
|
||||
stdout.styledWriteLine(fgBlue, "\t- Compilation date & time: ", fgYellow, fromUnix(serialized.compileDate).format("d/M/yyyy HH:mm:ss"))
|
||||
stdout.styledWrite(fgBlue, &"\t- Constants segment: ")
|
||||
if serialized.chunk.consts == compiled.consts:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, &"\t- Code segment: ")
|
||||
if serialized.chunk.code == compiled.code:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Line info segment: ")
|
||||
if serialized.chunk.lines == compiled.lines:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Functions segment: ")
|
||||
if serialized.chunk.functions == compiled.functions:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
stdout.styledWrite(fgBlue, "\t- Modules segment: ")
|
||||
if serialized.chunk.modules == compiled.modules:
|
||||
styledEcho fgGreen, "OK"
|
||||
else:
|
||||
styledEcho fgRed, "Corrupted"
|
||||
if run:
|
||||
case backend:
|
||||
of PeonBackend.Bytecode:
|
||||
|
@ -286,7 +283,6 @@ when isMainModule:
|
|||
var dump: bool = true
|
||||
var warnings: seq[WarningKind] = @[]
|
||||
var breaks: seq[uint64] = @[]
|
||||
var dis: bool = false
|
||||
var mismatches: bool = false
|
||||
var mode: CompileMode = CompileMode.Debug
|
||||
var run: bool = true
|
||||
|
@ -352,7 +348,7 @@ when isMainModule:
|
|||
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, &"error: invalid breakpoint value '{point}'")
|
||||
quit()
|
||||
of "disassemble":
|
||||
dis = true
|
||||
debugCompiler = true
|
||||
of "compile":
|
||||
run = false
|
||||
of "output":
|
||||
|
@ -363,8 +359,12 @@ when isMainModule:
|
|||
backend = PeonBackend.Bytecode
|
||||
of "c":
|
||||
backend = PeonBackend.NativeC
|
||||
of "cpp":
|
||||
backend = PeonBackend.NativeCpp
|
||||
of "debug-dump":
|
||||
debugSerializer = true
|
||||
of "debug-lexer":
|
||||
debugLexer = true
|
||||
of "debug-parser":
|
||||
debugParser = true
|
||||
else:
|
||||
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, &"error: unkown option '{key}'")
|
||||
quit()
|
||||
|
@ -405,7 +405,7 @@ when isMainModule:
|
|||
of "c":
|
||||
run = false
|
||||
of "d":
|
||||
dis = true
|
||||
debugCompiler = true
|
||||
else:
|
||||
stderr.styledWriteLine(fgRed, styleBright, "Error: ", fgDefault, &"unkown option '{key}'")
|
||||
quit()
|
||||
|
@ -417,4 +417,4 @@ when isMainModule:
|
|||
if file == "":
|
||||
repl(warnings, mismatches, mode, breaks)
|
||||
else:
|
||||
runFile(file, fromString, dump, breaks, dis, warnings, mismatches, mode, run, backend, output)
|
||||
runFile(file, fromString, dump, breaks, warnings, mismatches, mode, run, backend, output)
|
||||
|
|
Loading…
Reference in New Issue