mirror of
https://github.com/irmen/prog8.git
synced 2025-02-08 16:30:28 +00:00
fix data type difference error on range from and to values
This commit is contained in:
parent
fee46f2e54
commit
242a3eec63
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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))
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user