fixed var initialization bug in anonymous scopes

This commit is contained in:
Irmen de Jong 2020-03-23 02:09:30 +01:00
parent efef205fcf
commit f89457ba68
10 changed files with 28 additions and 98 deletions

View File

@ -3,8 +3,6 @@ package prog8.ast.base
import prog8.ast.Module
import prog8.ast.Program
import prog8.ast.processing.*
import prog8.ast.statements.Block
import prog8.ast.statements.VarDecl
import prog8.compiler.CompilationOptions
import prog8.compiler.target.AsmVariablePreparer
import prog8.optimizer.FlattenAnonymousScopesAndNopRemover

View File

@ -3,9 +3,16 @@ package prog8.ast.processing
import prog8.ast.IFunctionCall
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.base.DataType
import prog8.ast.base.IterableDatatypes
import prog8.ast.base.PassByReferenceDatatypes
import prog8.ast.expressions.AddressOf
import prog8.ast.expressions.Expression
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.IdentifierReference
import prog8.ast.statements.FunctionCallStatement
import prog8.ast.statements.Statement
import prog8.ast.statements.Subroutine
import prog8.compiler.CompilerException
import prog8.functions.BuiltinFunctions
import prog8.functions.FSignature

View File

@ -4,7 +4,9 @@ import prog8.ast.IFunctionCall
import prog8.ast.INameScope
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.*
import prog8.ast.base.DataType
import prog8.ast.base.ErrorReporter
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.functions.BuiltinFunctions

View File

@ -5,11 +5,10 @@ import prog8.ast.Program
import prog8.ast.base.ErrorReporter
import prog8.ast.base.NumericDatatypes
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.IdentifierReference
import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModification
import prog8.ast.statements.AnonymousScope
import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.ast.statements.*
class AsmVariablePreparer(val program: Program, val errors: ErrorReporter): AstWalker() {
@ -35,19 +34,19 @@ class AsmVariablePreparer(val program: Program, val errors: ErrorReporter): AstW
conflicts = true
}
}
if(!conflicts)
return listOf(MoveVardecls(decls, scope, sub))
if(!conflicts) {
val numericVarsWithValue = decls.filter { it.value!=null && it.datatype in NumericDatatypes }
return numericVarsWithValue.map {
val initValue = it.value!! // assume here that value has always been set by now
it.value = null // make sure no value init assignment for this vardecl will be created later (would be superfluous)
val target = AssignTarget(null, IdentifierReference(listOf(it.name), it.position), null, null, it.position)
val assign = Assignment(target, null, initValue, it.position)
IAstModification.Insert(null, assign, scope)
} +
decls.map { IAstModification.ReplaceNode(it, NopStatement(it.position), scope) } +
decls.map { IAstModification.Insert(null, it, sub) } // move it up to the subroutine
}
}
return emptyList()
}
private class MoveVardecls(val decls: Collection<VarDecl>,
val scope: AnonymousScope,
val sub: Subroutine) : IAstModification {
override fun perform() {
decls.forEach { scope.remove(it) }
sub.statements.addAll(0, decls)
decls.forEach { it.parent = sub }
}
}
}

View File

@ -1,8 +1,6 @@
package prog8.compiler.target
import prog8.ast.Program
import prog8.ast.statements.Block
import prog8.ast.statements.VarDecl
import prog8.compiler.CompilationOptions
import prog8.compiler.Zeropage
import java.nio.file.Path

View File

@ -117,7 +117,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.translateExpression(assign.value as FunctionCall)
assignFromEvalResult(assign.target)
}
is ArrayLiteralValue, is StringLiteralValue -> TODO("string/array/struct assignment?")
is ArrayLiteralValue, is StringLiteralValue -> TODO("string/array/struct assignment? $assign")
is StructLiteralValue -> throw AssemblyError("struct literal value assignment should have been flattened ${assign.value.position}")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values ${assign.value.position}")
}

View File

@ -6,7 +6,6 @@ import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.DataType
import prog8.ast.base.ParentSentinel
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.IdentifierReference
import prog8.ast.processing.IAstVisitor

View File

@ -2,9 +2,6 @@
TODO
====
- fix manderbrot compiler issue
- remove statements after an exit() or return
- fix warnings about that unreachable code?

View File

@ -19,10 +19,6 @@ main {
ubyte pixelx
ubyte pixely
; TODO fix compiler - calculation is broken now
for pixely in 0 to height-1 {
float yy = (pixely as float)/0.4/height - 1.0

View File

@ -5,73 +5,7 @@
main {
sub subje() {
ubyte a1
ubyte a2
ubyte zz
for a1 in 1 to 3 {
ubyte qq = 100 ; TODO should be inited here, and not in the subroutine.
for a2 in 1 to 3 {
ubyte zz = 100 ; TODO should be inited here, and not in the subroutine.
c64scr.print_ub(a1)
c64.CHROUT(',')
c64scr.print_ub(a2)
c64.CHROUT(',')
c64scr.print_ub(qq) ; TODO qq shoud be 100..103 repeated three times...
c64.CHROUT(',')
c64scr.print_ub(zz) ; TODO zz should always be 100...
c64.CHROUT('\n')
qq++
zz++
}
}
}
sub start() {
subje()
c64.CHROUT('\n')
subje()
c64.CHROUT('\n')
return
; ubyte ub1
; ubyte ub2 = 99
; uword uw1
; uword uw2 = 9999
; ubyte[5] array1
; ubyte[5] array2 = [22,33,44,55,66]
;
; c64scr.print_ub(ub1)
; c64.CHROUT(',')
; c64scr.print_ub(ub2)
; c64.CHROUT(',')
; c64scr.print_uw(uw1)
; c64.CHROUT(',')
; c64scr.print_uw(uw2)
; c64.CHROUT(',')
; c64scr.print_ub(array1[0])
; c64.CHROUT(',')
; c64scr.print_ub(array2[0])
; c64.CHROUT('\n')
;
; ub1++
; ub2++
; uw1++
; uw2++
; array1[0]++
; array2[0]++
;
; c64scr.print_ub(ub1)
; c64.CHROUT(',')
; c64scr.print_ub(ub2)
; c64.CHROUT(',')
; c64scr.print_uw(uw1)
; c64.CHROUT(',')
; c64scr.print_uw(uw2)
; c64.CHROUT(',')
; c64scr.print_ub(array1[0])
; c64.CHROUT(',')
; c64scr.print_ub(array2[0])
; c64.CHROUT('\n')
}
}