fix regression: don't add 0 initializer when variable is assigned to anyway (or is loopvar in a for-loop)

This commit is contained in:
Irmen de Jong 2021-11-02 21:23:59 +01:00
parent bc0a133bb1
commit 3410aea788
3 changed files with 12 additions and 4 deletions

View File

@ -10,6 +10,7 @@ prog8_lib {
word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
byte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size)
; NOTE: these variables are checked in the StatementReorderer (in fun after(decl: VarDecl)), for these exact names!
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
%asm {{

View File

@ -47,12 +47,20 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
if (decl.value == null) {
if (!decl.autogeneratedDontRemove && decl.allowInitializeWithZero) {
// A numeric vardecl without an initial value is initialized with zero,
// unless there's already an assignment below, that initializes the value.
// unless there's already an assignment below it, that initializes the value (or a for loop that uses it as loopvar).
// This allows you to restart the program and have the same starting values of the variables
// So basically consider 'ubyte xx' as a short form for 'ubyte xx; xx=0'
decl.value = null
val nextAssign = decl.nextSibling() as? Assignment
if (nextAssign == null || !(nextAssign.target isSameAs IdentifierReference(listOf(decl.name), Position.DUMMY))) {
if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") {
// no need to zero out the special internal returnvalue intermediates.
return noModifications
}
val nextStmt = decl.nextSibling()
val nextAssign = nextStmt as? Assignment
val nextFor = nextStmt as? ForLoop
val hasNextForWithThisLoopvar = nextFor?.loopVar?.nameInSource==listOf(decl.name)
val hasNextAssignment = nextAssign!=null && nextAssign.target isSameAs IdentifierReference(listOf(decl.name), Position.DUMMY)
if (!hasNextAssignment && !hasNextForWithThisLoopvar) {
// Add assignment to initialize with zero
// Note: for block-level vars, this will introduce assignments in the block scope. These have to be dealt with correctly later.
val identifier = IdentifierReference(listOf(decl.name), decl.position)

View File

@ -6,7 +6,6 @@ For next compiler release (7.2)
- fix the asm-labels problem (github issue #62)
- find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack?
- analyze (and fix?): TODO why are these bigger now than before the var-initializer optimization:
; wizzine
; wormfood
; cube3d-float (THIS ONE IS A LOT BIGGER!!)
; cube3d-sprites