From 5267e0696999acd67a2174e68b170f8a806971fb Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 30 Dec 2021 14:38:40 +0100 Subject: [PATCH] added -asmlist cli option to produce assembler listing output --- .../codegen/target/c64/C64MachineDefinition.kt | 5 +++-- .../prog8/codegen/target/cbm/AssemblyProgram.kt | 15 ++++++++++----- .../codegen/target/cx16/CX16MachineDefinition.kt | 4 ++-- compiler/src/prog8/CompilerMain.kt | 3 +++ compiler/src/prog8/compiler/Compiler.kt | 14 ++++++++------ .../compiler/astprocessing/ParentNodeChecker.kt | 6 +++--- .../compiler/astprocessing/StatementReorderer.kt | 14 +++++++------- compiler/test/TestCompilerOnExamples.kt | 1 + compiler/test/TestCompilerOptionLibdirs.kt | 1 + compiler/test/helpers/compileXyz.kt | 1 + .../src/prog8/ast/AstToSourceTextConverter.kt | 6 +++--- .../src/prog8/ast/expressions/AstExpressions.kt | 2 +- compilerAst/src/prog8/ast/walk/IAstVisitor.kt | 8 ++++---- .../prog8/compilerinterface/CompilationOptions.kt | 4 +++- .../prog8/compilerinterface/IAssemblyGenerator.kt | 2 +- docs/source/building.rst | 3 +++ docs/source/todo.rst | 2 +- httpCompilerService/src/prog8/http/TestHttp.kt | 3 ++- 18 files changed, 57 insertions(+), 37 deletions(-) diff --git a/codeGeneration/src/prog8/codegen/target/c64/C64MachineDefinition.kt b/codeGeneration/src/prog8/codegen/target/c64/C64MachineDefinition.kt index 852eabc64..f549a7d04 100644 --- a/codeGeneration/src/prog8/codegen/target/c64/C64MachineDefinition.kt +++ b/codeGeneration/src/prog8/codegen/target/c64/C64MachineDefinition.kt @@ -2,7 +2,7 @@ package prog8.codegen.target.c64 import prog8.ast.base.DataType import prog8.codegen.target.cbm.Mflpt5 -import prog8.codegen.target.cbm.viceMonListPostfix +import prog8.codegen.target.cbm.viceMonListName import prog8.compilerinterface.* import java.io.IOException import java.nio.file.Path @@ -42,7 +42,8 @@ class C64MachineDefinition: IMachineDefinition { for(emulator in listOf("x64sc", "x64")) { println("\nStarting C-64 emulator $emulator...") - val cmdline = listOf(emulator, "-silent", "-moncommands", "${programNameWithPath}.$viceMonListPostfix", + val viceMonlist = viceMonListName(programNameWithPath.toString()) + val cmdline = listOf(emulator, "-silent", "-moncommands", viceMonlist, "-autostartprgmode", "1", "-autostart-warp", "-autostart", "${programNameWithPath}.prg") val processb = ProcessBuilder(cmdline).inheritIO() val process: Process diff --git a/codeGeneration/src/prog8/codegen/target/cbm/AssemblyProgram.kt b/codeGeneration/src/prog8/codegen/target/cbm/AssemblyProgram.kt index 4d15f2e77..e3c3c438c 100644 --- a/codeGeneration/src/prog8/codegen/target/cbm/AssemblyProgram.kt +++ b/codeGeneration/src/prog8/codegen/target/cbm/AssemblyProgram.kt @@ -14,7 +14,7 @@ import kotlin.io.path.Path import kotlin.io.path.isRegularFile -internal const val viceMonListPostfix = "vice-mon-list" +internal fun viceMonListName(baseFilename: String) = "$baseFilename.vice-mon-list" class AssemblyProgram( override val valid: Boolean, @@ -25,17 +25,22 @@ class AssemblyProgram( private val assemblyFile = outputDir.resolve("$name.asm") private val prgFile = outputDir.resolve("$name.prg") private val binFile = outputDir.resolve("$name.bin") - private val viceMonListFile = outputDir.resolve("$name.$viceMonListPostfix") + private val viceMonListFile = outputDir.resolve(viceMonListName(name)) + private val listFile = outputDir.resolve("$name.list") - override fun assemble(quiet: Boolean, options: CompilationOptions): Int { + override fun assemble(options: CompilationOptions): Int { // add "-Wlong-branch" to see warnings about conversion of branch instructions to jumps (default = do this silently) val command = mutableListOf("64tass", "--ascii", "--case-sensitive", "--long-branch", "-Wall", "-Wno-strict-bool", "-Wno-shadow", // "-Werror", - "--dump-labels", "--vice-labels", "-l", viceMonListFile.toString(), "--no-monitor") + "--dump-labels", "--vice-labels", "--labels=$viceMonListFile", "--no-monitor" + ) - if(quiet) + if(options.asmQuiet) command.add("--quiet") + if(options.asmListfile) + command.add("--list=$listFile") + val outFile = when (options.output) { OutputType.PRG -> { command.add("--cbm-prg") diff --git a/codeGeneration/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt b/codeGeneration/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt index 0144895e2..c2c514cc1 100644 --- a/codeGeneration/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt +++ b/codeGeneration/src/prog8/codegen/target/cx16/CX16MachineDefinition.kt @@ -2,7 +2,7 @@ package prog8.codegen.target.cx16 import prog8.ast.base.DataType import prog8.codegen.target.cbm.Mflpt5 -import prog8.codegen.target.cbm.viceMonListPostfix +import prog8.codegen.target.cbm.viceMonListName import prog8.compilerinterface.* import java.io.IOException import java.nio.file.Path @@ -44,7 +44,7 @@ class CX16MachineDefinition: IMachineDefinition { } 2 -> { emulatorName = "box16" - extraArgs = listOf("-sym", "${programNameWithPath}.$viceMonListPostfix") + extraArgs = listOf("-sym", viceMonListName(programNameWithPath.toString())) } else -> { System.err.println("Cx16 target only supports x16emu and box16 emulators.") diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index c10e46daa..6b85236a4 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -40,6 +40,7 @@ private fun compileMain(args: Array): Boolean { val watchMode by cli.option(ArgType.Boolean, fullName = "watch", description = "continuous compilation mode (watches for file changes), greatly increases compilation speed") val slowCodegenWarnings by cli.option(ArgType.Boolean, fullName = "slowwarn", description="show debug warnings about slow/problematic assembly code generation") val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results") + val asmListfile by cli.option(ArgType.Boolean, fullName = "asmlist", description = "make the assembler produce a listing file as well") val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler, currently '${C64Target.name}' and '${Cx16Target.name}' available").default(C64Target.name) val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator) val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999) @@ -88,6 +89,7 @@ private fun compileMain(args: Array): Boolean { dontWriteAssembly != true, slowCodegenWarnings == true, quietAssembler == true, + asmListfile == true, compilationTarget, srcdirs, outputPath @@ -136,6 +138,7 @@ private fun compileMain(args: Array): Boolean { dontWriteAssembly != true, slowCodegenWarnings == true, quietAssembler == true, + asmListfile == true, compilationTarget, srcdirs, outputPath diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 45430e3cf..31a43dad9 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -34,6 +34,7 @@ class CompilerArguments(val filepath: Path, val writeAssembly: Boolean, val slowCodegenWarnings: Boolean, val quietAssembler: Boolean, + val asmListfile: Boolean, val compilationTarget: String, val sourceDirs: List = emptyList(), val outputDir: Path = Path(""), @@ -59,9 +60,11 @@ fun compileProgram(args: CompilerArguments): CompilationResult { // import main module and everything it needs val (programresult, compilationOptions, imported) = parseImports(args.filepath, args.errors, compTarget, args.sourceDirs) with(compilationOptions) { - this.slowCodegenWarnings = args.slowCodegenWarnings - this.optimize = args.optimize - this.optimizeFloatExpressions = optimizeFloatExpr + slowCodegenWarnings = args.slowCodegenWarnings + optimize = args.optimize + optimizeFloatExpressions = optimizeFloatExpr + asmQuiet = args.quietAssembler + asmListfile = args.asmListfile } program = programresult importedFiles = imported @@ -84,7 +87,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult { // printProgram(program) if (args.writeAssembly) { - when (val result = writeAssembly(program, args.errors, args.outputDir, args.quietAssembler, compilationOptions)) { + when (val result = writeAssembly(program, args.errors, args.outputDir, compilationOptions)) { is WriteAssemblyResult.Ok -> programName = result.filename is WriteAssemblyResult.Fail -> { System.err.println(result.error) @@ -326,7 +329,6 @@ private sealed class WriteAssemblyResult { private fun writeAssembly(program: Program, errors: IErrorReporter, outputDir: Path, - quietAssembler: Boolean, compilerOptions: CompilationOptions ): WriteAssemblyResult { // asm generation directly from the Ast @@ -346,7 +348,7 @@ private fun writeAssembly(program: Program, errors.report() return if(assembly.valid && errors.noErrors()) { - val assemblerReturnStatus = assembly.assemble(quietAssembler, compilerOptions) + val assemblerReturnStatus = assembly.assemble(compilerOptions) if(assemblerReturnStatus!=0) WriteAssemblyResult.Fail("assembler step failed with return code $assemblerReturnStatus") else { diff --git a/compiler/src/prog8/compiler/astprocessing/ParentNodeChecker.kt b/compiler/src/prog8/compiler/astprocessing/ParentNodeChecker.kt index c28d414fb..25e9febe0 100644 --- a/compiler/src/prog8/compiler/astprocessing/ParentNodeChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/ParentNodeChecker.kt @@ -209,9 +209,9 @@ internal class ParentNodeChecker: AstWalker() { return noModifications } - override fun before(`when`: When, parent: Node): Iterable { - if(`when`.parent!==parent) - throw FatalAstException("parent node mismatch at $`when`") + override fun before(whenStmt: When, parent: Node): Iterable { + if(whenStmt.parent!==parent) + throw FatalAstException("parent node mismatch at $whenStmt") return noModifications } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 531ea4494..36a7ef0ee 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -262,19 +262,19 @@ internal class StatementReorderer(val program: Program, return noModifications } - override fun after(`when`: When, parent: Node): Iterable { - val lastChoiceValues = `when`.choices.lastOrNull()?.values + override fun after(whenStmt: When, parent: Node): Iterable { + val lastChoiceValues = whenStmt.choices.lastOrNull()?.values if(lastChoiceValues?.isNotEmpty()==true) { - val elseChoice = `when`.choices.indexOfFirst { it.values==null || it.values?.isEmpty()==true } + val elseChoice = whenStmt.choices.indexOfFirst { it.values==null || it.values?.isEmpty()==true } if(elseChoice>=0) - errors.err("else choice must be the last one", `when`.choices[elseChoice].position) + errors.err("else choice must be the last one", whenStmt.choices[elseChoice].position) } - val choices = `when`.choiceValues(program).sortedBy { + val choices = whenStmt.choiceValues(program).sortedBy { it.first?.first() ?: Int.MAX_VALUE } - `when`.choices.clear() - choices.mapTo(`when`.choices) { it.second } + whenStmt.choices.clear() + choices.mapTo(whenStmt.choices) { it.second } return noModifications } diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index 53649587e..3c5b1f66b 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -30,6 +30,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat writeAssembly = true, slowCodegenWarnings = false, quietAssembler = true, + asmListfile = false, compilationTarget = target.name, outputDir = outputDir ) diff --git a/compiler/test/TestCompilerOptionLibdirs.kt b/compiler/test/TestCompilerOptionLibdirs.kt index ff4647bbb..22dcba967 100644 --- a/compiler/test/TestCompilerOptionLibdirs.kt +++ b/compiler/test/TestCompilerOptionLibdirs.kt @@ -44,6 +44,7 @@ class TestCompilerOptionSourcedirs: FunSpec({ writeAssembly = true, slowCodegenWarnings = false, quietAssembler = true, + asmListfile = false, compilationTarget = Cx16Target.name, sourceDirs, outputDir diff --git a/compiler/test/helpers/compileXyz.kt b/compiler/test/helpers/compileXyz.kt index 6c23f261b..37fd2abf9 100644 --- a/compiler/test/helpers/compileXyz.kt +++ b/compiler/test/helpers/compileXyz.kt @@ -51,6 +51,7 @@ internal fun compileFile( writeAssembly = writeAssembly, slowCodegenWarnings = false, quietAssembler = true, + asmListfile = false, platform.name, outputDir = outputDir, errors = errors ?: ErrorReporterForTests() diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index f01cdad73..f308556ff 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -428,12 +428,12 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: outputlni("}}") } - override fun visit(`when`: When) { + override fun visit(whenStmt: When) { output("when ") - `when`.condition.accept(this) + whenStmt.condition.accept(this) outputln(" {") scopelevel++ - `when`.choices.forEach { it.accept(this) } + whenStmt.choices.forEach { it.accept(this) } scopelevel-- outputlni("}") } diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 9fc48e13d..f9598ec0d 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -1055,7 +1055,7 @@ class ContainmentCheck(var element: Expression, override fun referencesIdentifier(nameInSource: List): Boolean { if(element is IdentifierReference) return element.referencesIdentifier(nameInSource) - return iterable?.referencesIdentifier(nameInSource) ?: false + return iterable.referencesIdentifier(nameInSource) } override fun inferType(program: Program) = InferredTypes.knownFor(DataType.UBYTE) diff --git a/compilerAst/src/prog8/ast/walk/IAstVisitor.kt b/compilerAst/src/prog8/ast/walk/IAstVisitor.kt index 8ea30bfec..2f847865b 100644 --- a/compilerAst/src/prog8/ast/walk/IAstVisitor.kt +++ b/compilerAst/src/prog8/ast/walk/IAstVisitor.kt @@ -28,7 +28,7 @@ interface IAstVisitor { fun visit(containment: ContainmentCheck) { containment.element.accept(this) - containment.iterable?.accept(this) + containment.iterable.accept(this) } fun visit(block: Block) { @@ -172,9 +172,9 @@ interface IAstVisitor { fun visit(nop: Nop) { } - fun visit(`when`: When) { - `when`.condition.accept(this) - `when`.choices.forEach { it.accept(this) } + fun visit(whenStmt: When) { + whenStmt.condition.accept(this) + whenStmt.choices.forEach { it.accept(this) } } fun visit(whenChoice: WhenChoice) { diff --git a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt index 67e75dc61..c8ea565f2 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt @@ -28,5 +28,7 @@ class CompilationOptions(val output: OutputType, // these are set based on command line arguments: var slowCodegenWarnings: Boolean = false, var optimize: Boolean = false, - var optimizeFloatExpressions: Boolean = false + var optimizeFloatExpressions: Boolean = false, + var asmQuiet: Boolean = false, + var asmListfile: Boolean = false ) diff --git a/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt b/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt index 4cf4e4c69..934485fec 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/IAssemblyGenerator.kt @@ -11,5 +11,5 @@ const val subroutineFloatEvalResultVar2 = "_prog8_float_eval_result2" interface IAssemblyProgram { val valid: Boolean val name: String - fun assemble(quiet: Boolean, options: CompilationOptions): Int + fun assemble(options: CompilationOptions): Int } diff --git a/docs/source/building.rst b/docs/source/building.rst index f36122466..b407f915b 100644 --- a/docs/source/building.rst +++ b/docs/source/building.rst @@ -144,6 +144,9 @@ One or more .p8 module files ``-quietasm`` Don't print assembler output results. +``-asmlist`` + Generate an assembler listing file as well. + Module source code files ------------------------ diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 20d1d7510..944fbff19 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,7 @@ TODO For next compiler release (7.6) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- make (an option) to let 64tass produce a listing file as well as output. +... Blocked by an official Commander-x16 v39 release diff --git a/httpCompilerService/src/prog8/http/TestHttp.kt b/httpCompilerService/src/prog8/http/TestHttp.kt index 863df7672..e0e28ae95 100644 --- a/httpCompilerService/src/prog8/http/TestHttp.kt +++ b/httpCompilerService/src/prog8/http/TestHttp.kt @@ -37,7 +37,8 @@ class RequestParser : Take { writeAssembly = true, slowCodegenWarnings = true, compilationTarget = "c64", - quietAssembler = false + quietAssembler = false, + asmListfile = false ) val compilationResult = compileProgram(args) return RsJson(Jsonding())