mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 04:30:03 +00:00
actually (re)initialize block level variables with their init values
This commit is contained in:
parent
3a8f069854
commit
c4a28b8502
@ -10,6 +10,9 @@ fun Module.reorderStatements(namespace: INameScope, heap: HeapValues) {
|
|||||||
this.process(checker)
|
this.process(checker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const val initvarsSubName="prog8_init_vars" // the name of the subroutine that should be called for every block to initialize its variables
|
||||||
|
|
||||||
|
|
||||||
private class StatementReorderer(private val namespace: INameScope, private val heap: HeapValues): IAstProcessor {
|
private class StatementReorderer(private val namespace: INameScope, private val heap: HeapValues): IAstProcessor {
|
||||||
// Reorders the statements in a way the compiler needs.
|
// Reorders the statements in a way the compiler needs.
|
||||||
// - 'main' block must be the very first statement UNLESS it has an address set.
|
// - 'main' block must be the very first statement UNLESS it has an address set.
|
||||||
@ -93,6 +96,19 @@ private class StatementReorderer(private val namespace: INameScope, private val
|
|||||||
|
|
||||||
sortConstantAssignments(block.statements)
|
sortConstantAssignments(block.statements)
|
||||||
|
|
||||||
|
val varInits = block.statements.withIndex().filter { it.value is VariableInitializationAssignment }
|
||||||
|
if(varInits.isNotEmpty()) {
|
||||||
|
val statements = varInits.map{it.value}.toMutableList()
|
||||||
|
val varInitSub = Subroutine(initvarsSubName, emptyList(), emptyList(), emptyList(), emptyList(),
|
||||||
|
emptySet(), null, false, statements, block.position)
|
||||||
|
varInitSub.linkParents(block)
|
||||||
|
block.statements.add(varInitSub)
|
||||||
|
|
||||||
|
// remove the varinits from the block's statements
|
||||||
|
for(index in varInits.map{it.index}.reversed())
|
||||||
|
block.statements.removeAt(index)
|
||||||
|
}
|
||||||
|
|
||||||
return super.process(block)
|
return super.process(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +173,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out(" ldx #\$ff\t; init estack pointer")
|
out(" ldx #\$ff\t; init estack pointer")
|
||||||
|
out(" ; initialize the variables in each block")
|
||||||
|
for(block in program.blocks) {
|
||||||
|
val initVarsLabel = block.instructions.firstOrNull { it is LabelInstr && it.name==initvarsSubName } as? LabelInstr
|
||||||
|
if(initVarsLabel!=null)
|
||||||
|
out(" jsr ${block.scopedname}.${initVarsLabel.name}")
|
||||||
|
}
|
||||||
out(" clc")
|
out(" clc")
|
||||||
out(" jmp main.start\t; jump to program entrypoint")
|
out(" jmp main.start\t; jump to program entrypoint")
|
||||||
out("")
|
out("")
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
|
ubyte[256] sieve
|
||||||
|
ubyte candidate_prime = 2
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
; clear the sieve, and mark 0 and 1 as not prime.
|
memset(sieve, 256, false) ; clear the sieve
|
||||||
memset(sieve, 256, false)
|
|
||||||
sieve[0] = true
|
|
||||||
sieve[1] = true
|
|
||||||
|
|
||||||
; calculate primes
|
; calculate primes
|
||||||
c64scr.print("prime numbers up to 255:\n\n")
|
c64scr.print("prime numbers up to 255:\n\n")
|
||||||
@ -21,21 +20,21 @@
|
|||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
ubyte[256] sieve
|
|
||||||
|
|
||||||
sub find_next_prime() -> ubyte {
|
sub find_next_prime() -> ubyte {
|
||||||
for ubyte prime in 2 to 255 {
|
while sieve[candidate_prime] {
|
||||||
if not sieve[prime] {
|
candidate_prime++
|
||||||
; found one, mark the multiples and return it.
|
if candidate_prime==0
|
||||||
sieve[prime] = true
|
return 0 ; we wrapped; no more primes available in the sieve
|
||||||
uword multiple = prime**2
|
|
||||||
while multiple < len(sieve) {
|
|
||||||
sieve[lsb(multiple)] = true
|
|
||||||
multiple += prime
|
|
||||||
}
|
|
||||||
return prime
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0
|
|
||||||
|
; found next one, mark the multiples and return it.
|
||||||
|
sieve[candidate_prime] = true
|
||||||
|
uword multiple = candidate_prime**2
|
||||||
|
while multiple < len(sieve) {
|
||||||
|
sieve[lsb(multiple)] = true
|
||||||
|
multiple += candidate_prime
|
||||||
|
}
|
||||||
|
return candidate_prime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,17 @@
|
|||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
|
ubyte xx=99
|
||||||
|
word yy=12345
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
while true {
|
c64scr.print_ub(xx)
|
||||||
A=99
|
c64.CHROUT('\n')
|
||||||
}
|
c64scr.print_w(yy)
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
while true {
|
foo.derp()
|
||||||
A=99
|
foo2.derp()
|
||||||
if A>100
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
A=99
|
|
||||||
} until false
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
A=99
|
|
||||||
if A>100
|
|
||||||
break
|
|
||||||
} until false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -33,3 +24,21 @@
|
|||||||
; push_byte ub:01
|
; push_byte ub:01
|
||||||
; jnz _prog8stmt_7_loop
|
; jnz _prog8stmt_7_loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~ foo {
|
||||||
|
|
||||||
|
ubyte woo=2
|
||||||
|
|
||||||
|
sub derp() {
|
||||||
|
A=woo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ foo2 {
|
||||||
|
|
||||||
|
sub derp() {
|
||||||
|
ubyte woo=3
|
||||||
|
A=99
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user