mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
add -plaintext and -ignorefootguns options
This commit is contained in:
parent
8341f9c066
commit
1ebfff7c7b
@ -29,6 +29,7 @@ class CompilationOptions(val output: OutputType,
|
||||
var slabsGolden: Boolean = false,
|
||||
var splitWordArrays: Boolean = false,
|
||||
var breakpointCpuInstruction: String? = null,
|
||||
var ignoreFootguns: Boolean = false,
|
||||
var outputDir: Path = Path(""),
|
||||
var symbolDefs: Map<String, String> = emptyMap()
|
||||
) {
|
||||
|
@ -7,6 +7,7 @@ import prog8.code.target.*
|
||||
import prog8.code.target.virtual.VirtualMachineDefinition
|
||||
import prog8.compiler.CompilationResult
|
||||
import prog8.compiler.CompilerArguments
|
||||
import prog8.compiler.ErrorReporter
|
||||
import prog8.compiler.compileProgram
|
||||
import java.io.File
|
||||
import java.nio.file.FileSystems
|
||||
@ -52,10 +53,12 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
val startEmulator2 by cli.option(ArgType.Boolean, fullName = "emu2", description = "auto-start alternative emulator after successful compilation")
|
||||
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
|
||||
val float2bytes by cli.option(ArgType.String, fullName = "float2bytes", description = "convert floating point number to a list of bytes for the target system. NOTE: you need to supply a target option too, and also still have to supply a dummy module file name as well!")
|
||||
val ignoreFootguns by cli.option(ArgType.Boolean, fullName = "ignorefootguns", description = "don't print warnings for 'footgun' issues: 'Yes I know I'm treading on mighty thin ice here'.")
|
||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform code optimizations")
|
||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||
val printAst1 by cli.option(ArgType.Boolean, fullName = "printast1", description = "print out the compiler AST")
|
||||
val plainText by cli.option(ArgType.Boolean, fullName = "plaintext", description = "output only plain text, no colors or fancy symbols")
|
||||
val printAst2 by cli.option(ArgType.Boolean, fullName = "printast2", description = "print out the intermediate AST that is used for code generation")
|
||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||
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.")
|
||||
@ -162,6 +165,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
results.clear()
|
||||
for(filepathRaw in moduleFiles) {
|
||||
val filepath = pathFrom(filepathRaw).normalize()
|
||||
val txtcolors = if(plainText==true) ErrorReporter.PlainText else ErrorReporter.AnsiColors
|
||||
val compilerArgs = CompilerArguments(
|
||||
filepath,
|
||||
if(checkSource==true) false else dontOptimize != true,
|
||||
@ -182,9 +186,11 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
breakpointCpuInstruction,
|
||||
printAst1 == true,
|
||||
printAst2 == true,
|
||||
ignoreFootguns == true,
|
||||
processedSymbols,
|
||||
srcdirs,
|
||||
outputPath
|
||||
outputPath,
|
||||
errors = ErrorReporter(txtcolors)
|
||||
)
|
||||
val compilationResult = compileProgram(compilerArgs)
|
||||
|
||||
@ -242,6 +248,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
val filepath = pathFrom(filepathRaw).normalize()
|
||||
val compilationResult: CompilationResult
|
||||
try {
|
||||
val txtcolors = if(plainText==true) ErrorReporter.PlainText else ErrorReporter.AnsiColors
|
||||
val compilerArgs = CompilerArguments(
|
||||
filepath,
|
||||
if(checkSource==true) false else dontOptimize != true,
|
||||
@ -262,9 +269,11 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
breakpointCpuInstruction,
|
||||
printAst1 == true,
|
||||
printAst2 == true,
|
||||
ignoreFootguns == true,
|
||||
processedSymbols,
|
||||
srcdirs,
|
||||
outputPath
|
||||
outputPath,
|
||||
errors = ErrorReporter(txtcolors)
|
||||
)
|
||||
val result = compileProgram(compilerArgs)
|
||||
|
||||
|
@ -52,10 +52,11 @@ class CompilerArguments(val filepath: Path,
|
||||
val breakpointCpuInstruction: String?,
|
||||
val printAst1: Boolean,
|
||||
val printAst2: Boolean,
|
||||
val ignoreFootguns: Boolean,
|
||||
val symbolDefs: Map<String, String>,
|
||||
val sourceDirs: List<String> = emptyList(),
|
||||
val outputDir: Path = Path(""),
|
||||
val errors: IErrorReporter = ErrorReporter())
|
||||
val errors: IErrorReporter = ErrorReporter(ErrorReporter.AnsiColors))
|
||||
|
||||
|
||||
fun compileProgram(args: CompilerArguments): CompilationResult? {
|
||||
@ -81,6 +82,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
||||
dumpVariables = args.dumpVariables
|
||||
dumpSymbols = args.dumpSymbols
|
||||
breakpointCpuInstruction = args.breakpointCpuInstruction
|
||||
ignoreFootguns = args.ignoreFootguns
|
||||
varsHighBank = args.varsHighBank
|
||||
varsGolden = args.varsGolden
|
||||
slabsHighBank = args.slabsHighBank
|
||||
@ -337,7 +339,7 @@ fun parseMainModule(filepath: Path,
|
||||
return Triple(program, compilerOptions, importedFiles)
|
||||
}
|
||||
|
||||
fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget): CompilationOptions {
|
||||
internal fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget): CompilationOptions {
|
||||
val toplevelModule = program.toplevelModule
|
||||
val outputDirective = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%output" } as? Directive)
|
||||
val launcherDirective = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%launcher" } as? Directive)
|
||||
|
@ -2,9 +2,9 @@ package prog8.compiler
|
||||
|
||||
import prog8.code.core.IErrorReporter
|
||||
import prog8.code.core.Position
|
||||
import java.io.PrintStream
|
||||
|
||||
|
||||
internal class ErrorReporter: IErrorReporter {
|
||||
internal class ErrorReporter(val colors: IConsoleColors): IErrorReporter {
|
||||
private enum class MessageSeverity {
|
||||
INFO,
|
||||
WARNING,
|
||||
@ -44,20 +44,27 @@ internal class ErrorReporter: IErrorReporter {
|
||||
when(it.severity) {
|
||||
MessageSeverity.ERROR -> {
|
||||
System.out.flush()
|
||||
printer.print("\u001b[91mERROR\u001B[0m ") // bright red
|
||||
colors.error(printer)
|
||||
printer.print("ERROR ")
|
||||
colors.normal(printer)
|
||||
numErrors++
|
||||
}
|
||||
MessageSeverity.WARNING -> {
|
||||
printer.print("\u001b[93mWARN\u001B[0m ") // bright yellow
|
||||
colors.warning(printer)
|
||||
printer.print("WARN ")
|
||||
colors.normal(printer)
|
||||
numWarnings++
|
||||
}
|
||||
MessageSeverity.INFO -> {
|
||||
printer.print("\u001b[92mINFO\u001B[0m ") // bright green
|
||||
colors.info(printer)
|
||||
printer.print("INFO ")
|
||||
colors.normal(printer)
|
||||
numInfos++
|
||||
}
|
||||
}
|
||||
printer.println(msg)
|
||||
alreadyReportedMessages.add(msg)
|
||||
val filtered = colors.filtered(msg)
|
||||
printer.println(filtered)
|
||||
alreadyReportedMessages.add(filtered)
|
||||
}
|
||||
}
|
||||
System.out.flush()
|
||||
@ -69,4 +76,28 @@ internal class ErrorReporter: IErrorReporter {
|
||||
override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR }
|
||||
override fun noErrorForLine(position: Position) = !messages.any { it.position.line==position.line && it.severity!=MessageSeverity.INFO }
|
||||
|
||||
|
||||
interface IConsoleColors {
|
||||
fun error(printer: PrintStream)
|
||||
fun warning(printer: PrintStream)
|
||||
fun info(printer: PrintStream)
|
||||
fun normal(printer: PrintStream)
|
||||
fun filtered(msg: String): String
|
||||
}
|
||||
|
||||
object AnsiColors: IConsoleColors {
|
||||
override fun error(printer: PrintStream) = printer.print("\u001b[91m") // red
|
||||
override fun warning(printer: PrintStream) = printer.print("\u001b[93m") // yellow
|
||||
override fun info(printer: PrintStream) = printer.print("\u001b[92m") // green
|
||||
override fun normal(printer: PrintStream) = printer.print("\u001B[0m")
|
||||
override fun filtered(msg: String): String = msg
|
||||
}
|
||||
|
||||
object PlainText: IConsoleColors {
|
||||
override fun error(printer: PrintStream) {}
|
||||
override fun warning(printer: PrintStream) {}
|
||||
override fun info(printer: PrintStream) {}
|
||||
override fun normal(printer: PrintStream) {}
|
||||
override fun filtered(msg: String): String = msg.filter { !it.isSurrogate() }
|
||||
}
|
||||
}
|
||||
|
@ -516,7 +516,8 @@ internal class AstChecker(private val program: Program,
|
||||
if (!subroutine.isAsmSubroutine && p.registerOrPair!=null) {
|
||||
if (p.registerOrPair !in Cx16VirtualRegisters) errors.err("can only use R0-R15 as register param for normal subroutines", p.position)
|
||||
else {
|
||||
errors.warn("\uD83D\uDCA3 footgun: reusing R0-R15 as parameters risks overwriting due to clobbering or no callstack", subroutine.position)
|
||||
if(!compilerOptions.ignoreFootguns)
|
||||
errors.warn("\uD83D\uDCA3 footgun: reusing R0-R15 as parameters risks overwriting due to clobbering or no callstack", subroutine.position)
|
||||
if(p.type !in WordDatatypes && p.type !in ByteDatatypesWithBoolean) {
|
||||
errors.err("can only use register param when type is boolean, byte or word", p.position)
|
||||
}
|
||||
@ -929,8 +930,10 @@ internal class AstChecker(private val program: Program,
|
||||
if(decl.datatype==DataType.STR)
|
||||
errors.err("string variables cannot be @dirty", decl.position)
|
||||
else {
|
||||
if(decl.value==null)
|
||||
errors.warn("\uD83D\uDCA3 footgun: dirty variable, initial value will be undefined", decl.position)
|
||||
if(decl.value==null) {
|
||||
if(!compilerOptions.ignoreFootguns)
|
||||
errors.warn("\uD83D\uDCA3 footgun: dirty variable, initial value will be undefined", decl.position)
|
||||
}
|
||||
else
|
||||
errors.err("dirty variable can't have initialization value", decl.position)
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
|
||||
breakpointCpuInstruction = null,
|
||||
printAst1 = false,
|
||||
printAst2 = false,
|
||||
ignoreFootguns = false,
|
||||
symbolDefs = emptyMap(),
|
||||
outputDir = outputDir
|
||||
)
|
||||
|
@ -41,6 +41,7 @@ class TestCompilerOptionSourcedirs: FunSpec({
|
||||
breakpointCpuInstruction = null,
|
||||
printAst1 = false,
|
||||
printAst2 = false,
|
||||
ignoreFootguns = false,
|
||||
symbolDefs = emptyMap(),
|
||||
sourceDirs,
|
||||
outputDir
|
||||
|
@ -43,6 +43,7 @@ internal fun compileFile(
|
||||
breakpointCpuInstruction = null,
|
||||
printAst1 = false,
|
||||
printAst2 = false,
|
||||
ignoreFootguns = false,
|
||||
)
|
||||
return compileProgram(args)
|
||||
}
|
||||
|
@ -176,6 +176,12 @@ One or more .p8 module files
|
||||
NOTE: you need to supply a target option too, and also still have to supply a dummy module file name as well!
|
||||
Also see -bytes2float
|
||||
|
||||
``-ignorefootguns``
|
||||
Don't print warnings for 'footgun' issues.
|
||||
Footgun issues are certain things you can do in Prog8 that may make your program blow up unexpectedly,
|
||||
for instance uncareful use of dirty variables, or reusing the R0-R15 registers for subroutine parameters.
|
||||
With this option you're basically saying: "Yes, I know I am treading on mighty thin ice here, but I don't want to be reminded about that".
|
||||
|
||||
``-noasm``
|
||||
Do not create assembly code and output program.
|
||||
Useful for debugging or doing quick syntax checks.
|
||||
@ -187,6 +193,9 @@ One or more .p8 module files
|
||||
``-out <directory>``
|
||||
sets directory location for output files instead of current directory
|
||||
|
||||
``-plaintext``
|
||||
Prints output messages in plain text: no colors or fancy symbols.
|
||||
|
||||
``-printast1``
|
||||
Prints the "compiler AST" (the internal representation of the program) after all processing steps.
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
add a -plain option to turn off text output coloring and unicode symbols in error messages (footguns)
|
||||
make a compiler switch to disable footgun warnings -ignorefootguns
|
||||
|
||||
update zsmkit to newest version that includes the on_deck routines when stabilized
|
||||
|
Loading…
Reference in New Issue
Block a user