mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
improve the way %option merge works, you can now merge your own code with library code for instance.
This commit is contained in:
parent
ad14c88fde
commit
42db3085df
@ -110,14 +110,18 @@ class ModuleImporter(private val program: Program,
|
||||
// their content has to be merged into already existing other block with the same name.
|
||||
val blocks = importedModule.statements.filterIsInstance<Block>()
|
||||
for(block in blocks) {
|
||||
if("merge" in block.options()) {
|
||||
val existingBlock = program.allBlocks.firstOrNull { it.name==block.name && it !== block}
|
||||
if(existingBlock!=null) {
|
||||
val blockHasMergeOption = "merge" in block.options()
|
||||
val existingBlock = program.allBlocks.firstOrNull { it.name==block.name && it !== block}
|
||||
if(existingBlock!=null) {
|
||||
val existingBlockHasMergeOption = "merge" in existingBlock.options()
|
||||
if (blockHasMergeOption || existingBlockHasMergeOption) {
|
||||
// transplant the contents
|
||||
existingBlock.statements.addAll(block.statements.filter { it !is Directive })
|
||||
importedModule.statements.remove(block)
|
||||
} else {
|
||||
val merges = block.statements.filter { it is Directive && it.directive=="%option" && it.args.any { a->a.name=="merge" } }
|
||||
block.statements.removeAll(merges.toSet())
|
||||
|
||||
if(blockHasMergeOption && !existingBlockHasMergeOption) {
|
||||
existingBlock.statements.add(0, Directive("%option", listOf(DirectiveArg(null, "merge", null, block.position)), block.position))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,13 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
|
||||
override fun visit(block: Block) {
|
||||
val existing = blocks[block.name]
|
||||
if(existing!=null) {
|
||||
if(block.isInLibrary)
|
||||
nameError(existing.name, existing.position, block)
|
||||
else
|
||||
nameError(block.name, block.position, existing)
|
||||
// we allow duplicates if at least one of them has %option merge
|
||||
if("merge" !in existing.options() + block.options()) {
|
||||
if (block.isInLibrary)
|
||||
nameError(existing.name, existing.position, block)
|
||||
else
|
||||
nameError(block.name, block.position, existing)
|
||||
}
|
||||
}
|
||||
else
|
||||
blocks[block.name] = block
|
||||
|
@ -3,10 +3,12 @@ package prog8tests
|
||||
import io.kotest.assertions.withClue
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldStartWith
|
||||
import prog8.code.core.ZeropageType
|
||||
import prog8.code.core.internedStringsModuleName
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8.compiler.determineCompilationOptions
|
||||
import prog8.compiler.parseMainModule
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
@ -108,4 +110,29 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
test("merge option works on library modules") {
|
||||
val src="""
|
||||
%zeropage basicsafe
|
||||
%import textio
|
||||
|
||||
txt {
|
||||
%option merge
|
||||
sub println(uword string) {
|
||||
txt.print(string)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
txt.lowercase()
|
||||
txt.println("Hello, world1")
|
||||
txt.println("Hello, world2")
|
||||
txt.println("Hello, world3")
|
||||
}
|
||||
}"""
|
||||
compileText(VMTarget(), optimize = false, src) shouldNotBe null
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
@ -143,7 +143,7 @@ Directives
|
||||
Warning: if you use this to align array variables in the block, these have to be initialized with a value to make them stay in the block and get aligned properly. Otherwise they'll end up at a random spot in the BSS section and the alignment doesn't apply there.
|
||||
- ``align_page`` (in a block) will make the assembler align the start address of this block on a page boundary in memory (so, the LSB of the address is 0).
|
||||
Warning: if you use this to align array variables in the block, these have to be initialized with a value to make them stay in the block and get aligned properly. Otherwise they'll end up at a random spot in the BSS section and the alignment doesn't apply there.
|
||||
- ``merge`` (in a block) will merge this block's contents into an already existing block with the same name. Useful in library scenarios.
|
||||
- ``merge`` (in a block) will merge this block's contents into an already existing block with the same name. Useful in library scenarios. Can result in a bunch of unused symbol warnings, this depends on the import order.
|
||||
- ``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) 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.
|
||||
|
@ -2,8 +2,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- improve the working of %option merge: should be able to merge your own stuff into say textio. , and improve the docs about it too.
|
||||
|
||||
- [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: ir-less-branch-opcodes] IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? Bitwise operations, etc), but only after setting the status bits is verified!
|
||||
|
@ -1,15 +1,19 @@
|
||||
%zeropage basicsafe
|
||||
%import textio
|
||||
|
||||
txt {
|
||||
%option merge
|
||||
sub println(uword string) {
|
||||
txt.print(string)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
str name = "thing"
|
||||
modify(name)
|
||||
|
||||
sub modify(str arg) {
|
||||
ubyte n=1
|
||||
uword pointervar
|
||||
arg[n+1] = arg[1]
|
||||
pointervar[n+1] = pointervar[1]
|
||||
}
|
||||
txt.lowercase()
|
||||
txt.println("Hello, world1")
|
||||
txt.println("Hello, world2")
|
||||
txt.println("Hello, world3")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user