added -quiet flag to suppres all compiler and assembler messages

This commit is contained in:
Irmen de Jong
2025-04-10 21:16:26 +02:00
parent e2a8bdbdfb
commit 59582f5210
26 changed files with 113 additions and 71 deletions

View File

@@ -32,6 +32,7 @@ class CompilationOptions(val output: OutputType,
var breakpointCpuInstruction: String? = null,
var ignoreFootguns: Boolean = false,
var outputDir: Path = Path(""),
var quiet: Boolean = false,
var symbolDefs: Map<String, String> = emptyMap()
) {
init {

View File

@@ -36,7 +36,7 @@ interface ICompilationTarget: IStringEncoding, IMemSizer {
fun convertFloatToBytes(num: Double): List<UByte>
fun convertBytesToFloat(bytes: List<UByte>): Double
fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path)
fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean)
fun isIOAddress(address: UInt): Boolean
override fun encodeString(str: String, encoding: Encoding): List<UByte>

View File

@@ -49,13 +49,15 @@ class C128Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by N
return m5.toDouble()
}
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
if(selectedEmulator!=1) {
System.err.println("The c128 target only supports the main emulator (Vice).")
return
}
if(!quiet)
println("\nStarting C-128 emulator x128...")
val viceMonlist = C64Target.viceMonListName(programNameWithPath.toString())
val cmdline = listOf("x128", "-silent", "-moncommands", viceMonlist,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg")

View File

@@ -53,14 +53,16 @@ class C64Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by No
return m5.toDouble()
}
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
if(selectedEmulator!=1) {
System.err.println("The c64 target only supports the main emulator (Vice).")
return
}
for(emulator in listOf("x64sc", "x64")) {
if(!quiet)
println("\nStarting C-64 emulator $emulator...")
val viceMonlist = viceMonListName(programNameWithPath.toString())
val cmdline = listOf(emulator, "-silent", "-moncommands", viceMonlist,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg")

View File

@@ -153,7 +153,7 @@ class ConfigFileTarget(
override fun getFloatAsmBytes(num: Number) = TODO("floats")
override fun convertFloatToBytes(num: Double): List<UByte> = TODO("floats")
override fun convertBytesToFloat(bytes: List<UByte>): Double = TODO("floats")
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
throw IllegalArgumentException("Custom compiler target cannot automatically launch an emulator. Do this manually.")
}

View File

@@ -49,7 +49,7 @@ class Cx16Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by N
return m5.toDouble()
}
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
val emulator: String
val extraArgs: List<String>
@@ -68,7 +68,9 @@ class Cx16Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by N
}
}
if(!quiet)
println("\nStarting Commander X16 emulator $emulator...")
val cmdline = listOf(emulator, "-scale", "2", "-rtc", "-run", "-prg", "${programNameWithPath}.prg") + extraArgs
val processb = ProcessBuilder(cmdline).inheritIO()
processb.environment()["PULSE_LATENCY_MSEC"] = "10"

View File

