mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
added %option ignore_unused to suppress warnings about unused vars and subs in that module/block.
Also improved error for invalid directive.
This commit is contained in:
parent
2eb137618e
commit
2b8f613a00
@ -86,6 +86,7 @@ class PtBlock(name: String,
|
|||||||
val forceOutput: Boolean = false,
|
val forceOutput: Boolean = false,
|
||||||
val noSymbolPrefixing: Boolean = false,
|
val noSymbolPrefixing: Boolean = false,
|
||||||
val veraFxMuls: Boolean = false,
|
val veraFxMuls: Boolean = false,
|
||||||
|
val ignoreUnused: Boolean = false,
|
||||||
val alignment: BlockAlignment = BlockAlignment.NONE)
|
val alignment: BlockAlignment = BlockAlignment.NONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1667,6 +1667,7 @@ class IRCodeGen(
|
|||||||
block.options.forceOutput,
|
block.options.forceOutput,
|
||||||
block.options.noSymbolPrefixing,
|
block.options.noSymbolPrefixing,
|
||||||
block.options.veraFxMuls,
|
block.options.veraFxMuls,
|
||||||
|
block.options.ignoreUnused,
|
||||||
translate(block.options.alignment)
|
translate(block.options.alignment)
|
||||||
), block.position)
|
), block.position)
|
||||||
for (child in block.children) {
|
for (child in block.children) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package prog8.codegen.intermediate
|
package prog8.codegen.intermediate
|
||||||
|
|
||||||
import prog8.code.core.IErrorReporter
|
import prog8.code.core.IErrorReporter
|
||||||
import prog8.code.core.SourceCode.Companion.LIBRARYFILEPREFIX
|
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ class IRUnusedCodeRemover(
|
|||||||
irprog.blocks.forEach { block ->
|
irprog.blocks.forEach { block ->
|
||||||
block.children.filterIsInstance<IRSubroutine>().reversed().forEach { sub ->
|
block.children.filterIsInstance<IRSubroutine>().reversed().forEach { sub ->
|
||||||
if(sub.isEmpty()) {
|
if(sub.isEmpty()) {
|
||||||
if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) {
|
if(!block.options.ignoreUnused) {
|
||||||
errors.warn("unused subroutine '${sub.label}'", sub.position)
|
errors.warn("unused subroutine '${sub.label}'", sub.position)
|
||||||
}
|
}
|
||||||
block.children.remove(sub)
|
block.children.remove(sub)
|
||||||
@ -82,7 +81,7 @@ class IRUnusedCodeRemover(
|
|||||||
irprog.blocks.forEach { block ->
|
irprog.blocks.forEach { block ->
|
||||||
block.children.filterIsInstance<IRAsmSubroutine>().reversed().forEach { sub ->
|
block.children.filterIsInstance<IRAsmSubroutine>().reversed().forEach { sub ->
|
||||||
if(sub.isEmpty()) {
|
if(sub.isEmpty()) {
|
||||||
if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) {
|
if(!block.options.ignoreUnused) {
|
||||||
errors.warn("unused subroutine '${sub.label}'", sub.position)
|
errors.warn("unused subroutine '${sub.label}'", sub.position)
|
||||||
}
|
}
|
||||||
block.children.remove(sub)
|
block.children.remove(sub)
|
||||||
|
@ -90,7 +90,7 @@ class UnusedCodeRemover(private val program: Program,
|
|||||||
if (subroutine !== program.entrypoint && !forceOutput && !subroutine.isAsmSubroutine) {
|
if (subroutine !== program.entrypoint && !forceOutput && !subroutine.isAsmSubroutine) {
|
||||||
if(callgraph.unused(subroutine)) {
|
if(callgraph.unused(subroutine)) {
|
||||||
if(subroutine.containsNoCodeNorVars) {
|
if(subroutine.containsNoCodeNorVars) {
|
||||||
if(!subroutine.definingModule.isLibrary)
|
if("ignore_unused" !in subroutine.definingBlock.options())
|
||||||
errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position)
|
errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position)
|
||||||
val removals = mutableListOf(IAstModification.Remove(subroutine, parent as IStatementContainer))
|
val removals = mutableListOf(IAstModification.Remove(subroutine, parent as IStatementContainer))
|
||||||
callgraph.calledBy[subroutine]?.let {
|
callgraph.calledBy[subroutine]?.let {
|
||||||
@ -99,7 +99,7 @@ class UnusedCodeRemover(private val program: Program,
|
|||||||
}
|
}
|
||||||
return removals
|
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)
|
errors.warn("unused subroutine '${subroutine.name}'", subroutine.position)
|
||||||
}
|
}
|
||||||
if(!subroutine.inline) {
|
if(!subroutine.inline) {
|
||||||
@ -119,7 +119,7 @@ class UnusedCodeRemover(private val program: Program,
|
|||||||
if (!forceOutput && decl.origin==VarDeclOrigin.USERCODE && !decl.sharedWithAsm) {
|
if (!forceOutput && decl.origin==VarDeclOrigin.USERCODE && !decl.sharedWithAsm) {
|
||||||
val usages = callgraph.usages(decl)
|
val usages = callgraph.usages(decl)
|
||||||
if (usages.isEmpty()) {
|
if (usages.isEmpty()) {
|
||||||
if(!decl.definingModule.isLibrary)
|
if("ignore_unused" !in decl.definingBlock.options())
|
||||||
errors.warn("removing unused variable '${decl.name}'", decl.position)
|
errors.warn("removing unused variable '${decl.name}'", decl.position)
|
||||||
return listOf(IAstModification.Remove(decl, parent as IStatementContainer))
|
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!=null && assignment.origin==AssignmentOrigin.VARINIT) {
|
||||||
if(assignment.value.isSimple) {
|
if(assignment.value.isSimple) {
|
||||||
// remove the vardecl
|
// remove the vardecl
|
||||||
if(!decl.definingModule.isLibrary)
|
if("ignore_unused" !in decl.definingBlock.options())
|
||||||
errors.warn("removing unused variable '${decl.name}'", decl.position)
|
errors.warn("removing unused variable '${decl.name}'", decl.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
IAstModification.Remove(decl, parent as IStatementContainer),
|
IAstModification.Remove(decl, parent as IStatementContainer),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Prog8 definitions for the Atari800XL
|
; Prog8 definitions for the Atari800XL
|
||||||
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
atari {
|
atari {
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
txt {
|
txt {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte DEFAULT_WIDTH = 40
|
const ubyte DEFAULT_WIDTH = 40
|
||||||
const ubyte DEFAULT_HEIGHT = 24
|
const ubyte DEFAULT_HEIGHT = 24
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Prog8 definitions for the Commodore-128
|
; Prog8 definitions for the Commodore-128
|
||||||
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
cbm {
|
cbm {
|
||||||
; Commodore (CBM) common variables, vectors and kernal routines
|
; Commodore (CBM) common variables, vectors and kernal routines
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
txt {
|
txt {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte DEFAULT_WIDTH = 40
|
const ubyte DEFAULT_WIDTH = 40
|
||||||
const ubyte DEFAULT_HEIGHT = 25
|
const ubyte DEFAULT_HEIGHT = 25
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Prog8 definitions for floating point handling on the Commodore-64
|
; 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
|
%import floats_functions
|
||||||
|
|
||||||
floats {
|
floats {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
; so that the program itself can be larger without starting to overwrite the graphics memory.
|
; so that the program itself can be larger without starting to overwrite the graphics memory.
|
||||||
|
|
||||||
graphics {
|
graphics {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const uword WIDTH = 320
|
const uword WIDTH = 320
|
||||||
const ubyte HEIGHT = 200
|
const ubyte HEIGHT = 200
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Prog8 definitions for the Commodore-64
|
; Prog8 definitions for the Commodore-64
|
||||||
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
cbm {
|
cbm {
|
||||||
; Commodore (CBM) common variables, vectors and kernal routines
|
; Commodore (CBM) common variables, vectors and kernal routines
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
txt {
|
txt {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte DEFAULT_WIDTH = 40
|
const ubyte DEFAULT_WIDTH = 40
|
||||||
const ubyte DEFAULT_HEIGHT = 25
|
const ubyte DEFAULT_HEIGHT = 25
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
conv {
|
conv {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
; ----- number conversions to decimal strings ----
|
; ----- number conversions to decimal strings ----
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
%import syslib
|
%import syslib
|
||||||
|
|
||||||
diskio {
|
diskio {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte READ_IO_CHANNEL=12
|
const ubyte READ_IO_CHANNEL=12
|
||||||
const ubyte WRITE_IO_CHANNEL=13
|
const ubyte WRITE_IO_CHANNEL=13
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Prog8 definitions for floating point handling on the CommanderX16
|
; 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
|
%import floats_functions
|
||||||
|
|
||||||
floats {
|
floats {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
gfx2 {
|
gfx2 {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
; read-only control variables:
|
; read-only control variables:
|
||||||
ubyte active_mode = 0
|
ubyte active_mode = 0
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
|
|
||||||
graphics {
|
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
|
romsub $feff = FB_cursor_position2() clobbers(A,X,Y) ; alias for the normal FB_cursor_position() call but reuses existing r0 and r1
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
monogfx {
|
monogfx {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
; read-only control variables:
|
; read-only control variables:
|
||||||
uword width = 0
|
uword width = 0
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
; The first 16 colors can be restored to their default with set_default16()
|
; The first 16 colors can be restored to their default with set_default16()
|
||||||
|
|
||||||
palette {
|
palette {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
uword vera_palette_ptr
|
uword vera_palette_ptr
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%import syslib
|
%import syslib
|
||||||
|
|
||||||
psg {
|
psg {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
; $1F9C0 - $1F9FF 16 blocks of 4 PSG registers (16 voices)
|
; $1F9C0 - $1F9FF 16 blocks of 4 PSG registers (16 voices)
|
||||||
; 00 frequency word LSB
|
; 00 frequency word LSB
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Prog8 definitions for the CommanderX16
|
; Prog8 definitions for the CommanderX16
|
||||||
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
cbm {
|
cbm {
|
||||||
; Commodore (CBM) common variables, vectors and kernal routines
|
; Commodore (CBM) common variables, vectors and kernal routines
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
txt {
|
txt {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte DEFAULT_WIDTH = 80
|
const ubyte DEFAULT_WIDTH = 80
|
||||||
const ubyte DEFAULT_HEIGHT = 60
|
const ubyte DEFAULT_HEIGHT = 60
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
; https://docs.google.com/document/d/1q34uWOiM3Be2pnaHRVgSdHySI-qsiQWPTo_gfE54PTg/edit
|
; https://docs.google.com/document/d/1q34uWOiM3Be2pnaHRVgSdHySI-qsiQWPTo_gfE54PTg/edit
|
||||||
|
|
||||||
verafx {
|
verafx {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
sub available() -> bool {
|
sub available() -> bool {
|
||||||
; returns true if Vera FX is available (Vera V0.3.1 or later), false if not.
|
; returns true if Vera FX is available (Vera V0.3.1 or later), false if not.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
|
||||||
cx16logo {
|
cx16logo {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
sub logo_at(ubyte column, ubyte row) {
|
sub logo_at(ubyte column, ubyte row) {
|
||||||
uword strptr
|
uword strptr
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
%import syslib
|
%import syslib
|
||||||
|
|
||||||
diskio {
|
diskio {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte READ_IO_CHANNEL=12
|
const ubyte READ_IO_CHANNEL=12
|
||||||
const ubyte WRITE_IO_CHANNEL=13
|
const ubyte WRITE_IO_CHANNEL=13
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
floats {
|
floats {
|
||||||
; the floating point functions shared across compiler targets
|
; 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) {
|
asmsub print_f(float value @FAC1) clobbers(A,X,Y) {
|
||||||
; ---- prints the floating point value (without a newline). No leading space (unlike BASIC)!
|
; ---- prints the floating point value (without a newline). No leading space (unlike BASIC)!
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
; such as abs, sqrt, clamp, min, max for example.
|
; such as abs, sqrt, clamp, min, max for example.
|
||||||
|
|
||||||
math {
|
math {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
%asminclude "library:math.asm"
|
%asminclude "library:math.asm"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
; Including memory registers, I/O registers, Basic and Kernal subroutines.
|
; 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
|
; 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 {
|
cbm {
|
||||||
; Commodore (CBM) common variables, vectors and kernal routines
|
; Commodore (CBM) common variables, vectors and kernal routines
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
txt {
|
txt {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
const ubyte DEFAULT_WIDTH = 40
|
const ubyte DEFAULT_WIDTH = 40
|
||||||
const ubyte DEFAULT_HEIGHT = 25
|
const ubyte DEFAULT_HEIGHT = 25
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Internal library routines - always included by the compiler
|
; Internal library routines - always included by the compiler
|
||||||
|
|
||||||
prog8_lib {
|
prog8_lib {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
%asminclude "library:prog8_lib.asm"
|
%asminclude "library:prog8_lib.asm"
|
||||||
%asminclude "library:prog8_funcs.asm"
|
%asminclude "library:prog8_funcs.asm"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; 0-terminated string manipulation routines.
|
; 0-terminated string manipulation routines.
|
||||||
|
|
||||||
string {
|
string {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
asmsub length(uword string @AY) clobbers(A) -> ubyte @Y {
|
asmsub length(uword string @AY) clobbers(A) -> ubyte @Y {
|
||||||
; Returns the number of bytes in the string.
|
; Returns the number of bytes in the string.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
|
||||||
test_stack {
|
test_stack {
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
asmsub test() {
|
asmsub test() {
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -4,6 +4,8 @@ conv {
|
|||||||
|
|
||||||
; ----- number conversions to decimal strings ----
|
; ----- number conversions to decimal strings ----
|
||||||
|
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
str string_out = "????????????????" ; result buffer for the string conversion routines
|
str string_out = "????????????????" ; result buffer for the string conversion routines
|
||||||
|
|
||||||
sub str_ub0(ubyte value) {
|
sub str_ub0(ubyte value) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
|
||||||
emudbg {
|
emudbg {
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
sub is_emulator() -> bool {
|
sub is_emulator() -> bool {
|
||||||
; Test for emulator presence.
|
; Test for emulator presence.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Prog8 definitions for floating point handling on the VirtualMachine
|
; Prog8 definitions for floating point handling on the VirtualMachine
|
||||||
|
|
||||||
%option enable_floats
|
%option enable_floats, ignore_unused
|
||||||
|
|
||||||
floats {
|
floats {
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
; such as abs, sqrt, clamp, min, max for example.
|
; such as abs, sqrt, clamp, min, max for example.
|
||||||
|
|
||||||
math {
|
math {
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
sub sin8u(ubyte angle) -> ubyte {
|
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,
|
ubyte[256] sintab = [$80, $83, $86, $89, $8c, $8f, $92, $95, $98, $9b, $9e, $a2, $a5, $a7, $aa, $ad, $b0, $b3, $b6, $b9,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
monogfx {
|
monogfx {
|
||||||
|
|
||||||
%option no_symbol_prefixing
|
%option no_symbol_prefixing, ignore_unused
|
||||||
|
|
||||||
; read-only control variables:
|
; read-only control variables:
|
||||||
uword width = 0
|
uword width = 0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; Internal library routines - always included by the compiler
|
; Internal library routines - always included by the compiler
|
||||||
|
|
||||||
prog8_lib {
|
prog8_lib {
|
||||||
%option force_output
|
%option force_output, ignore_unused
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
; 0-terminated string manipulation routines. For the Virtual Machine target.
|
; 0-terminated string manipulation routines. For the Virtual Machine target.
|
||||||
|
|
||||||
string {
|
string {
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
sub length(str st) -> ubyte {
|
sub length(str st) -> ubyte {
|
||||||
; Returns the number of bytes in the string.
|
; 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,
|
; This value is determined during runtime and counts upto the first terminating 0 byte in the string,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
; Prog8 definitions for the Virtual Machine
|
; Prog8 definitions for the Virtual Machine
|
||||||
|
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
sys {
|
sys {
|
||||||
; ------- lowlevel system routines --------
|
; ------- lowlevel system routines --------
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
; Prog8 definitions for the Text I/O console routines for the Virtual Machine
|
; Prog8 definitions for the Text I/O console routines for the Virtual Machine
|
||||||
|
|
||||||
%import conv
|
%import conv
|
||||||
|
%option ignore_unused
|
||||||
|
|
||||||
txt {
|
txt {
|
||||||
|
|
||||||
|
@ -843,16 +843,16 @@ internal class AstChecker(private val program: Program,
|
|||||||
err("this directive may only occur in a block or at module level")
|
err("this directive may only occur in a block or at module level")
|
||||||
if(directive.args.isEmpty())
|
if(directive.args.isEmpty())
|
||||||
err("missing option directive argument(s)")
|
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)")
|
err("invalid option directive argument(s)")
|
||||||
if(directive.args.any {it.name=="align_word"} && directive.args.any { it.name=="align_page"})
|
if(directive.args.any {it.name=="align_word"} && directive.args.any { it.name=="align_page"})
|
||||||
err("conflicting alignment options")
|
err("conflicting alignment options")
|
||||||
if(directive.parent is Block) {
|
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")
|
err("using an option that is not valid for blocks")
|
||||||
}
|
}
|
||||||
if(directive.parent is Module) {
|
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")
|
err("using an option that is not valid for modules")
|
||||||
}
|
}
|
||||||
if(directive.args.any { it.name=="verafxmuls" } && compilerOptions.compTarget.name != Cx16Target.NAME)
|
if(directive.args.any { it.name=="verafxmuls" } && compilerOptions.compTarget.name != Cx16Target.NAME)
|
||||||
|
@ -164,7 +164,8 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
|||||||
var alignment = PtBlock.BlockAlignment.NONE
|
var alignment = PtBlock.BlockAlignment.NONE
|
||||||
var forceOutput = false
|
var forceOutput = false
|
||||||
var veraFxMuls = false
|
var veraFxMuls = false
|
||||||
var noSymbolPrefixing = "no_symbol_prefixing" in srcBlock.definingModule.options()
|
var noSymbolPrefixing = false
|
||||||
|
var ignoreUnused = false
|
||||||
val directives = srcBlock.statements.filterIsInstance<Directive>()
|
val directives = srcBlock.statements.filterIsInstance<Directive>()
|
||||||
for (directive in directives.filter { it.directive == "%option" }) {
|
for (directive in directives.filter { it.directive == "%option" }) {
|
||||||
for (arg in directive.args) {
|
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_word" -> alignment = PtBlock.BlockAlignment.WORD
|
||||||
"align_page" -> alignment = PtBlock.BlockAlignment.PAGE
|
"align_page" -> alignment = PtBlock.BlockAlignment.PAGE
|
||||||
"no_symbol_prefixing" -> noSymbolPrefixing = true
|
"no_symbol_prefixing" -> noSymbolPrefixing = true
|
||||||
|
"ignore_unused" -> ignoreUnused = true
|
||||||
"force_output" -> forceOutput = true
|
"force_output" -> forceOutput = true
|
||||||
"merge", "splitarrays" -> { /* ignore this one */ }
|
"merge", "splitarrays" -> { /* ignore this one */ }
|
||||||
"verafxmuls" -> veraFxMuls = true
|
"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 (vardecls, statements) = srcBlock.statements.partition { it is VarDecl }
|
||||||
val src = srcBlock.definingModule.source
|
val src = srcBlock.definingModule.source
|
||||||
val block = PtBlock(srcBlock.name, srcBlock.isInLibrary, src,
|
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)
|
srcBlock.position)
|
||||||
makeScopeVarsDecls(vardecls).forEach { block.add(it) }
|
makeScopeVarsDecls(vardecls).forEach { block.add(it) }
|
||||||
for (stmt in statements)
|
for (stmt in statements)
|
||||||
|
@ -14,6 +14,16 @@ import prog8.code.core.*
|
|||||||
|
|
||||||
internal class VariousCleanups(val program: Program, val errors: IErrorReporter, val options: CompilationOptions): AstWalker() {
|
internal class VariousCleanups(val program: Program, val errors: IErrorReporter, val options: CompilationOptions): AstWalker() {
|
||||||
|
|
||||||
|
override fun after(block: Block, parent: Node): Iterable<IAstModification> {
|
||||||
|
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<IAstModification> {
|
override fun after(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
|
||||||
return if(parent is IStatementContainer)
|
return if(parent is IStatementContainer)
|
||||||
listOf(ScopeFlatten(scope, parent as IStatementContainer))
|
listOf(ScopeFlatten(scope, parent as IStatementContainer))
|
||||||
|
@ -361,7 +361,7 @@ private fun ArrayindexContext.toAst() : ArrayIndex =
|
|||||||
ArrayIndex(expression().toAst(), toPosition())
|
ArrayIndex(expression().toAst(), toPosition())
|
||||||
|
|
||||||
internal fun DirectiveContext.toAst() : Directive =
|
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 {
|
private fun DirectiveargContext.toAst() : DirectiveArg {
|
||||||
val str = stringliteral()
|
val str = stringliteral()
|
||||||
|
@ -99,6 +99,23 @@ class Block(override val name: String,
|
|||||||
data class Directive(val directive: String, val args: List<DirectiveArg>, override val position: Position) : Statement() {
|
data class Directive(val directive: String, val args: List<DirectiveArg>, override val position: Position) : Statement() {
|
||||||
override lateinit var parent: Node
|
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) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
args.forEach{it.linkParents(this)}
|
args.forEach{it.linkParents(this)}
|
||||||
|
@ -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.
|
- ``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.
|
- ``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.
|
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()``.
|
- ``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 <encodingname>
|
.. data:: %encoding <encodingname>
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
TODO
|
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 ....
|
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -350,6 +350,7 @@ class IRFileReader {
|
|||||||
attrs.getOrDefault("FORCEOUTPUT", "false").toBoolean(),
|
attrs.getOrDefault("FORCEOUTPUT", "false").toBoolean(),
|
||||||
attrs.getOrDefault("NOPREFIXING", "false").toBoolean(),
|
attrs.getOrDefault("NOPREFIXING", "false").toBoolean(),
|
||||||
attrs.getOrDefault("VERAFXMULS", "false").toBoolean(),
|
attrs.getOrDefault("VERAFXMULS", "false").toBoolean(),
|
||||||
|
attrs.getOrDefault("IGNOREUNUSED", "false").toBoolean(),
|
||||||
IRBlock.BlockAlignment.valueOf(attrs.getValue("ALIGN"))
|
IRBlock.BlockAlignment.valueOf(attrs.getValue("ALIGN"))
|
||||||
),
|
),
|
||||||
parsePosition(attrs.getValue("POS")))
|
parsePosition(attrs.getValue("POS")))
|
||||||
|
@ -58,11 +58,12 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
|||||||
xml.writeStartElement("BLOCK")
|
xml.writeStartElement("BLOCK")
|
||||||
xml.writeAttribute("NAME", block.label)
|
xml.writeAttribute("NAME", block.label)
|
||||||
xml.writeAttribute("ADDRESS", block.options.address?.toHex() ?: "")
|
xml.writeAttribute("ADDRESS", block.options.address?.toHex() ?: "")
|
||||||
xml.writeAttribute("LIBRARY", block.library.toString())
|
if(block.options.forceOutput) xml.writeAttribute("FORCEOUTPUT", "true")
|
||||||
xml.writeAttribute("FORCEOUTPUT", block.options.forceOutput.toString())
|
if(block.options.noSymbolPrefixing) xml.writeAttribute("NOPREFIXING", "true")
|
||||||
xml.writeAttribute("NOPREFIXING", block.options.noSymbolPrefixing.toString())
|
if(block.options.veraFxMuls) xml.writeAttribute("VERAFXMULS", "true")
|
||||||
xml.writeAttribute("VERAFXMULS", block.options.veraFxMuls.toString())
|
if(block.options.ignoreUnused) xml.writeAttribute("IGNOREUNUSED", "true")
|
||||||
xml.writeAttribute("ALIGN", block.options.alignment.toString())
|
xml.writeAttribute("ALIGN", block.options.alignment.toString())
|
||||||
|
xml.writeAttribute("LIBRARY", block.library.toString())
|
||||||
xml.writeAttribute("POS", block.position.toString())
|
xml.writeAttribute("POS", block.position.toString())
|
||||||
xml.writeCharacters("\n")
|
xml.writeCharacters("\n")
|
||||||
block.children.forEach { child ->
|
block.children.forEach { child ->
|
||||||
|
@ -361,6 +361,7 @@ class IRBlock(
|
|||||||
val forceOutput: Boolean = false,
|
val forceOutput: Boolean = false,
|
||||||
val noSymbolPrefixing: Boolean = false,
|
val noSymbolPrefixing: Boolean = false,
|
||||||
val veraFxMuls: Boolean = false,
|
val veraFxMuls: Boolean = false,
|
||||||
|
val ignoreUnused: Boolean = false,
|
||||||
val alignment: BlockAlignment = BlockAlignment.NONE)
|
val alignment: BlockAlignment = BlockAlignment.NONE)
|
||||||
|
|
||||||
operator fun plusAssign(sub: IRSubroutine) { children += sub }
|
operator fun plusAssign(sub: IRSubroutine) { children += sub }
|
||||||
|
@ -34,6 +34,8 @@ INVALID_AND_COMPOSITE: '&&' ;
|
|||||||
fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ;
|
fragment HEX_DIGIT: ('a'..'f') | ('A'..'F') | ('0'..'9') ;
|
||||||
fragment BIN_DIGIT: ('0' | '1') ;
|
fragment BIN_DIGIT: ('0' | '1') ;
|
||||||
fragment DEC_DIGIT: ('0'..'9') ;
|
fragment DEC_DIGIT: ('0'..'9') ;
|
||||||
|
fragment LOWERCASE: ('a'..'z') ;
|
||||||
|
DIRECTIVE: '%' LOWERCASE+ ;
|
||||||
|
|
||||||
FLOAT_NUMBER : FNUMBER (('E'|'e') ('+' | '-')? DEC_INTEGER)? ; // sign comes later from unary expression
|
FLOAT_NUMBER : FNUMBER (('E'|'e') ('+' | '-')? DEC_INTEGER)? ; // sign comes later from unary expression
|
||||||
FNUMBER : FDOTNUMBER | FNUMDOTNUMBER ;
|
FNUMBER : FDOTNUMBER | FNUMDOTNUMBER ;
|
||||||
@ -128,11 +130,7 @@ labeldef : identifier ':' ;
|
|||||||
|
|
||||||
unconditionaljump : 'goto' (integerliteral | scoped_identifier) ;
|
unconditionaljump : 'goto' (integerliteral | scoped_identifier) ;
|
||||||
|
|
||||||
directive :
|
directive : DIRECTIVE (directivearg? | directivearg (',' directivearg)*) ;
|
||||||
directivename=('%output' | '%launcher' | '%zeropage' | '%zpreserved' | '%zpallowed' | '%address' | '%import' |
|
|
||||||
'%breakpoint' | '%asminclude' | '%asmbinary' | '%option' | '%encoding' )
|
|
||||||
(directivearg? | directivearg (',' directivearg)*)
|
|
||||||
;
|
|
||||||
|
|
||||||
directivearg : stringliteral | identifier | integerliteral ;
|
directivearg : stringliteral | identifier | integerliteral ;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user