From 2b8f613a001e7aafd10744ffafaaec74af52241d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 26 Dec 2023 23:37:59 +0100 Subject: [PATCH] added %option ignore_unused to suppress warnings about unused vars and subs in that module/block. Also improved error for invalid directive. --- codeCore/src/prog8/code/ast/AstBase.kt | 1 + .../src/prog8/codegen/intermediate/IRCodeGen.kt | 1 + .../codegen/intermediate/IRUnusedCodeRemover.kt | 5 ++--- .../src/prog8/optimizer/UnusedCodeRemover.kt | 8 ++++---- compiler/res/prog8lib/atari/syslib.p8 | 2 +- compiler/res/prog8lib/atari/textio.p8 | 2 +- compiler/res/prog8lib/c128/syslib.p8 | 2 +- compiler/res/prog8lib/c128/textio.p8 | 2 +- compiler/res/prog8lib/c64/floats.p8 | 2 +- compiler/res/prog8lib/c64/graphics.p8 | 2 +- compiler/res/prog8lib/c64/syslib.p8 | 2 +- compiler/res/prog8lib/c64/textio.p8 | 2 +- compiler/res/prog8lib/conv.p8 | 2 +- compiler/res/prog8lib/cx16/diskio.p8 | 2 +- compiler/res/prog8lib/cx16/floats.p8 | 2 +- compiler/res/prog8lib/cx16/gfx2.p8 | 2 +- compiler/res/prog8lib/cx16/graphics.p8 | 2 +- compiler/res/prog8lib/cx16/monogfx.p8 | 2 +- compiler/res/prog8lib/cx16/palette.p8 | 2 +- compiler/res/prog8lib/cx16/psg.p8 | 2 +- compiler/res/prog8lib/cx16/syslib.p8 | 2 +- compiler/res/prog8lib/cx16/textio.p8 | 2 +- compiler/res/prog8lib/cx16/verafx.p8 | 2 +- compiler/res/prog8lib/cx16logo.p8 | 2 +- compiler/res/prog8lib/diskio.p8 | 2 +- compiler/res/prog8lib/floats_functions.p8 | 2 +- compiler/res/prog8lib/math.p8 | 2 +- compiler/res/prog8lib/pet32/syslib.p8 | 2 +- compiler/res/prog8lib/pet32/textio.p8 | 2 +- compiler/res/prog8lib/prog8_lib.p8 | 2 +- compiler/res/prog8lib/string.p8 | 2 +- compiler/res/prog8lib/test_stack.p8 | 2 +- compiler/res/prog8lib/virtual/conv.p8 | 2 ++ compiler/res/prog8lib/virtual/emudbg.p8 | 1 + compiler/res/prog8lib/virtual/floats.p8 | 2 +- compiler/res/prog8lib/virtual/math.p8 | 1 + compiler/res/prog8lib/virtual/monogfx.p8 | 2 +- compiler/res/prog8lib/virtual/prog8_lib.p8 | 2 +- compiler/res/prog8lib/virtual/string.p8 | 2 ++ compiler/res/prog8lib/virtual/syslib.p8 | 2 ++ compiler/res/prog8lib/virtual/textio.p8 | 1 + .../prog8/compiler/astprocessing/AstChecker.kt | 6 +++--- .../astprocessing/IntermediateAstMaker.kt | 6 ++++-- .../compiler/astprocessing/VariousCleanups.kt | 10 ++++++++++ compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt | 2 +- .../src/prog8/ast/statements/AstStatements.kt | 17 +++++++++++++++++ docs/source/syntaxreference.rst | 4 +++- docs/source/todo.rst | 3 --- .../src/prog8/intermediate/IRFileReader.kt | 1 + .../src/prog8/intermediate/IRFileWriter.kt | 9 +++++---- .../src/prog8/intermediate/IRProgram.kt | 1 + parser/antlr/Prog8ANTLR.g4 | 8 +++----- 52 files changed, 96 insertions(+), 57 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstBase.kt b/codeCore/src/prog8/code/ast/AstBase.kt index 7b5ccb384..244a47cb4 100644 --- a/codeCore/src/prog8/code/ast/AstBase.kt +++ b/codeCore/src/prog8/code/ast/AstBase.kt @@ -86,6 +86,7 @@ class PtBlock(name: String, val forceOutput: Boolean = false, val noSymbolPrefixing: Boolean = false, val veraFxMuls: Boolean = false, + val ignoreUnused: Boolean = false, val alignment: BlockAlignment = BlockAlignment.NONE) } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index e199ff9f2..3291ea945 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -1667,6 +1667,7 @@ class IRCodeGen( block.options.forceOutput, block.options.noSymbolPrefixing, block.options.veraFxMuls, + block.options.ignoreUnused, translate(block.options.alignment) ), block.position) for (child in block.children) { diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt index 055bc0c1c..021d4bc1e 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt @@ -1,7 +1,6 @@ package prog8.codegen.intermediate import prog8.code.core.IErrorReporter -import prog8.code.core.SourceCode.Companion.LIBRARYFILEPREFIX import prog8.intermediate.* @@ -61,7 +60,7 @@ class IRUnusedCodeRemover( irprog.blocks.forEach { block -> block.children.filterIsInstance().reversed().forEach { sub -> if(sub.isEmpty()) { - if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) { + if(!block.options.ignoreUnused) { errors.warn("unused subroutine '${sub.label}'", sub.position) } block.children.remove(sub) @@ -82,7 +81,7 @@ class IRUnusedCodeRemover( irprog.blocks.forEach { block -> block.children.filterIsInstance().reversed().forEach { sub -> if(sub.isEmpty()) { - if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) { + if(!block.options.ignoreUnused) { errors.warn("unused subroutine '${sub.label}'", sub.position) } block.children.remove(sub) diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index 501326efd..18c1a88f3 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -90,7 +90,7 @@ class UnusedCodeRemover(private val program: Program, if (subroutine !== program.entrypoint && !forceOutput && !subroutine.isAsmSubroutine) { if(callgraph.unused(subroutine)) { if(subroutine.containsNoCodeNorVars) { - if(!subroutine.definingModule.isLibrary) + if("ignore_unused" !in subroutine.definingBlock.options()) errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position) val removals = mutableListOf(IAstModification.Remove(subroutine, parent as IStatementContainer)) callgraph.calledBy[subroutine]?.let { @@ -99,7 +99,7 @@ class UnusedCodeRemover(private val program: Program, } return removals } - if(!subroutine.hasBeenInlined && !subroutine.definingModule.isLibrary) { + if(!subroutine.hasBeenInlined && "ignore_unused" !in subroutine.definingBlock.options()) { errors.warn("unused subroutine '${subroutine.name}'", subroutine.position) } if(!subroutine.inline) { @@ -119,7 +119,7 @@ class UnusedCodeRemover(private val program: Program, if (!forceOutput && decl.origin==VarDeclOrigin.USERCODE && !decl.sharedWithAsm) { val usages = callgraph.usages(decl) if (usages.isEmpty()) { - if(!decl.definingModule.isLibrary) + if("ignore_unused" !in decl.definingBlock.options()) errors.warn("removing unused variable '${decl.name}'", decl.position) return listOf(IAstModification.Remove(decl, parent as IStatementContainer)) } @@ -131,7 +131,7 @@ class UnusedCodeRemover(private val program: Program, if(assignment!=null && assignment.origin==AssignmentOrigin.VARINIT) { if(assignment.value.isSimple) { // remove the vardecl - if(!decl.definingModule.isLibrary) + if("ignore_unused" !in decl.definingBlock.options()) errors.warn("removing unused variable '${decl.name}'", decl.position) return listOf( IAstModification.Remove(decl, parent as IStatementContainer), diff --git a/compiler/res/prog8lib/atari/syslib.p8 b/compiler/res/prog8lib/atari/syslib.p8 index 79d318ef6..9e9b3b899 100644 --- a/compiler/res/prog8lib/atari/syslib.p8 +++ b/compiler/res/prog8lib/atari/syslib.p8 @@ -1,7 +1,7 @@ ; Prog8 definitions for the Atari800XL ; Including memory registers, I/O registers, Basic and Kernal subroutines. -%option no_symbol_prefixing +%option no_symbol_prefixing, ignore_unused atari { diff --git a/compiler/res/prog8lib/atari/textio.p8 b/compiler/res/prog8lib/atari/textio.p8 index 6641a7c49..536058a86 100644 --- a/compiler/res/prog8lib/atari/textio.p8 +++ b/compiler/res/prog8lib/atari/textio.p8 @@ -7,7 +7,7 @@ txt { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 24 diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index bf7237bc9..24e2b92c4 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -1,7 +1,7 @@ ; Prog8 definitions for the Commodore-128 ; Including memory registers, I/O registers, Basic and Kernal subroutines. -%option no_symbol_prefixing +%option no_symbol_prefixing, ignore_unused cbm { ; Commodore (CBM) common variables, vectors and kernal routines diff --git a/compiler/res/prog8lib/c128/textio.p8 b/compiler/res/prog8lib/c128/textio.p8 index 9eee73ca5..511f4175c 100644 --- a/compiler/res/prog8lib/c128/textio.p8 +++ b/compiler/res/prog8lib/c128/textio.p8 @@ -7,7 +7,7 @@ txt { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8 index 6d2792714..7a8514679 100644 --- a/compiler/res/prog8lib/c64/floats.p8 +++ b/compiler/res/prog8lib/c64/floats.p8 @@ -1,6 +1,6 @@ ; Prog8 definitions for floating point handling on the Commodore-64 -%option enable_floats, no_symbol_prefixing +%option enable_floats, no_symbol_prefixing, ignore_unused %import floats_functions floats { diff --git a/compiler/res/prog8lib/c64/graphics.p8 b/compiler/res/prog8lib/c64/graphics.p8 index d31f6a87e..03455d9ab 100644 --- a/compiler/res/prog8lib/c64/graphics.p8 +++ b/compiler/res/prog8lib/c64/graphics.p8 @@ -8,7 +8,7 @@ ; so that the program itself can be larger without starting to overwrite the graphics memory. graphics { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const uword WIDTH = 320 const ubyte HEIGHT = 200 diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 3c21576b8..8ca06d5bd 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -1,7 +1,7 @@ ; Prog8 definitions for the Commodore-64 ; Including memory registers, I/O registers, Basic and Kernal subroutines. -%option no_symbol_prefixing +%option no_symbol_prefixing, ignore_unused cbm { ; Commodore (CBM) common variables, vectors and kernal routines diff --git a/compiler/res/prog8lib/c64/textio.p8 b/compiler/res/prog8lib/c64/textio.p8 index 0a9146da8..29ca48509 100644 --- a/compiler/res/prog8lib/c64/textio.p8 +++ b/compiler/res/prog8lib/c64/textio.p8 @@ -8,7 +8,7 @@ txt { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 diff --git a/compiler/res/prog8lib/conv.p8 b/compiler/res/prog8lib/conv.p8 index 065e64702..00a26f62e 100644 --- a/compiler/res/prog8lib/conv.p8 +++ b/compiler/res/prog8lib/conv.p8 @@ -2,7 +2,7 @@ conv { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused ; ----- number conversions to decimal strings ---- diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 56aba0812..66768b8e8 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -17,7 +17,7 @@ %import syslib diskio { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte READ_IO_CHANNEL=12 const ubyte WRITE_IO_CHANNEL=13 diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index 035b753ef..5e764d517 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -1,6 +1,6 @@ ; Prog8 definitions for floating point handling on the CommanderX16 -%option enable_floats, no_symbol_prefixing +%option enable_floats, no_symbol_prefixing, ignore_unused %import floats_functions floats { diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index 354f493be..d2eeb9605 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -24,7 +24,7 @@ gfx2 { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused ; read-only control variables: ubyte active_mode = 0 diff --git a/compiler/res/prog8lib/cx16/graphics.p8 b/compiler/res/prog8lib/cx16/graphics.p8 index e4088eb31..9c1f150fe 100644 --- a/compiler/res/prog8lib/cx16/graphics.p8 +++ b/compiler/res/prog8lib/cx16/graphics.p8 @@ -14,7 +14,7 @@ graphics { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused romsub $feff = FB_cursor_position2() clobbers(A,X,Y) ; alias for the normal FB_cursor_position() call but reuses existing r0 and r1 diff --git a/compiler/res/prog8lib/cx16/monogfx.p8 b/compiler/res/prog8lib/cx16/monogfx.p8 index cf6e67e67..f3ef7b8f3 100644 --- a/compiler/res/prog8lib/cx16/monogfx.p8 +++ b/compiler/res/prog8lib/cx16/monogfx.p8 @@ -11,7 +11,7 @@ monogfx { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused ; read-only control variables: uword width = 0 diff --git a/compiler/res/prog8lib/cx16/palette.p8 b/compiler/res/prog8lib/cx16/palette.p8 index 01f2cbbbc..55f3fbde0 100644 --- a/compiler/res/prog8lib/cx16/palette.p8 +++ b/compiler/res/prog8lib/cx16/palette.p8 @@ -3,7 +3,7 @@ ; The first 16 colors can be restored to their default with set_default16() palette { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused uword vera_palette_ptr diff --git a/compiler/res/prog8lib/cx16/psg.p8 b/compiler/res/prog8lib/cx16/psg.p8 index 7e3cb8d8a..d4475a0a5 100644 --- a/compiler/res/prog8lib/cx16/psg.p8 +++ b/compiler/res/prog8lib/cx16/psg.p8 @@ -1,7 +1,7 @@ %import syslib psg { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused ; $1F9C0 - $1F9FF 16 blocks of 4 PSG registers (16 voices) ; 00 frequency word LSB diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 408ef08a3..97e121568 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -1,7 +1,7 @@ ; Prog8 definitions for the CommanderX16 ; Including memory registers, I/O registers, Basic and Kernal subroutines. -%option no_symbol_prefixing +%option no_symbol_prefixing, ignore_unused cbm { ; Commodore (CBM) common variables, vectors and kernal routines diff --git a/compiler/res/prog8lib/cx16/textio.p8 b/compiler/res/prog8lib/cx16/textio.p8 index ee0213cc4..d97cb8655 100644 --- a/compiler/res/prog8lib/cx16/textio.p8 +++ b/compiler/res/prog8lib/cx16/textio.p8 @@ -8,7 +8,7 @@ txt { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte DEFAULT_WIDTH = 80 const ubyte DEFAULT_HEIGHT = 60 diff --git a/compiler/res/prog8lib/cx16/verafx.p8 b/compiler/res/prog8lib/cx16/verafx.p8 index b44bca12c..bc8fdbc50 100644 --- a/compiler/res/prog8lib/cx16/verafx.p8 +++ b/compiler/res/prog8lib/cx16/verafx.p8 @@ -4,7 +4,7 @@ ; https://docs.google.com/document/d/1q34uWOiM3Be2pnaHRVgSdHySI-qsiQWPTo_gfE54PTg/edit verafx { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused sub available() -> bool { ; returns true if Vera FX is available (Vera V0.3.1 or later), false if not. diff --git a/compiler/res/prog8lib/cx16logo.p8 b/compiler/res/prog8lib/cx16logo.p8 index 7557d54e2..2e55124f2 100644 --- a/compiler/res/prog8lib/cx16logo.p8 +++ b/compiler/res/prog8lib/cx16logo.p8 @@ -3,7 +3,7 @@ %import textio cx16logo { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused sub logo_at(ubyte column, ubyte row) { uword strptr diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index 923bbb5f5..43e4e8085 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -6,7 +6,7 @@ %import syslib diskio { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte READ_IO_CHANNEL=12 const ubyte WRITE_IO_CHANNEL=13 diff --git a/compiler/res/prog8lib/floats_functions.p8 b/compiler/res/prog8lib/floats_functions.p8 index 3d1db59a8..d9d877c0c 100644 --- a/compiler/res/prog8lib/floats_functions.p8 +++ b/compiler/res/prog8lib/floats_functions.p8 @@ -1,6 +1,6 @@ floats { ; the floating point functions shared across compiler targets - %option merge, no_symbol_prefixing + %option merge, no_symbol_prefixing, ignore_unused asmsub print_f(float value @FAC1) clobbers(A,X,Y) { ; ---- prints the floating point value (without a newline). No leading space (unlike BASIC)! diff --git a/compiler/res/prog8lib/math.p8 b/compiler/res/prog8lib/math.p8 index 9b01ebaa8..086faa33c 100644 --- a/compiler/res/prog8lib/math.p8 +++ b/compiler/res/prog8lib/math.p8 @@ -3,7 +3,7 @@ ; such as abs, sqrt, clamp, min, max for example. math { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused %asminclude "library:math.asm" diff --git a/compiler/res/prog8lib/pet32/syslib.p8 b/compiler/res/prog8lib/pet32/syslib.p8 index 8cf327ca9..d4a93fb06 100644 --- a/compiler/res/prog8lib/pet32/syslib.p8 +++ b/compiler/res/prog8lib/pet32/syslib.p8 @@ -2,7 +2,7 @@ ; Including memory registers, I/O registers, Basic and Kernal subroutines. ; see: https://www.pagetable.com/?p=926 , http://www.zimmers.net/cbmpics/cbm/PETx/petmem.txt -%option no_symbol_prefixing +%option no_symbol_prefixing, ignore_unused cbm { ; Commodore (CBM) common variables, vectors and kernal routines diff --git a/compiler/res/prog8lib/pet32/textio.p8 b/compiler/res/prog8lib/pet32/textio.p8 index c64cef41e..544170577 100644 --- a/compiler/res/prog8lib/pet32/textio.p8 +++ b/compiler/res/prog8lib/pet32/textio.p8 @@ -7,7 +7,7 @@ txt { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 diff --git a/compiler/res/prog8lib/prog8_lib.p8 b/compiler/res/prog8lib/prog8_lib.p8 index 77b6a529f..3ada09470 100644 --- a/compiler/res/prog8lib/prog8_lib.p8 +++ b/compiler/res/prog8lib/prog8_lib.p8 @@ -1,7 +1,7 @@ ; Internal library routines - always included by the compiler prog8_lib { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused %asminclude "library:prog8_lib.asm" %asminclude "library:prog8_funcs.asm" diff --git a/compiler/res/prog8lib/string.p8 b/compiler/res/prog8lib/string.p8 index 6bc4cdded..915bfda4b 100644 --- a/compiler/res/prog8lib/string.p8 +++ b/compiler/res/prog8lib/string.p8 @@ -1,7 +1,7 @@ ; 0-terminated string manipulation routines. string { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused asmsub length(uword string @AY) clobbers(A) -> ubyte @Y { ; Returns the number of bytes in the string. diff --git a/compiler/res/prog8lib/test_stack.p8 b/compiler/res/prog8lib/test_stack.p8 index 6a7fa33bf..650789733 100644 --- a/compiler/res/prog8lib/test_stack.p8 +++ b/compiler/res/prog8lib/test_stack.p8 @@ -3,7 +3,7 @@ %import textio test_stack { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused asmsub test() { %asm {{ diff --git a/compiler/res/prog8lib/virtual/conv.p8 b/compiler/res/prog8lib/virtual/conv.p8 index 6611b6c82..bcda7477c 100644 --- a/compiler/res/prog8lib/virtual/conv.p8 +++ b/compiler/res/prog8lib/virtual/conv.p8 @@ -4,6 +4,8 @@ conv { ; ----- number conversions to decimal strings ---- + %option ignore_unused + str string_out = "????????????????" ; result buffer for the string conversion routines sub str_ub0(ubyte value) { diff --git a/compiler/res/prog8lib/virtual/emudbg.p8 b/compiler/res/prog8lib/virtual/emudbg.p8 index e98cc7603..f6993333a 100644 --- a/compiler/res/prog8lib/virtual/emudbg.p8 +++ b/compiler/res/prog8lib/virtual/emudbg.p8 @@ -4,6 +4,7 @@ %import textio emudbg { + %option ignore_unused sub is_emulator() -> bool { ; Test for emulator presence. diff --git a/compiler/res/prog8lib/virtual/floats.p8 b/compiler/res/prog8lib/virtual/floats.p8 index beed68e96..b7acbf724 100644 --- a/compiler/res/prog8lib/virtual/floats.p8 +++ b/compiler/res/prog8lib/virtual/floats.p8 @@ -1,6 +1,6 @@ ; Prog8 definitions for floating point handling on the VirtualMachine -%option enable_floats +%option enable_floats, ignore_unused floats { diff --git a/compiler/res/prog8lib/virtual/math.p8 b/compiler/res/prog8lib/virtual/math.p8 index a0f50c17b..a9d0aacc9 100644 --- a/compiler/res/prog8lib/virtual/math.p8 +++ b/compiler/res/prog8lib/virtual/math.p8 @@ -3,6 +3,7 @@ ; such as abs, sqrt, clamp, min, max for example. math { + %option ignore_unused sub sin8u(ubyte angle) -> ubyte { ubyte[256] sintab = [$80, $83, $86, $89, $8c, $8f, $92, $95, $98, $9b, $9e, $a2, $a5, $a7, $aa, $ad, $b0, $b3, $b6, $b9, diff --git a/compiler/res/prog8lib/virtual/monogfx.p8 b/compiler/res/prog8lib/virtual/monogfx.p8 index 74d8fe972..31c0cf7cd 100644 --- a/compiler/res/prog8lib/virtual/monogfx.p8 +++ b/compiler/res/prog8lib/virtual/monogfx.p8 @@ -7,7 +7,7 @@ monogfx { - %option no_symbol_prefixing + %option no_symbol_prefixing, ignore_unused ; read-only control variables: uword width = 0 diff --git a/compiler/res/prog8lib/virtual/prog8_lib.p8 b/compiler/res/prog8lib/virtual/prog8_lib.p8 index 359a0b248..ff2a9c8d5 100644 --- a/compiler/res/prog8lib/virtual/prog8_lib.p8 +++ b/compiler/res/prog8lib/virtual/prog8_lib.p8 @@ -1,6 +1,6 @@ ; Internal library routines - always included by the compiler prog8_lib { - %option force_output + %option force_output, ignore_unused } diff --git a/compiler/res/prog8lib/virtual/string.p8 b/compiler/res/prog8lib/virtual/string.p8 index 487df01ce..9fa2e9988 100644 --- a/compiler/res/prog8lib/virtual/string.p8 +++ b/compiler/res/prog8lib/virtual/string.p8 @@ -1,6 +1,8 @@ ; 0-terminated string manipulation routines. For the Virtual Machine target. string { + %option ignore_unused + sub length(str st) -> ubyte { ; Returns the number of bytes in the string. ; This value is determined during runtime and counts upto the first terminating 0 byte in the string, diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index d1ff3af49..17df1b6ab 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -1,5 +1,7 @@ ; Prog8 definitions for the Virtual Machine +%option ignore_unused + sys { ; ------- lowlevel system routines -------- diff --git a/compiler/res/prog8lib/virtual/textio.p8 b/compiler/res/prog8lib/virtual/textio.p8 index cda072808..7fb1aa9a6 100644 --- a/compiler/res/prog8lib/virtual/textio.p8 +++ b/compiler/res/prog8lib/virtual/textio.p8 @@ -1,6 +1,7 @@ ; Prog8 definitions for the Text I/O console routines for the Virtual Machine %import conv +%option ignore_unused txt { diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 0f08c2c43..be0983c44 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -843,16 +843,16 @@ internal class AstChecker(private val program: Program, err("this directive may only occur in a block or at module level") if(directive.args.isEmpty()) err("missing option directive argument(s)") - else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page", "merge", "splitarrays", "no_symbol_prefixing", "verafxmuls")}.any { !it }) + else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page", "merge", "verafxmuls", "splitarrays", "no_symbol_prefixing", "ignore_unused")}.any { !it }) err("invalid option directive argument(s)") if(directive.args.any {it.name=="align_word"} && directive.args.any { it.name=="align_page"}) err("conflicting alignment options") if(directive.parent is Block) { - if(directive.args.any {it.name !in arrayOf("align_word", "align_page", "no_symbol_prefixing", "force_output", "merge", "splitarrays", "verafxmuls")}) + if(directive.args.any {it.name !in arrayOf("align_word", "align_page", "force_output", "merge", "verafxmuls", "splitarrays", "no_symbol_prefixing", "ignore_unused")}) err("using an option that is not valid for blocks") } if(directive.parent is Module) { - if(directive.args.any {it.name !in arrayOf("enable_floats", "no_sysinit", "splitarrays", "no_symbol_prefixing")}) + if(directive.args.any {it.name !in arrayOf("enable_floats", "no_sysinit", "splitarrays", "no_symbol_prefixing", "ignore_unused")}) err("using an option that is not valid for modules") } if(directive.args.any { it.name=="verafxmuls" } && compilerOptions.compTarget.name != Cx16Target.NAME) diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index 78d23e813..5990e91e4 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -164,7 +164,8 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr var alignment = PtBlock.BlockAlignment.NONE var forceOutput = false var veraFxMuls = false - var noSymbolPrefixing = "no_symbol_prefixing" in srcBlock.definingModule.options() + var noSymbolPrefixing = false + var ignoreUnused = false val directives = srcBlock.statements.filterIsInstance() for (directive in directives.filter { it.directive == "%option" }) { for (arg in directive.args) { @@ -172,6 +173,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr "align_word" -> alignment = PtBlock.BlockAlignment.WORD "align_page" -> alignment = PtBlock.BlockAlignment.PAGE "no_symbol_prefixing" -> noSymbolPrefixing = true + "ignore_unused" -> ignoreUnused = true "force_output" -> forceOutput = true "merge", "splitarrays" -> { /* ignore this one */ } "verafxmuls" -> veraFxMuls = true @@ -182,7 +184,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr val (vardecls, statements) = srcBlock.statements.partition { it is VarDecl } val src = srcBlock.definingModule.source val block = PtBlock(srcBlock.name, srcBlock.isInLibrary, src, - PtBlock.Options(srcBlock.address, forceOutput, noSymbolPrefixing, veraFxMuls, alignment), + PtBlock.Options(srcBlock.address, forceOutput, noSymbolPrefixing, veraFxMuls, ignoreUnused, alignment), srcBlock.position) makeScopeVarsDecls(vardecls).forEach { block.add(it) } for (stmt in statements) diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index af912e809..81298e05c 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -14,6 +14,16 @@ import prog8.code.core.* internal class VariousCleanups(val program: Program, val errors: IErrorReporter, val options: CompilationOptions): AstWalker() { + override fun after(block: Block, parent: Node): Iterable { + val inheritOptions = block.definingModule.options() intersect setOf("splitarrays", "no_symbol_prefixing", "ignore_unused") subtract block.options() + if(inheritOptions.isNotEmpty()) { + val directive = Directive("%option", inheritOptions.map{ DirectiveArg(null, it, null, block.position) }, block.position) + return listOf(IAstModification.InsertFirst(directive, block)) + } + + return noModifications + } + override fun after(scope: AnonymousScope, parent: Node): Iterable { return if(parent is IStatementContainer) listOf(ScopeFlatten(scope, parent as IStatementContainer)) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index 598dad9ed..50894bba1 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -361,7 +361,7 @@ private fun ArrayindexContext.toAst() : ArrayIndex = ArrayIndex(expression().toAst(), toPosition()) internal fun DirectiveContext.toAst() : Directive = - Directive(directivename.text, directivearg().map { it.toAst() }, toPosition()) + Directive(DIRECTIVE().text, directivearg().map { it.toAst() }, toPosition()) private fun DirectiveargContext.toAst() : DirectiveArg { val str = stringliteral() diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index fcf8302f7..d5670d55b 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -99,6 +99,23 @@ class Block(override val name: String, data class Directive(val directive: String, val args: List, override val position: Position) : Statement() { override lateinit var parent: Node +// init { +// require(directive in arrayOf( +// "%address", +// "%asmbinary", +// "%asminclude", +// "%breakpoint", +// "%encoding", +// "%import", +// "%launcher", +// "%option", +// "%output", +// "%zeropage", +// "%zpallowed", +// "%zpreserved", +// )) { "invalid directive" } +// } + override fun linkParents(parent: Node) { this.parent = parent args.forEach{it.linkParents(this)} diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 1ccd4cca7..19c64b30e 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -147,7 +147,9 @@ Directives - ``splitarrays`` (block or module) makes all word-arrays in this scope lsb/msb split arrays (as if they all have the @split tag). See Arrays. - ``no_symbol_prefixing`` (block or module) makes the compiler *not* use symbol-prefixing when translating prog8 code into assembly. Only use this if you know what you're doing because it could result in invalid assembly code being generated. - It can be useful when writing library modules that you don't want to be exposing prefixed assembly symbols. + This option can be useful when writing library modules that you don't want to be exposing prefixed assembly symbols. + - ``ignore_unused`` (block or module) suppress warnings about unused variables and subroutines. Instead, these will be silently stripped. + This option is useful in library modules that contain many more routines beside the ones that you actually use. - ``verafxmuls`` (block, cx16 target only) uses Vera FX hardware word multiplication on the CommanderX16 for all word multiplications in this block. Warning: this may interfere with IRQs and other Vera operations, so use this only when you know what you're doing. It's safer to explicitly use ``verafx.muls()``. .. data:: %encoding diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 5b57b5e57..b6ed95eb0 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,9 +2,6 @@ TODO ==== -- add -nowarnunused, or %option ignore_unused (module and block scope), to suppress all warnings about unused symbols. Useful in libraries. - put this in all library code, like %option no_symbol_prefixing, and get rid of the "trick" it uses currently to suppress unused symbol warnings for library modules. - - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... ... diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index 1d16c2fab..2b8bf9ea3 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -350,6 +350,7 @@ class IRFileReader { attrs.getOrDefault("FORCEOUTPUT", "false").toBoolean(), attrs.getOrDefault("NOPREFIXING", "false").toBoolean(), attrs.getOrDefault("VERAFXMULS", "false").toBoolean(), + attrs.getOrDefault("IGNOREUNUSED", "false").toBoolean(), IRBlock.BlockAlignment.valueOf(attrs.getValue("ALIGN")) ), parsePosition(attrs.getValue("POS"))) diff --git a/intermediate/src/prog8/intermediate/IRFileWriter.kt b/intermediate/src/prog8/intermediate/IRFileWriter.kt index 15ac7d265..8972e0127 100644 --- a/intermediate/src/prog8/intermediate/IRFileWriter.kt +++ b/intermediate/src/prog8/intermediate/IRFileWriter.kt @@ -58,11 +58,12 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) { xml.writeStartElement("BLOCK") xml.writeAttribute("NAME", block.label) xml.writeAttribute("ADDRESS", block.options.address?.toHex() ?: "") - xml.writeAttribute("LIBRARY", block.library.toString()) - xml.writeAttribute("FORCEOUTPUT", block.options.forceOutput.toString()) - xml.writeAttribute("NOPREFIXING", block.options.noSymbolPrefixing.toString()) - xml.writeAttribute("VERAFXMULS", block.options.veraFxMuls.toString()) + if(block.options.forceOutput) xml.writeAttribute("FORCEOUTPUT", "true") + if(block.options.noSymbolPrefixing) xml.writeAttribute("NOPREFIXING", "true") + if(block.options.veraFxMuls) xml.writeAttribute("VERAFXMULS", "true") + if(block.options.ignoreUnused) xml.writeAttribute("IGNOREUNUSED", "true") xml.writeAttribute("ALIGN", block.options.alignment.toString()) + xml.writeAttribute("LIBRARY", block.library.toString()) xml.writeAttribute("POS", block.position.toString()) xml.writeCharacters("\n") block.children.forEach { child -> diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 4ac1bfb40..769eb5a1a 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -361,6 +361,7 @@ class IRBlock( val forceOutput: Boolean = false, val noSymbolPrefixing: Boolean = false, val veraFxMuls: Boolean = false, + val ignoreUnused: Boolean = false, val alignment: BlockAlignment = BlockAlignment.NONE) operator fun plusAssign(sub: IRSubroutine) { children += sub } diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index c202dd092..0128dfb43 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -34,6 +34,8 @@ INVALID_AND_COMPOSITE: '&&' ; fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ; fragment BIN_DIGIT: ('0' | '1') ; fragment DEC_DIGIT: ('0'..'9') ; +fragment LOWERCASE: ('a'..'z') ; +DIRECTIVE: '%' LOWERCASE+ ; FLOAT_NUMBER : FNUMBER (('E'|'e') ('+' | '-')? DEC_INTEGER)? ; // sign comes later from unary expression FNUMBER : FDOTNUMBER | FNUMDOTNUMBER ; @@ -128,11 +130,7 @@ labeldef : identifier ':' ; unconditionaljump : 'goto' (integerliteral | scoped_identifier) ; -directive : - directivename=('%output' | '%launcher' | '%zeropage' | '%zpreserved' | '%zpallowed' | '%address' | '%import' | - '%breakpoint' | '%asminclude' | '%asmbinary' | '%option' | '%encoding' ) - (directivearg? | directivearg (',' directivearg)*) - ; +directive : DIRECTIVE (directivearg? | directivearg (',' directivearg)*) ; directivearg : stringliteral | identifier | integerliteral ;