fix expression splitter handling related to code ballooning

This commit is contained in:
Irmen de Jong 2020-10-02 00:46:40 +02:00
parent 24c8d1f1f4
commit 3994de77d0
5 changed files with 30 additions and 41 deletions

View File

@ -33,8 +33,8 @@ graphics {
}
word @zp d = 0
ubyte positive_ix = true
word @zp dx = x2 - x1 as word
word @zp dy = y2 as word - y1 as word
word @zp dx = x2-x1
word @zp dy = y2-y1
if dx < 0 {
dx = -dx
positive_ix = false

View File

@ -17,7 +17,7 @@ import kotlin.math.abs
val associativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=")
val comparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
val augmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>")
sealed class Expression: Node {
abstract fun constValue(program: Program): NumericLiteralValue?

View File

@ -3,7 +3,6 @@ package prog8.optimizer
import prog8.ast.INameScope
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.VarDeclType
import prog8.ast.expressions.*
import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModification
@ -16,19 +15,21 @@ class ExpressionSplitter(private val program: Program) : AstWalker() {
// TODO once this works, integrate it back into expressionsimplifier
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if(decl.type==VarDeclType.VAR) {
val binExpr = decl.value as? BinaryExpression
if (binExpr != null) {
// split into a vardecl with just the left expression, and an aug. assignment with the right expression.
val augExpr = BinaryExpression(IdentifierReference(listOf(decl.name), decl.position), binExpr.operator, binExpr.right, binExpr.position)
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
val assign = Assignment(target, augExpr, binExpr.position)
return listOf(
IAstModification.SetExpression({ decl.value = it }, binExpr.left, decl),
IAstModification.InsertAfter(decl, assign, parent)
)
}
}
// TODO somehow if we do this, the resulting code for some programs (cube3d.p8) gets hundreds of bytes larger...:
// if(decl.type==VarDeclType.VAR ) {
// val binExpr = decl.value as? BinaryExpression
// if (binExpr != null && binExpr.operator in augmentAssignmentOperators) {
// // split into a vardecl with just the left expression, and an aug. assignment with the right expression.
// val augExpr = BinaryExpression(IdentifierReference(listOf(decl.name), decl.position), binExpr.operator, binExpr.right, binExpr.position)
// val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
// val assign = Assignment(target, augExpr, binExpr.position)
// println("SPLIT VARDECL $decl")
// return listOf(
// IAstModification.SetExpression({ decl.value = it }, binExpr.left, decl),
// IAstModification.InsertAfter(decl, assign, parent)
// )
// }
// }
return emptyList()
}
@ -53,32 +54,12 @@ X = BinExpr X = LeftExpr
/ \ / \ X RightExpr.
.. .. .. ..
X = BinExpr X = RightExpr
<operator> followed by
/ \ IF ASSOCIATIVE X = BinExpr
/ \ <operator> ==> <operator>
/ \ / \
LeftExpr. SimpleExpr. / \
/ \ (not X) X LeftExpr.
.. ..
*/
if(!assignment.isAugmentable && isSimpleTarget(assignment.target, program.namespace)) {
val firstAssign = Assignment(assignment.target, binExpr.left, binExpr.left.position)
val targetExpr = assignment.target.toExpression()
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.right, binExpr.right.position)
return listOf(
IAstModification.InsertBefore(assignment, firstAssign, parent),
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))
}
if(binExpr.operator in associativeOperators && binExpr.left is BinaryExpression) {
if (binExpr.right !is BinaryExpression && !(binExpr.right isSameAs assignment.target)) {
val firstAssign = Assignment(assignment.target, binExpr.right, binExpr.right.position)
if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program.namespace)) {
if (!assignment.isAugmentable) {
val firstAssign = Assignment(assignment.target, binExpr.left, binExpr.left.position)
val targetExpr = assignment.target.toExpression()
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.left, binExpr.left.position)
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.right, binExpr.right.position)
return listOf(
IAstModification.InsertBefore(assignment, firstAssign, parent),
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))

View File

@ -2,6 +2,9 @@
; Note: this program is compatible with C64 and CX16.
; TODO FIX circle drawing errors
main {
sub start() {

View File

@ -21,6 +21,11 @@ main {
sub start() {
ubyte a
ubyte b
ubyte c
c = a==b
Color c1 = [11,22,33]
Color c2 = [11,22,33]