mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +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 noSymbolPrefixing: Boolean = false,
|
||||
val veraFxMuls: Boolean = false,
|
||||
val ignoreUnused: Boolean = false,
|
||||
val alignment: BlockAlignment = BlockAlignment.NONE)
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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<IRSubroutine>().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<IRAsmSubroutine>().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)
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
conv {
|
||||
|
||||
%option no_symbol_prefixing
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
; ----- number conversions to decimal strings ----
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
gfx2 {
|
||||
|
||||
%option no_symbol_prefixing
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
; read-only control variables:
|
||||
ubyte active_mode = 0
|
||||
|
@ -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
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
monogfx {
|
||||
|
||||
%option no_symbol_prefixing
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
; read-only control variables:
|
||||
uword width = 0
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)!
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -3,7 +3,7 @@
|
||||
%import textio
|
||||
|
||||
test_stack {
|
||||
%option no_symbol_prefixing
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
asmsub test() {
|
||||
%asm {{
|
||||
|
@ -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) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
%import textio
|
||||
|
||||
emudbg {
|
||||
%option ignore_unused
|
||||
|
||||
sub is_emulator() -> bool {
|
||||
; Test for emulator presence.
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Prog8 definitions for floating point handling on the VirtualMachine
|
||||
|
||||
%option enable_floats
|
||||
%option enable_floats, ignore_unused
|
||||
|
||||
floats {
|
||||
|
||||
|
@ -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,
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
monogfx {
|
||||
|
||||
%option no_symbol_prefixing
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
; read-only control variables:
|
||||
uword width = 0
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Internal library routines - always included by the compiler
|
||||
|
||||
prog8_lib {
|
||||
%option force_output
|
||||
%option force_output, ignore_unused
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -1,5 +1,7 @@
|
||||
; Prog8 definitions for the Virtual Machine
|
||||
|
||||
%option ignore_unused
|
||||
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
; Prog8 definitions for the Text I/O console routines for the Virtual Machine
|
||||
|
||||
%import conv
|
||||
%option ignore_unused
|
||||
|
||||
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")
|
||||
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)
|
||||
|
@ -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<Directive>()
|
||||
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)
|
||||
|
@ -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<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> {
|
||||
return if(parent is IStatementContainer)
|
||||
listOf(ScopeFlatten(scope, parent as IStatementContainer))
|
||||
|
@ -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()
|
||||
|
@ -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() {
|
||||
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)}
|
||||
|
@ -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 <encodingname>
|
||||
|
@ -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 ....
|
||||
|
||||
...
|
||||
|
@ -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")))
|
||||
|
@ -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 ->
|
||||
|
@ -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 }
|
||||
|
@ -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 ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user