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 word @zp d = 0
ubyte positive_ix = true ubyte positive_ix = true
word @zp dx = x2 - x1 as word word @zp dx = x2-x1
word @zp dy = y2 as word - y1 as word word @zp dy = y2-y1
if dx < 0 { if dx < 0 {
dx = -dx dx = -dx
positive_ix = false positive_ix = false

View File

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

View File

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

View File

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

View File

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