@@ -48,13 +48,15 @@ class PETTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by No
return m5.toDouble()
}
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
if(selectedEmulator!=1) {
System.err.println("The pet target only supports the main emulator (Vice).")
return
}
if(!quiet)
println("\nStarting PET emulator...")
val viceMonlist = C64Target.viceMonListName(programNameWithPath.toString())
val cmdline = listOf("xpet", "-model", "4032", "-ramsize", "32", "-videosize", "40", "-silent", "-moncommands", viceMonlist,
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg")

View File

@@ -64,17 +64,19 @@ class VMTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by Nor
return Double.fromBits(b0 or b1 or b2 or b3 or b4 or b5 or b6 or b7)
}
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path, quiet: Boolean) {
if(!quiet)
println("\nStarting Virtual Machine...")
// to not have external module dependencies in our own module, we launch the virtual machine via reflection
val vm = Class.forName("prog8.vm.VmRunner").getDeclaredConstructor().newInstance() as IVirtualMachineRunner
val filename = programNameWithPath.name
if(programNameWithPath.isReadable()) {
vm.runProgram(programNameWithPath.readText())
vm.runProgram(programNameWithPath.readText(), quiet)
} else {
val withExt = programNameWithPath.resolveSibling("$filename.p8ir")
if(withExt.isReadable())
vm.runProgram(withExt.readText())
vm.runProgram(withExt.readText(), quiet)
else
throw java.nio.file.NoSuchFileException(withExt.name, null, "not a .p8ir file")
}
@@ -116,7 +118,7 @@ class VMTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by Nor
interface IVirtualMachineRunner {
fun runProgram(irSource: String)
fun runProgram(irSource: String, quiet: Boolean)
}
private class VirtualZeropage(options: CompilationOptions): Zeropage(options) {

View File

@@ -265,7 +265,9 @@ class AsmGen6502Internal (
assembly.clear()
loopEndLabels.clear()
if(!options.quiet)
println("Generating assembly code... ")
programGen.generate()
if(errors.noErrors()) {

View File

@@ -2,7 +2,10 @@ package prog8.codegen.cpu6502
import prog8.code.GENERATED_LABEL_PREFIX
import prog8.code.IAssemblyProgram
import prog8.code.core.*
import prog8.code.core.CompilationOptions
import prog8.code.core.ICompilationTarget
import prog8.code.core.IErrorReporter
import prog8.code.core.OutputType
import prog8.code.target.C128Target
import prog8.code.target.C64Target
import prog8.code.target.PETTarget
@@ -46,6 +49,7 @@ internal class AssemblyProgram(
command.addAll(listOf("--output", prgFile.toString(), assemblyFile.toString()))
assemblerCommand = command
if(!options.quiet)
println("\nCreating prg for target ${compTarget.name}.")
}
OutputType.XEX -> {
@@ -67,6 +71,7 @@ internal class AssemblyProgram(
command.addAll(listOf("--output", xexFile.toString(), assemblyFile.toString()))
assemblerCommand = command
if(!options.quiet)
println("\nCreating xex for target ${compTarget.name}.")
}
OutputType.RAW -> {
@@ -87,6 +92,7 @@ internal class AssemblyProgram(
command.addAll(listOf("--output", binFile.toString(), assemblyFile.toString()))
assemblerCommand = command
if(!options.quiet)
println("\nCreating raw binary for target ${compTarget.name}.")
}
OutputType.LIBRARY -> {
@@ -107,9 +113,11 @@ internal class AssemblyProgram(
command.add("--list=$listFile")
if(compTarget.name in listOf(C64Target.NAME, C128Target.NAME, PETTarget.NAME)) {
if(!options.quiet)
println("\nCreating binary library file with header for target ${compTarget.name}.")
command.add("--cbm-prg")
} else {
if(!options.quiet)
println("\nCreating binary library file without header for target ${compTarget.name}.")
command.add("--nostart") // should be headerless bin, because basic has problems doing a normal LOAD"lib",8,1 - need to use BLOAD
}

View File

@@ -28,12 +28,6 @@ fun main(args: Array<String>) {
// it means that you have to run the gradle task once to generate this file.
// Do that with this command: gradle createVersionFile
println("\nProg8 compiler v${prog8.buildversion.VERSION} by Irmen de Jong (irmen@razorvine.net)")
if('-' in prog8.buildversion.VERSION) {
println("Prerelease version from git commit ${prog8.buildversion.GIT_SHA.take(8)} in branch ${prog8.buildversion.GIT_BRANCH}")
}
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
val succes = compileMain(args)
if(!succes)
exitProcess(1)
@@ -63,7 +57,8 @@ private fun compileMain(args: Array<String>): Boolean {
val plainText by cli.option(ArgType.Boolean, fullName = "plaintext", description = "output only plain text, no colors or fancy symbols")
val printAst1 by cli.option(ArgType.Boolean, fullName = "printast1", description = "print out the internal compiler AST")
val printAst2 by cli.option(ArgType.Boolean, fullName = "printast2", description = "print out the simplified AST that is used for code generation")
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
val quietAll by cli.option(ArgType.Boolean, fullName = "quiet", description = "don't print compiler and assembler messages")
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler messages")
val slabsGolden by cli.option(ArgType.Boolean, fullName = "slabsgolden", description = "put memory() slabs in 'golden ram' memory area instead of at the end of the program. On the cx16 target this is $0400-07ff. This is unavailable on other systems.")
val slabsHighBank by cli.option(ArgType.Int, fullName = "slabshigh", description = "put memory() slabs in high memory area instead of at the end of the program. On the cx16 target the value specifies the HiRAM bank to use, on other systems this value is ignored.")
val dontIncludeSourcelines by cli.option(ArgType.Boolean, fullName = "nosourcelines", description = "do not include original Prog8 source lines in generated asm code")
@@ -84,6 +79,14 @@ private fun compileMain(args: Array<String>): Boolean {
return false
}
if(quietAll!=true) {
println("\nProg8 compiler v${prog8.buildversion.VERSION} by Irmen de Jong (irmen@razorvine.net)")
if('-' in prog8.buildversion.VERSION) {
println("Prerelease version from git commit ${prog8.buildversion.GIT_SHA.take(8)} in branch ${prog8.buildversion.GIT_BRANCH}")
}
println("This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html\n")
}
val outputPath = pathFrom(outputDir)
if(!outputPath.toFile().isDirectory) {
System.err.println("Output path doesn't exist")
@@ -148,7 +151,7 @@ private fun compileMain(args: Array<String>): Boolean {
}
if(startVm==true) {
runVm(moduleFiles.first())
runVm(moduleFiles.first(), quietAll==true)
return true
}
@@ -169,7 +172,8 @@ private fun compileMain(args: Array<String>): Boolean {
if(checkSource==true) false else dontOptimize != true,
if(checkSource==true) false else dontWriteAssembly != true,
warnSymbolShadowing == true,
quietAssembler == true,
quietAll == true,
quietAll == true || quietAssembler == true,
asmListfile == true,
dontIncludeSourcelines != true,
experimentalCodegen == true,
@@ -252,7 +256,8 @@ private fun compileMain(args: Array<String>): Boolean {
if(checkSource==true) false else dontOptimize != true,
if(checkSource==true) false else dontWriteAssembly != true,
warnSymbolShadowing == true,
quietAssembler == true,
quietAll == true,
quietAll == true || quietAssembler == true,
asmListfile == true,
dontIncludeSourcelines != true,
experimentalCodegen == true,
@@ -296,9 +301,9 @@ private fun compileMain(args: Array<String>): Boolean {
val programNameInPath = outputPath.resolve(compilationResult.compilerAst.name)
if (startEmulator1 == true)
compilationResult.compilationOptions.compTarget.launchEmulator(1, programNameInPath)
compilationResult.compilationOptions.compTarget.launchEmulator(1, programNameInPath, quietAll==true)
else if (startEmulator2 == true)
compilationResult.compilationOptions.compTarget.launchEmulator(2, programNameInPath)
compilationResult.compilationOptions.compTarget.launchEmulator(2, programNameInPath, quietAll==true)
}
}
@@ -335,8 +340,8 @@ private fun processSymbolDefs(symbolDefs: List<String>): Map<String, String>? {
return result
}
fun runVm(irFilename: String) {
fun runVm(irFilename: String, quiet: Boolean) {
val irFile = Path(irFilename)
val vmdef = VMTarget()
vmdef.launchEmulator(0, irFile)
vmdef.launchEmulator(0, irFile, quiet)
}

View File

@@ -38,6 +38,7 @@ class CompilerArguments(val filepath: Path,
val optimize: Boolean,
val writeAssembly: Boolean,
val warnSymbolShadowing: Boolean,
val quietAll: Boolean,
val quietAssembler: Boolean,
val asmListfile: Boolean,
val includeSourcelines: Boolean,
@@ -84,13 +85,14 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
try {
val totalTime = measureTimeMillis {
val libraryDirs = if(compTarget.libraryPath!=null) listOf(compTarget.libraryPath.toString()) else emptyList()
val (program, options, imported) = parseMainModule(args.filepath, args.errors, compTarget, args.sourceDirs, libraryDirs)
val (program, options, imported) = parseMainModule(args.filepath, args.errors, compTarget, args.sourceDirs, libraryDirs, args.quietAll)
compilationOptions = options
with(compilationOptions) {
warnSymbolShadowing = args.warnSymbolShadowing
optimize = args.optimize
asmQuiet = args.quietAssembler
quiet = args.quietAll
asmListfile = args.asmListfile
includeSourcelines = args.includeSourcelines
experimentalCodegen = args.experimentalCodegen
@@ -183,8 +185,10 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
System.out.flush()
System.err.flush()
val seconds = totalTime/1000.0
println("\nTotal compilation+assemble time: ${round(seconds*100.0)/100.0} sec.")
if(!args.quietAll) {
val seconds = totalTime / 1000.0
println("\nTotal compilation+assemble time: ${round(seconds * 100.0) / 100.0} sec.")
}
return CompilationResult(resultingProgram!!, ast, compilationOptions, importedFiles)
} catch (px: ParseError) {
System.out.flush()
@@ -300,12 +304,13 @@ fun parseMainModule(filepath: Path,
errors: IErrorReporter,
compTarget: ICompilationTarget,
sourceDirs: List<String>,
libraryDirs: List<String>): Triple<Program, CompilationOptions, List<Path>> {
libraryDirs: List<String>,
quiet: Boolean): Triple<Program, CompilationOptions, List<Path>> {
val bf = BuiltinFunctionsFacade(BuiltinFunctions)
val program = Program(filepath.nameWithoutExtension, bf, compTarget, compTarget)
bf.program = program
val importer = ModuleImporter(program, compTarget.name, errors, sourceDirs, libraryDirs)
val importer = ModuleImporter(program, compTarget.name, errors, sourceDirs, libraryDirs, quiet)
val importedModuleResult = importer.importMainModule(filepath)
importedModuleResult.onFailure { throw it }
errors.report()

View File

@@ -23,7 +23,8 @@ class ModuleImporter(private val program: Program,
private val compilationTargetName: String,
val errors: IErrorReporter,
sourceDirs: List<String>,
libraryDirs: List<String>) {
libraryDirs: List<String>,
val quiet: Boolean) {
private val sourcePaths: List<Path> = sourceDirs.map { Path(it).sanitize() }.toSortedSet().toList()
private val libraryPaths: List<Path> = libraryDirs.map { Path(it).sanitize() }.toSortedSet().toList()
@@ -34,8 +35,10 @@ class ModuleImporter(private val program: Program,
for(path in searchIn) {
val programPath = path.resolve(normalizedFilePath)
if(programPath.exists()) {
if(!quiet) {
println("Compiling program ${Path("").absolute().relativize(programPath)}")
println("Compiler target: $compilationTargetName")
}
val source = ImportFileSystem.getFile(programPath, false)
return Ok(importModule(source))
}

View File

@@ -10,9 +10,9 @@ import io.kotest.matchers.collections.shouldBeIn
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain
import prog8.ast.Program
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.code.core.IErrorReporter
import prog8.code.source.SourceCode
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.compiler.ModuleImporter
import prog8.parser.ParseError
import prog8tests.helpers.*
@@ -29,7 +29,7 @@ class TestModuleImporter: FunSpec({
}
fun makeImporter(errors: IErrorReporter? = null, searchIn: Iterable<String>) =
ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(false), searchIn.toList(), emptyList())
ModuleImporter(program, "blah", errors ?: ErrorReporterForTests(false), searchIn.toList(), emptyList(), false)
fun makeImporter(errors: IErrorReporter?, vararg searchIn: String): ModuleImporter {
return makeImporter(errors, searchIn.asList())

View File

@@ -288,7 +288,7 @@ main {
errors.infos.any { "unused" in it } shouldBe false
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
test("also remove subroutines with names matching IR asm instruction") {

View File

@@ -34,6 +34,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
optimize,
writeAssembly = true,
warnSymbolShadowing = false,
quietAll = true,
quietAssembler = true,
asmListfile = false,
includeSourcelines = false,

View File

@@ -26,6 +26,7 @@ class TestCompilerOptionSourcedirs: FunSpec({
optimize = false,
writeAssembly = true,
warnSymbolShadowing = false,
quietAll = true,
quietAssembler = true,
asmListfile = false,
includeSourcelines = false,

View File

@@ -7,8 +7,8 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.string.shouldStartWith
import prog8.code.core.ZeropageType
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.code.core.ZeropageType
import prog8.code.target.C64Target
import prog8.code.target.Cx16Target
import prog8.code.target.VMTarget
@@ -95,7 +95,7 @@ main {
val filepath = outputDir.resolve("$filenameBase.p8")
filepath.toFile().writeText(sourceText)
val (program, options, importedfiles) = parseMainModule(filepath, errors, C64Target(), emptyList(), emptyList())
val (program, options, importedfiles) = parseMainModule(filepath, errors, C64Target(), emptyList(), emptyList(), false)
program.toplevelModule.name shouldBe filenameBase
withClue("all imports other than the test source must have been internal resources library files") {

View File

@@ -39,7 +39,7 @@ class TestLaunchEmu: FunSpec({
</BLOCK>
</PROGRAM>
""")
target.launchEmulator(0, tmpfile)
target.launchEmulator(0, tmpfile, true)
tmpfile.deleteExisting()
}
})

View File

@@ -25,6 +25,7 @@ internal fun compileFile(
optimize,
writeAssembly = writeAssembly,
warnSymbolShadowing = false,
quietAll = true,
quietAssembler = true,
asmListfile = false,
includeSourcelines = false,

View File

@@ -41,7 +41,7 @@ main {
val target = VMTarget()
val result = compileText(target, false, src, outputDir, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
test("split words array with pointers") {
@@ -61,7 +61,7 @@ main {
val target = VMTarget()
val result = compileText(target, false, src, outputDir, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
test("taking address of split arrays works") {
@@ -109,11 +109,11 @@ test {
val target = VMTarget()
var result = compileText(target, false, src, outputDir, writeAssembly = true)!!
var virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
result = compileText(target, true, src, outputDir, writeAssembly = true)!!
virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
test("compile virtual: nested labels") {
@@ -273,7 +273,7 @@ main {
val result = compileText(target, false, src, outputDir, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
exc.message shouldContain("encountered unconverted inline assembly chunk")
}
@@ -294,7 +294,7 @@ main {
val irSrc = virtfile.readText()
irSrc.shouldContain("incm.b $2000")
irSrc.shouldNotContain("</ASM>")
VmRunner().runProgram(irSrc)
VmRunner().runProgram(irSrc, false)
}
test("addresses from labels/subroutines not yet supported in VM") {
@@ -316,7 +316,7 @@ mylabel:
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
VmRunner().runProgram(virtfile.readText(), false)
}
exc.message shouldContain("cannot yet load a label address as a value")
}

View File

@@ -207,8 +207,11 @@ One or more .p8 module files
Prints the "simplified AST" which is the reduced representation of the program.
This is what is used in the code generators, to generate the executable code from.
``-quiet``
Don't print compiler and assembler messages.
``-quietasm``
Don't print assembler output results.
Don't print assembler messages
``-slabsgolden``
put memory() slabs in 'golden ram' memory area instead of at the end of the program.

View File

@@ -1,8 +1,6 @@
TODO
====
make compiler quiet when running .p8ir files via -vm (also add -quiet flag to suppress output on regular operation?)
romable: check library files for routines that are not yet romable and add "TODO: Romable" comment
romable: fix as many of those issues as possible to improve romability of library code

View File

@@ -20,7 +20,9 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
private var numInstr = 0
fun write(): Path {
if(!irProgram.options.quiet)
println("Writing intermediate representation to $outfile")
xml.writeStartDocument("utf-8", "1.0")
xml.writeEndDocument()
xml.writeCharacters("\n")
@@ -43,6 +45,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
val used = irProgram.registersUsed()
val numberUsed = (used.readRegs.keys + used.writeRegs.keys).size + (used.readFpRegs.keys + used.writeFpRegs.keys).size
if(!irProgram.options.quiet)
println("($numInstr instructions in $numChunks chunks, $numberUsed registers)")
return outfile
}

View File

@@ -76,7 +76,7 @@ class VirtualMachine(irProgram: IRProgram) {
reset(false)
}
fun run() {
fun run(quiet: Boolean) {
try {
var before = System.nanoTime()
var numIns = 0
@@ -98,6 +98,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
}
} catch (hx: ProgramExitException) {
if(!quiet)
println("\nProgram exit! Statuscode=${hx.status} #steps=${stepCount}")
gfx_close()
}
@@ -2613,18 +2614,18 @@ internal fun ArrayDeque<UByte>.popf(): Double {
// probably called via reflection
class VmRunner: IVirtualMachineRunner {
override fun runProgram(irSource: String) {
runAndTestProgram(irSource) { /* no tests */ }
override fun runProgram(irSource: String, quiet: Boolean) {
runAndTestProgram(irSource, quiet) { /* no tests */ }
}
fun runAndTestProgram(irSource: String, test: (VirtualMachine) -> Unit) {
fun runAndTestProgram(irSource: String, quiet: Boolean = false, test: (VirtualMachine) -> Unit) {
val irProgram = IRFileReader().read(irSource)
val vm = VirtualMachine(irProgram)
// vm.breakpointHandler = { pcChunk, pcIndex ->
// println("UNHANDLED BREAKPOINT")
// println(" IN CHUNK: $pcChunk(${pcChunk.label}) INDEX: $pcIndex = INSTR ${pcChunk.instructions[pcIndex]}")
// }
vm.run()
vm.run(quiet)
test(vm)
}
}

View File

@@ -36,7 +36,7 @@ class TestVm: FunSpec( {
vm.valueStack.shouldBeEmpty()
vm.pcIndex shouldBe 0
vm.stepCount shouldBe 0
vm.run()
vm.run(false)
vm.callStack.shouldBeEmpty()
vm.valueStack.shouldBeEmpty()
vm.pcIndex shouldBe 0
@@ -63,7 +63,7 @@ class TestVm: FunSpec( {
vm.valueStack.shouldBeEmpty()
vm.pcIndex shouldBe 0
vm.stepCount shouldBe 0
vm.run()
vm.run(false)
vm.stepCount shouldBe 4
vm.memory.getUW(1000) shouldBe 12345u
vm.callStack.shouldBeEmpty()
@@ -121,7 +121,7 @@ class TestVm: FunSpec( {
</BLOCK>
</PROGRAM>
"""
runner.runProgram(irSource)
runner.runProgram(irSource, false)
}
test("vm machine float bits") {