mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 04:30:03 +00:00
fix expression splitter handling related to code ballooning
This commit is contained in:
parent
24c8d1f1f4
commit
3994de77d0
@ -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
|
||||
|
@ -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?
|
||||
|
@ -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,19 +54,9 @@ 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)) {
|
||||
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.right, binExpr.right.position)
|
||||
@ -73,16 +64,6 @@ X = BinExpr X = RightExpr
|
||||
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)
|
||||
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.
|
||||
|
@ -2,6 +2,9 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO FIX circle drawing errors
|
||||
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
@ -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]
|
||||
|
Loading…
x
Reference in New Issue
Block a user