mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
main block element order now remains the same as in source
This commit is contained in:
parent
df1793efbf
commit
922033c1b2
@ -202,16 +202,10 @@ internal class ProgramAndVarsGen(
|
||||
asmsubs2asm(block.statements)
|
||||
|
||||
asmgen.out("")
|
||||
asmgen.out("; subroutines in this block")
|
||||
|
||||
// First translate regular statements, and then put the subroutines at the end.
|
||||
// (regular statements = everything except the initialization assignments;
|
||||
// these will be part of the prog8_init_vars init routine generated below)
|
||||
val initializers = blockVariableInitializers.getValue(block)
|
||||
val statements = block.statements.filterNot { it in initializers }
|
||||
val (subroutine, stmts) = statements.partition { it is Subroutine }
|
||||
stmts.forEach { asmgen.translate(it) }
|
||||
subroutine.forEach { asmgen.translate(it) }
|
||||
val notInitializers = block.statements.filterNot { it in initializers }
|
||||
notInitializers.forEach { asmgen.translate(it) }
|
||||
|
||||
if(!options.dontReinitGlobals) {
|
||||
// generate subroutine to initialize block-level (global) variables
|
||||
|
@ -1122,7 +1122,7 @@ class IRCodeGen(
|
||||
irBlock += IRInlineBinaryChunk(null, readBinaryData(child), null)
|
||||
}
|
||||
is PtLabel -> {
|
||||
TODO("allow label inside block scope ${child.name}")
|
||||
irBlock += IRCodeChunk(child.name, null)
|
||||
}
|
||||
else -> TODO("weird child node $child")
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOpt
|
||||
callGraph.checkRecursiveCalls(errors)
|
||||
program.verifyFunctionArgTypes(errors)
|
||||
errors.report()
|
||||
program.moveMainAndStartToFirst()
|
||||
program.moveMainBlockAsFirst()
|
||||
program.checkValid(errors, compilerOptions) // check if final tree is still valid
|
||||
errors.report()
|
||||
}
|
||||
|
@ -129,35 +129,19 @@ internal fun Program.variousCleanups(errors: IErrorReporter, options: Compilatio
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Program.moveMainAndStartToFirst() {
|
||||
internal fun Program.moveMainBlockAsFirst() {
|
||||
// The module containing the program entrypoint is moved to the first in the sequence.
|
||||
// the "main" block containing the entrypoint is moved to the top in there,
|
||||
// and finally the entrypoint subroutine "start" itself is moved to the top in that block.
|
||||
// the "main" block containing the entrypoint is moved to the top in there.
|
||||
|
||||
// sortModules()
|
||||
val directives = modules[0].statements.filterIsInstance<Directive>()
|
||||
val start = this.entrypoint
|
||||
val mod = start.definingModule
|
||||
val block = start.definingBlock
|
||||
moveModuleToFront(mod)
|
||||
mod.remove(block)
|
||||
var afterDirective = mod.statements.indexOfFirst { it !is Directive }
|
||||
val module = this.entrypoint.definingModule
|
||||
val block = this.entrypoint.definingBlock
|
||||
moveModuleToFront(module)
|
||||
module.remove(block)
|
||||
val afterDirective = module.statements.indexOfFirst { it !is Directive }
|
||||
if(afterDirective<0)
|
||||
mod.statements.add(block)
|
||||
module.statements.add(block)
|
||||
else
|
||||
mod.statements.add(afterDirective, block)
|
||||
block.remove(start)
|
||||
afterDirective = block.statements.indexOfFirst { it !is Directive }
|
||||
if(afterDirective<0)
|
||||
block.statements.add(start)
|
||||
else
|
||||
block.statements.add(afterDirective, start)
|
||||
|
||||
// overwrite the directives in the module containing the entrypoint
|
||||
for(directive in directives) {
|
||||
modules[0].statements.removeAll { it is Directive && it.directive == directive.directive }
|
||||
modules[0].statements.add(0, directive)
|
||||
}
|
||||
module.statements.add(afterDirective, block)
|
||||
}
|
||||
|
||||
internal fun IdentifierReference.isSubroutineParameter(program: Program): Boolean {
|
||||
|
@ -37,11 +37,6 @@ internal class BeforeAsmAstChanger(val program: Program,
|
||||
}
|
||||
|
||||
override fun before(block: Block, parent: Node): Iterable<IAstModification> {
|
||||
// move all subroutines to the bottom of the block
|
||||
val subs = block.statements.filterIsInstance<Subroutine>()
|
||||
block.statements.removeAll(subs)
|
||||
block.statements.addAll(subs)
|
||||
|
||||
// adjust global variables initialization
|
||||
if(options.dontReinitGlobals) {
|
||||
block.statements.asSequence().filterIsInstance<VarDecl>().forEach {
|
||||
|
@ -3,6 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- make it so that uword xx = <byte constant> <op> expr is treated as <word constant> <op> <expr> instead (or inverse order)
|
||||
- ir/vm: allow label in block scope
|
||||
- regression test the various projects
|
||||
- 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
|
||||
|
@ -1,8 +1,25 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
|
||||
alsostart:
|
||||
sub start() {
|
||||
uword xx = 100
|
||||
uword yy = xx / 256 ; TODO hangs in optimizer for 6502
|
||||
yy++
|
||||
|
||||
internalstart:
|
||||
txt.print_uwhex(start, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(alsostart, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(internalstart, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(startend, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(internalend, true)
|
||||
txt.nl()
|
||||
internalend:
|
||||
}
|
||||
|
||||
startend:
|
||||
|
||||
}
|
||||
|
@ -222,6 +222,11 @@ class IRBlock(
|
||||
operator fun plusAssign(sub: IRAsmSubroutine) { asmSubroutines += sub }
|
||||
operator fun plusAssign(asm: IRInlineAsmChunk) { inlineAssemblies += asm }
|
||||
operator fun plusAssign(binary: IRInlineBinaryChunk) { inlineBinaries += binary }
|
||||
operator fun plusAssign(irCodeChunk: IRCodeChunk) {
|
||||
// this is for a separate label in the block scope. (random code statements are not allowed)
|
||||
require(irCodeChunk.isEmpty() && irCodeChunk.label!=null)
|
||||
TODO("allow labels in block scope, ${irCodeChunk.label}")
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
val noAsm = inlineAssemblies.isEmpty() || inlineAssemblies.all { it.isEmpty() }
|
||||
@ -230,6 +235,7 @@ class IRBlock(
|
||||
val noBins = inlineBinaries.isEmpty() || inlineBinaries.all { it.isEmpty() }
|
||||
return noAsm && noSubs && noAsmSubs && noBins
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class IRSubroutine(val name: String,
|
||||
|
Loading…
x
Reference in New Issue
Block a user