mirror of
https://github.com/irmen/prog8.git
synced 2025-02-21 10:29:03 +00:00
User defined blocks are sorted first, before library blocks. This prioritizes zero page allocation to user code (and makes reading the program easier)
This commit is contained in:
parent
86ff08e854
commit
f83b9732ee
@ -506,11 +506,11 @@ private class GlobalNamespace(override val name: String,
|
|||||||
class Block(override val name: String,
|
class Block(override val name: String,
|
||||||
val address: Int?,
|
val address: Int?,
|
||||||
override var statements: MutableList<IStatement>,
|
override var statements: MutableList<IStatement>,
|
||||||
|
val isInLibrary: Boolean,
|
||||||
override val position: Position) : IStatement, INameScope {
|
override val position: Position) : IStatement, INameScope {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
val scopedname: String by lazy { makeScopedName(name).joinToString(".") }
|
val scopedname: String by lazy { makeScopedName(name).joinToString(".") }
|
||||||
|
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
statements.forEach {it.linkParents(this)}
|
statements.forEach {it.linkParents(this)}
|
||||||
@ -1754,7 +1754,7 @@ class RepeatLoop(var body: AnonymousScope,
|
|||||||
/***************** Antlr Extension methods to create AST ****************/
|
/***************** Antlr Extension methods to create AST ****************/
|
||||||
|
|
||||||
fun prog8Parser.ModuleContext.toAst(name: String, isLibrary: Boolean, importedFrom: Path) : Module =
|
fun prog8Parser.ModuleContext.toAst(name: String, isLibrary: Boolean, importedFrom: Path) : Module =
|
||||||
Module(name, modulestatement().asSequence().map { it.toAst() }.toMutableList(), toPosition(), isLibrary, importedFrom)
|
Module(name, modulestatement().asSequence().map { it.toAst(isLibrary) }.toMutableList(), toPosition(), isLibrary, importedFrom)
|
||||||
|
|
||||||
|
|
||||||
private fun ParserRuleContext.toPosition() : Position {
|
private fun ParserRuleContext.toPosition() : Position {
|
||||||
@ -1768,19 +1768,19 @@ private fun ParserRuleContext.toPosition() : Position {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun prog8Parser.ModulestatementContext.toAst() : IStatement {
|
private fun prog8Parser.ModulestatementContext.toAst(isInLibrary: Boolean) : IStatement {
|
||||||
val directive = directive()?.toAst()
|
val directive = directive()?.toAst()
|
||||||
if(directive!=null) return directive
|
if(directive!=null) return directive
|
||||||
|
|
||||||
val block = block()?.toAst()
|
val block = block()?.toAst(isInLibrary)
|
||||||
if(block!=null) return block
|
if(block!=null) return block
|
||||||
|
|
||||||
throw FatalAstException(text)
|
throw FatalAstException(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun prog8Parser.BlockContext.toAst() : IStatement =
|
private fun prog8Parser.BlockContext.toAst(isInLibrary: Boolean) : IStatement =
|
||||||
Block(identifier().text, integerliteral()?.toAst()?.number?.toInt(), statement_block().toAst(), toPosition())
|
Block(identifier().text, integerliteral()?.toAst()?.number?.toInt(), statement_block().toAst(), isInLibrary, toPosition())
|
||||||
|
|
||||||
|
|
||||||
private fun prog8Parser.Statement_blockContext.toAst(): MutableList<IStatement> =
|
private fun prog8Parser.Statement_blockContext.toAst(): MutableList<IStatement> =
|
||||||
|
@ -33,11 +33,21 @@ private class StatementReorderer(private val namespace: INameScope, private val
|
|||||||
val (blocks, other) = module.statements.partition { it is Block }
|
val (blocks, other) = module.statements.partition { it is Block }
|
||||||
module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: Int.MAX_VALUE }).toMutableList()
|
module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: Int.MAX_VALUE }).toMutableList()
|
||||||
|
|
||||||
|
// make sure user-defined blocks come BEFORE library blocks, and move the "main" block to the top of everything
|
||||||
|
val nonLibraryBlocks = module.statements.withIndex()
|
||||||
|
.filter { it.value is Block && !(it.value as Block).isInLibrary }
|
||||||
|
.map { it.index to it.value }
|
||||||
|
.reversed()
|
||||||
|
for(blocks in nonLibraryBlocks)
|
||||||
|
module.statements.removeAt(blocks.first)
|
||||||
|
for(blocks in nonLibraryBlocks)
|
||||||
|
module.statements.add(0, blocks.second)
|
||||||
val mainBlock = module.statements.single { it is Block && it.name=="main" }
|
val mainBlock = module.statements.single { it is Block && it.name=="main" }
|
||||||
if((mainBlock as Block).address==null) {
|
if((mainBlock as Block).address==null) {
|
||||||
module.statements.remove(mainBlock)
|
module.statements.remove(mainBlock)
|
||||||
module.statements.add(0, mainBlock)
|
module.statements.add(0, mainBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
val varDecls = module.statements.filterIsInstance<VarDecl>()
|
val varDecls = module.statements.filterIsInstance<VarDecl>()
|
||||||
module.statements.removeAll(varDecls)
|
module.statements.removeAll(varDecls)
|
||||||
module.statements.addAll(0, varDecls)
|
module.statements.addAll(0, varDecls)
|
||||||
@ -46,8 +56,6 @@ private class StatementReorderer(private val namespace: INameScope, private val
|
|||||||
module.statements.removeAll(directives)
|
module.statements.removeAll(directives)
|
||||||
module.statements.addAll(0, directives)
|
module.statements.addAll(0, directives)
|
||||||
|
|
||||||
// TODO make sure user-defined blocks come BEFORE library blocks
|
|
||||||
|
|
||||||
sortConstantAssignments(module.statements)
|
sortConstantAssignments(module.statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ Add more compiler optimizations to the existing ones.
|
|||||||
- on the final assembly source level
|
- on the final assembly source level
|
||||||
- can the parameter passing to subroutines be optimized to avoid copying?
|
- can the parameter passing to subroutines be optimized to avoid copying?
|
||||||
|
|
||||||
- make sure user-defined blocks come BEFORE library blocks (this helps zeropage variable allocations)
|
|
||||||
- subroutines with 1 or 2 byte args (or 1 word arg) should be converted to asm calling convention with the args in A/Y register
|
- subroutines with 1 or 2 byte args (or 1 word arg) should be converted to asm calling convention with the args in A/Y register
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,27 +4,23 @@
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
foo(1)
|
myblock2.foo()
|
||||||
foo2(20)
|
myblock3.foo()
|
||||||
bar(2,3)
|
|
||||||
baz(3333)
|
|
||||||
baz(-3333)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub foo(ubyte arg) {
|
|
||||||
A=arg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub foo2(byte arg) {
|
~ myblock2 {
|
||||||
A=33
|
|
||||||
|
sub foo() {
|
||||||
|
A=99
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub bar(ubyte arg1, ubyte arg2) {
|
|
||||||
A=arg1
|
|
||||||
}
|
|
||||||
|
|
||||||
sub baz(word arg) {
|
~ myblock3 {
|
||||||
A=lsb(arg)
|
|
||||||
|
sub foo() {
|
||||||
|
A=99
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/docs/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/gradle" />
|
<excludeFolder url="file://$MODULE_DIR$/gradle" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/out" />
|
<excludeFolder url="file://$MODULE_DIR$/out" />
|
||||||
</content>
|
</content>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user