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.
// TODO: check for commonalities across multiple separate expressions in the current scope, not only inside a single line
commons.forEach { binexpr, (occurrence1, occurrence2) ->
val (stmtContainer, stmt) = findContainingStatements(binexpr)
val occurrence1idx = occurrence1.parent.children.indexOf(occurrence1)
@ -92,7 +93,7 @@ private fun optimizeCommonSubExpressions(program: PtProgram, errors: IErrorRepor
stmtContainer.add(0, tempvar)
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

View File

@ -29,7 +29,7 @@ internal class AnyExprAsmGen(
require(expr.operator in ComparisonOperators)
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 -> {
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 {
fun desugar(range: RangeExpression): PtExpression {
require(range.from.inferType(program)==range.to.inferType(program))
val expr = PtBinaryExpression("and", DataType.UBYTE, srcCheck.position)
val x1 = 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 {
require(srcRange.from.inferType(program)==srcRange.to.inferType(program))
val type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val range=PtRange(type, srcRange.position)
range.add(transformExpression(srcRange.from))

View File

@ -378,6 +378,17 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
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(
modifications: MutableList<IAstModification>,
expressionToCast: Expression,

View File

@ -440,4 +440,21 @@ class TestCompilerOnRanges: FunSpec({
}
}""", 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 floats
%zeropage basicsafe
main {
sub start() {
ubyte [] array = 100 to 110
for cx16.r0L in array {
txt.print_ub(cx16.r0L)
txt.spc()
}
txt.nl()
cx16.r0 = 500
if cx16.r0 in 127 to 5555
cx16.r0++
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 {
txt.print("yep1b\n")
}
if x in 20 to 30 step 2 {
txt.print("yep2b\n")
}
cx16.r0 = 50
if cx16.r0 in 5555 downto 127
cx16.r0++
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")
}
}
}