fix regression compiler crash in string comparison

This commit is contained in:
Irmen de Jong 2022-05-08 13:45:11 +02:00
parent fef52c0112
commit dad5b17ac8
4 changed files with 59 additions and 4 deletions

View File

@ -27,7 +27,11 @@ internal class LiteralsToAutoVars(private val program: Program,
errors.err("compilation target doesn't support this text encoding", string.position)
return noModifications
}
if(string.parent !is VarDecl && string.parent !is WhenChoice && string.parent !is BinaryExpression) {
if(string.parent !is VarDecl && string.parent !is WhenChoice) {
val binExpr = string.parent as? BinaryExpression
if(binExpr!=null &&(binExpr.operator=="+" || binExpr.operator=="*"))
return noModifications // allow string concatenation or repeats later, based on just string literals
// replace the literal string by an identifier reference to the interned string
val parentFunc = (string.parent as? IFunctionCall)?.target
if(parentFunc!=null) {

View File

@ -3,7 +3,6 @@ package prog8tests
import io.kotest.assertions.fail
import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldStartWith
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
@ -753,7 +752,6 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
printProgram(result.program)
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 5
val ifStmt = stmts[4] as IfElse

View File

@ -3,9 +3,15 @@ package prog8tests.ast
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import prog8.ast.IFunctionCall
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.StringLiteral
import prog8.ast.statements.Assignment
import prog8.ast.statements.InlineAssembly
import prog8.ast.statements.VarDecl
import prog8.code.core.Position
import prog8.code.target.C64Target
import prog8.compiler.printProgram
import prog8tests.helpers.compileText
class TestVarious: FunSpec({
@ -61,5 +67,53 @@ main {
}"""
compileText(C64Target(), false, text, writeAssembly = false) shouldBe null
}
test("simple string comparison still works") {
val src="""
main {
sub start() {
ubyte @shared value
str thing = "????"
if thing=="name" {
value++
}
if thing!="name" {
value++
}
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=true)!!
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 6
}
test("string concatenation and repeats") {
val src="""
main {
sub start() {
str @shared name = "part1" + "part2"
str @shared rept = "rep"*4
const ubyte times = 3
name = "xx1" + "xx2"
rept = "xyz" * (times+1)
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=true)!!
printProgram(result.program)
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 6
val name1 = stmts[0] as VarDecl
val rept1 = stmts[1] as VarDecl
(name1.value as StringLiteral).value shouldBe "part1part2"
(rept1.value as StringLiteral).value shouldBe "reprepreprep"
val name2strcopy = stmts[3] as IFunctionCall
val rept2strcopy = stmts[4] as IFunctionCall
val name2 = name2strcopy.args.first() as IdentifierReference
val rept2 = rept2strcopy.args.first() as IdentifierReference
(name2.targetVarDecl(result.program)!!.value as StringLiteral).value shouldBe "xx1xx2"
(rept2.targetVarDecl(result.program)!!.value as StringLiteral).value shouldBe "xyzxyzxyzxyz"
}
})

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix compiler crash when comparing strings
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
Only if the arguments are simple expressions, and the inlined subroutine cannot contain further nested subroutines!
This requires all identifiers in the inlined expression to be changed to fully scoped names (because their scope changes).