fix compiler crash on hoisting certain vardecls from inner scopes

This commit is contained in:
Irmen de Jong 2022-12-22 18:49:53 +01:00
parent 4e103a1963
commit d0e6a2eb8b
5 changed files with 35 additions and 9 deletions

View File

@ -120,16 +120,19 @@ class AstPreprocessor(val program: Program,
movements.add(IAstModification.InsertFirst(decl, parentscope))
replacements.add(IAstModification.Remove(decl, scope))
} else {
val declToInsert: VarDecl
if(decl.value!=null && decl.datatype in NumericDatatypes) {
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
val assign = Assignment(target, decl.value!!, AssignmentOrigin.VARINIT, decl.position)
replacements.add(IAstModification.ReplaceNode(decl, assign, scope))
decl.value = null
decl.allowInitializeWithZero = false
declToInsert = decl.copy()
} else {
replacements.add(IAstModification.Remove(decl, scope))
declToInsert = decl
}
movements.add(IAstModification.InsertFirst(decl, parentscope))
movements.add(IAstModification.InsertFirst(declToInsert, parentscope))
}
}
return movements + replacements
@ -138,12 +141,10 @@ class AstPreprocessor(val program: Program,
}
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
// this has to be done here becuse otherwise the string / range literal values will have been replaced by variables
if(expr.operator=="in") {
val containment = ContainmentCheck(expr.left, expr.right, expr.position)
return listOf(IAstModification.ReplaceNode(expr, containment, parent))
}
return noModifications
}

View File

@ -163,4 +163,12 @@ _after:
}
return noModifications
}
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
if(expr.operator=="in") {
val containment = ContainmentCheck(expr.left, expr.right, expr.position)
return listOf(IAstModification.ReplaceNode(expr, containment, parent))
}
return noModifications
}
}

View File

@ -913,7 +913,7 @@ class TestProg8Parser: FunSpec( {
val text="""
main {
sub start() {
ubyte cc
ubyte @shared cc
ubyte[] array = [1,2,3]
cc = 99 in 12345
cc = 9999 in array

View File

@ -3,11 +3,9 @@ package prog8tests.ast
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.types.instanceOf
import prog8.ast.IFunctionCall
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.NumericLiteral
import prog8.ast.expressions.StringLiteral
import prog8.ast.statements.Assignment
import prog8.ast.statements.InlineAssembly
@ -15,7 +13,6 @@ import prog8.ast.statements.VarDecl
import prog8.code.core.DataType
import prog8.code.core.Position
import prog8.code.target.C64Target
import prog8.compiler.printProgram
import prog8tests.helpers.compileText
class TestVarious: FunSpec({
@ -148,7 +145,6 @@ main {
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
printProgram(result.program)
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 7
val assign1expr = (stmts[3] as Assignment).value as BinaryExpression
@ -161,5 +157,27 @@ main {
leftval2.type shouldBe DataType.UWORD
leftval2.number shouldBe 1.0
}
test("hoisting vars with complex initializer expressions to outer scope") {
val src="""
main {
sub pget(uword @zp x, uword y) -> ubyte {
return lsb(x+y)
}
sub start() {
uword[128] YY
ubyte[] ARRAY = [1, 5, 2]
repeat {
ubyte pixel_side1 = pget(2, YY[2]+1) in ARRAY
ubyte pixel_side2 = pget(2, 2) in ARRAY
ubyte[] array2 = [1,2,3]
}
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 9
}
})

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix compiler crash on : bool bb = gfx2.pget(pilex1, flakes1_yy[idx]+1) in PILED_SNOW_COLORS
- bool bb = not bb -> larger code than bool bb ^= 1
- bool xx = ~xx -> larger code than xx ^= 1
- ubyte xx = not xx -> much larger code than xx ^= 1