mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 05:29:38 +00:00
fix compiler crash on hoisting certain vardecls from inner scopes
This commit is contained in:
parent
4e103a1963
commit
d0e6a2eb8b
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user