mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 04:30:03 +00:00
fix expression simplification issue
This commit is contained in:
parent
a825bbff96
commit
ab73353cd2
@ -5,41 +5,28 @@
|
||||
|
||||
~ main {
|
||||
|
||||
str str1 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789abcde"
|
||||
str_p str2 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789abcde"
|
||||
str_s str3 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789abcde"
|
||||
str_ps str4 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789abcde"
|
||||
|
||||
byte[256] barr2 = 2 ; @todo weird init error
|
||||
byte[256] barr3 = 3 ; @todo weird init error
|
||||
byte[256] barr2b ; @todo weird init error
|
||||
byte[256] barr3b ; @todo weird init error
|
||||
|
||||
ubyte[256] ubarr2 = 2 ; @todo weird init error
|
||||
ubyte[256] ubarr3 = 3 ; @todo weird init error
|
||||
ubyte[256] ubarr2b ; @todo weird init error
|
||||
ubyte[256] ubarr3b ; @todo weird init error
|
||||
|
||||
|
||||
word[128] warr2 = 2 ; @todo weird init error
|
||||
word[128] warr3 = 3 ; @todo weird init error
|
||||
word[128] warr2b ; @todo weird init error
|
||||
word[128] warr3b ; @todo weird init error
|
||||
|
||||
uword[128] wbarr2 = 2 ; @todo weird init error
|
||||
uword[128] wbarr3 = 3 ; @todo weird init error
|
||||
uword[128] wbarr2b ; @todo weird init error
|
||||
uword[128] wbarr3b ; @todo weird init error
|
||||
|
||||
|
||||
byte[256,257] bmatrix ; @todo weird init error
|
||||
ubyte[256,257] ubmatrix ; @todo weird init error
|
||||
|
||||
|
||||
; @todo later: allow for arrays/matrixes with length > 256 (uword index)
|
||||
|
||||
|
||||
sub start() {
|
||||
|
||||
const uword width = 160
|
||||
const uword height = 128
|
||||
ubyte pixely = 255
|
||||
const ubyte yoffset = 50
|
||||
|
||||
float y11a = (pixely-30)
|
||||
float y11b = (pixely-30)/128
|
||||
float y11c = (pixely-30)/128/3.6
|
||||
float y11d = (pixely-30)/500+0.4
|
||||
float y11e = (pixely-30)/128/3.6+0.4
|
||||
float y11f = flt(pixely-30)/128/3.6+0.4
|
||||
float y111 = (((pixely-30)))/128/3.6+0.4
|
||||
float y1 = (pixely-yoffset)/128/3.6+0.4
|
||||
float y1a = flt(pixely-yoffset)/128/3.6+0.4
|
||||
float y1a2 = (flt(pixely-yoffset))/128/3.6+0.4
|
||||
float y1b = (pixely-40)/128/3.6+0.4
|
||||
float y1c = (pixely-40.0)/128/3.6+0.4
|
||||
float y2 = flt((pixely-yoffset))/128.0/3.6+0.4
|
||||
float y3 = flt((pixely-yoffset))/height/3.6+0.4
|
||||
float y4 = flt((pixely-yoffset))/height/3.6+0.4
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -763,6 +763,10 @@ class BinaryExpression(var left: IExpression, var operator: String, var right: I
|
||||
right.linkParents(this)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "[$left $operator $right]"
|
||||
}
|
||||
|
||||
// binary expression should actually have been optimized away into a single value, before const value was requested...
|
||||
override fun constValue(namespace: INameScope, heap: HeapValues): LiteralValue? = null
|
||||
override fun isIterable(namespace: INameScope, heap: HeapValues) = false
|
||||
@ -962,18 +966,17 @@ class LiteralValue(val type: DataType,
|
||||
}
|
||||
|
||||
fun optimalNumeric(value: Number, position: Position): LiteralValue {
|
||||
val floatval = value.toDouble()
|
||||
return if(floatval == floor(floatval) && floatval in -32768..65535) {
|
||||
// the floating point value is actually an integer.
|
||||
when (floatval) {
|
||||
in 0..255 -> LiteralValue(DataType.UBYTE, bytevalue=floatval.toShort(), position = position)
|
||||
in -128..127 -> LiteralValue(DataType.BYTE, bytevalue=floatval.toShort(), position = position)
|
||||
in 0..65535 -> LiteralValue(DataType.UWORD, wordvalue = floatval.toInt(), position = position)
|
||||
in -32768..32767 -> LiteralValue(DataType.WORD, wordvalue = floatval.toInt(), position = position)
|
||||
else -> LiteralValue(DataType.FLOAT, floatvalue = floatval, position = position)
|
||||
}
|
||||
return if(value is Double) {
|
||||
LiteralValue(DataType.FLOAT, floatvalue = value, position = position)
|
||||
} else {
|
||||
LiteralValue(DataType.FLOAT, floatvalue = floatval, position = position)
|
||||
val intval = value.toInt()
|
||||
when (intval) {
|
||||
in 0..255 -> LiteralValue(DataType.UBYTE, bytevalue=intval.toShort(), position = position)
|
||||
in -128..127 -> LiteralValue(DataType.BYTE, bytevalue=intval.toShort(), position = position)
|
||||
in 0..65535 -> LiteralValue(DataType.UWORD, wordvalue = intval, position = position)
|
||||
in -32768..32767 -> LiteralValue(DataType.WORD, wordvalue = intval, position = position)
|
||||
else -> LiteralValue(DataType.FLOAT, floatvalue = intval.toDouble(), position = position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,7 +1015,7 @@ class LiteralValue(val type: DataType,
|
||||
val asIntegerValue: Int? = when {
|
||||
bytevalue!=null -> bytevalue.toInt()
|
||||
wordvalue!=null -> wordvalue
|
||||
floatvalue!=null -> floor(floatvalue).toInt()
|
||||
// don't round a float value, otherwise code will not detect that it's not an integer
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
@ -204,11 +204,9 @@ class ConstExprEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun divideByZeroError(pos: Position): Unit =
|
||||
throw ExpressionError("division by zero", pos)
|
||||
|
||||
|
||||
private fun divide(left: LiteralValue, right: LiteralValue): LiteralValue {
|
||||
val error = "cannot divide $left by $right"
|
||||
return when {
|
||||
|
@ -229,6 +229,10 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
* and ITS other operand is NOT a Constant,
|
||||
* ...it may be possible to rewrite the expression to group the two Constants together,
|
||||
* to allow them to be const-folded away.
|
||||
*
|
||||
* examples include:
|
||||
* (X / c1) * c2 -> X / (c2/c1)
|
||||
* (X + c1) - c2 -> X + (c1-c2)
|
||||
*/
|
||||
override fun process(expr: BinaryExpression): IExpression {
|
||||
return try {
|
||||
@ -244,11 +248,12 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
if(subExpr!=null) {
|
||||
val subleftconst = subExpr.left.constValue(namespace, heap)
|
||||
val subrightconst = subExpr.right.constValue(namespace, heap)
|
||||
if ((subleftconst != null && subrightconst == null) || (subleftconst==null && subrightconst!=null))
|
||||
if ((subleftconst != null && subrightconst == null) || (subleftconst==null && subrightconst!=null)) {
|
||||
// try reordering.
|
||||
return groupTwoConstsTogether(expr, subExpr,
|
||||
leftconst!=null, rightconst!=null,
|
||||
subleftconst!=null, subrightconst!=null)
|
||||
leftconst != null, rightconst != null,
|
||||
subleftconst != null, subrightconst != null)
|
||||
}
|
||||
}
|
||||
|
||||
// const fold when both operands are a const
|
||||
@ -298,30 +303,33 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
if(expr.operator=="-" || expr.operator=="/") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst) {
|
||||
if(subleftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
val tmp = subExpr.right
|
||||
subExpr.right = subExpr.left
|
||||
subExpr.left = expr.left
|
||||
expr.left = tmp
|
||||
expr.operator = if(expr.operator=="-") "+" else "*"
|
||||
expr
|
||||
} else
|
||||
return BinaryExpression(
|
||||
BinaryExpression(
|
||||
BinaryExpression(expr.left, if(expr.operator=="-") "+" else "*", subExpr.right, subExpr.position),
|
||||
expr.operator, subExpr.left, expr.position)
|
||||
} else {
|
||||
if(subleftIsConst)
|
||||
expr.right = subExpr.right.also {subExpr.right = expr.right}
|
||||
else
|
||||
return BinaryExpression(
|
||||
return if(subleftIsConst) {
|
||||
expr.right = subExpr.right.also { subExpr.right = expr.right }
|
||||
expr
|
||||
} else
|
||||
BinaryExpression(
|
||||
subExpr.left, expr.operator,
|
||||
BinaryExpression(expr.right, if(expr.operator=="-") "+" else "*", subExpr.right, subExpr.position),
|
||||
expr.position)
|
||||
}
|
||||
return expr
|
||||
}
|
||||
return expr
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(expr.operator=="/" && subExpr.operator=="*") {
|
||||
optimizationsDone++
|
||||
@ -354,7 +362,8 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="*" && subExpr.operator=="/") {
|
||||
}
|
||||
else if(expr.operator=="*" && subExpr.operator=="/") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
@ -385,7 +394,9 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="+" && subExpr.operator=="-") {
|
||||
}
|
||||
else if(expr.operator=="+" && subExpr.operator=="-") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst){
|
||||
return if(subleftIsConst){
|
||||
// c1+(c2-v) -> (c1+c2)-v
|
||||
@ -415,7 +426,9 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
subExpr.left, expr.position)
|
||||
}
|
||||
}
|
||||
} else if(expr.operator=="-" && subExpr.operator=="+") {
|
||||
}
|
||||
else if(expr.operator=="-" && subExpr.operator=="+") {
|
||||
optimizationsDone++
|
||||
if(leftIsConst) {
|
||||
return if(subleftIsConst) {
|
||||
// c1-(c2+v) -> (c1-c2)-v
|
||||
|
@ -14,7 +14,8 @@ import kotlin.math.abs
|
||||
X % 1 -> constant 0 (if X is byte/word)
|
||||
X % 2 -> X and 1 (if X is byte/word)
|
||||
|
||||
todo expression optimization: common (sub) expression elimination (turn common expressions into single subroutine call)
|
||||
|
||||
todo expression optimization: common (sub) expression elimination (turn common expressions into single subroutine call + introduce variable to hold it)
|
||||
|
||||
*/
|
||||
|
||||
@ -199,7 +200,7 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
throw AstException("binary expression with 2 const values should have been evaluated")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user