fix data type difference error on range from and to values

This commit is contained in:
Irmen de Jong 2024-01-03 21:46:22 +01:00
parent fee46f2e54
commit 242a3eec63
6 changed files with 39 additions and 45 deletions

View File

@ -62,6 +62,7 @@ private fun optimizeCommonSubExpressions(program: PtProgram, errors: IErrorRepor
} }
// replace common subexpressions by a temp variable that is assigned only once. // replace common subexpressions by a temp variable that is assigned only once.
// TODO: check for commonalities across multiple separate expressions in the current scope, not only inside a single line
commons.forEach { binexpr, (occurrence1, occurrence2) -> commons.forEach { binexpr, (occurrence1, occurrence2) ->
val (stmtContainer, stmt) = findContainingStatements(binexpr) val (stmtContainer, stmt) = findContainingStatements(binexpr)
val occurrence1idx = occurrence1.parent.children.indexOf(occurrence1) val occurrence1idx = occurrence1.parent.children.indexOf(occurrence1)
@ -92,7 +93,7 @@ private fun optimizeCommonSubExpressions(program: PtProgram, errors: IErrorRepor
stmtContainer.add(0, tempvar) stmtContainer.add(0, tempvar)
tempvar.parent = stmtContainer tempvar.parent = stmtContainer
errors.info("common subexpressions replaced by a tempvar, maybe simplify the expression manually", binexpr.position) // errors.info("common subexpressions replaced by a tempvar, maybe simplify the expression manually", binexpr.position)
} }
return commons.size return commons.size

View File

@ -29,7 +29,7 @@ internal class AnyExprAsmGen(
require(expr.operator in ComparisonOperators) require(expr.operator in ComparisonOperators)
return assignFloatBinExpr(expr, assign) return assignFloatBinExpr(expr, assign)
} }
throw AssemblyError("weird expr operand types: ${expr.left.type} and {${expr.right.type}") throw AssemblyError("weird expr operand types: ${expr.left.type} and ${expr.right.type}")
} }
in WordDatatypes -> { in WordDatatypes -> {
require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) { require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {

View File

@ -586,6 +586,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
private fun transform(srcCheck: ContainmentCheck): PtExpression { private fun transform(srcCheck: ContainmentCheck): PtExpression {
fun desugar(range: RangeExpression): PtExpression { fun desugar(range: RangeExpression): PtExpression {
require(range.from.inferType(program)==range.to.inferType(program))
val expr = PtBinaryExpression("and", DataType.UBYTE, srcCheck.position) val expr = PtBinaryExpression("and", DataType.UBYTE, srcCheck.position)
val x1 = transformExpression(srcCheck.element) val x1 = transformExpression(srcCheck.element)
val x2 = transformExpression(srcCheck.element) val x2 = transformExpression(srcCheck.element)
@ -674,6 +675,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
} }
private fun transform(srcRange: RangeExpression): PtRange { private fun transform(srcRange: RangeExpression): PtRange {
require(srcRange.from.inferType(program)==srcRange.to.inferType(program))
val type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") } val type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val range=PtRange(type, srcRange.position) val range=PtRange(type, srcRange.position)
range.add(transformExpression(srcRange.from)) range.add(transformExpression(srcRange.from))

View File

@ -378,6 +378,17 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
return noModifications return noModifications
} }
override fun after(range: RangeExpression, parent: Node): Iterable<IAstModification> {
val fromDt = range.from.inferType(program).getOr(DataType.UNDEFINED)
val toDt = range.to.inferType(program).getOr(DataType.UNDEFINED)
val modifications = mutableListOf<IAstModification>()
val (commonDt, toChange) = BinaryExpression.commonDatatype(fromDt, toDt, range.from, range.to)
if(toChange!=null)
addTypecastOrCastedValueModification(modifications, toChange, commonDt, range)
return modifications
}
private fun addTypecastOrCastedValueModification( private fun addTypecastOrCastedValueModification(
modifications: MutableList<IAstModification>, modifications: MutableList<IAstModification>,
expressionToCast: Expression, expressionToCast: Expression,

View File

@ -440,4 +440,21 @@ class TestCompilerOnRanges: FunSpec({
} }
}""", writeAssembly = true) shouldNotBe null }""", writeAssembly = true) shouldNotBe null
} }
test("ranges with byte and word boundary") {
val src="""
main{
sub start() {
cx16.r0 = 500
if cx16.r0 in 127 to 5555
cx16.r0++
cx16.r0 = 50
if cx16.r0 in 5555 downto 127
cx16.r0++
}
}
"""
compileText(Cx16Target(), true, src, writeAssembly = true) shouldNotBe null
}
}) })

View File

@ -1,54 +1,17 @@
%import textio %import textio
%import floats
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
ubyte [] array = 100 to 110
for cx16.r0L in array { cx16.r0 = 500
txt.print_ub(cx16.r0L) if cx16.r0 in 127 to 5555
txt.spc() cx16.r0++
}
txt.nl()
ubyte x = 14
if x in 10 to 20 {
txt.print("yep1\n")
}
if x in 20 to 30 {
txt.print("yep2\n")
}
if x in 10 to 20 step 2 { cx16.r0 = 50
txt.print("yep1b\n") if cx16.r0 in 5555 downto 127
} cx16.r0++
if x in 20 to 30 step 2 {
txt.print("yep2b\n")
}
if x in 20 to 10 step -2 {
txt.print("yep1c\n")
}
if x in 30 to 20 step -2 {
txt.print("yep2c\n")
}
txt.nl()
ubyte @shared y = 12
if y in 10 to 20 {
txt.print("yep1\n")
}
if y in 20 to 30 {
txt.print("yep2\n")
}
if y in 20 downto 10 {
txt.print("yep1c\n")
}
if y in 30 downto 20 {
txt.print("yep2c\n")
}
} }
} }