diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 48a1f357e..c70c05a02 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -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 } diff --git a/compiler/src/prog8/ast/AST.kt b/compiler/src/prog8/ast/AST.kt index 5568b5b21..a90ce8a22 100644 --- a/compiler/src/prog8/ast/AST.kt +++ b/compiler/src/prog8/ast/AST.kt @@ -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 } diff --git a/compiler/src/prog8/optimizing/ConstExprEvaluator.kt b/compiler/src/prog8/optimizing/ConstExprEvaluator.kt index fcc465160..67e1917fb 100644 --- a/compiler/src/prog8/optimizing/ConstExprEvaluator.kt +++ b/compiler/src/prog8/optimizing/ConstExprEvaluator.kt @@ -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 { diff --git a/compiler/src/prog8/optimizing/ConstantFolding.kt b/compiler/src/prog8/optimizing/ConstantFolding.kt index 170ee80c6..f263f368a 100644 --- a/compiler/src/prog8/optimizing/ConstantFolding.kt +++ b/compiler/src/prog8/optimizing/ConstantFolding.kt @@ -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 diff --git a/compiler/src/prog8/optimizing/SimplifyExpressions.kt b/compiler/src/prog8/optimizing/SimplifyExpressions.kt index 7e9d772d4..5c30de6ef 100644 --- a/compiler/src/prog8/optimizing/SimplifyExpressions.kt +++ b/compiler/src/prog8/optimizing/SimplifyExpressions.kt @@ -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 } }