From 24c8d1f1f480918e32666df5fa89fb0a22a9a581 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 2 Oct 2020 00:34:12 +0200 Subject: [PATCH] expression splitter for vardecls with binexpr init expression --- .../src/prog8/optimizer/ExpressionSplitter.kt | 37 ++---- examples/plasma.p8 | 18 +-- examples/test.p8 | 110 +++++------------- 3 files changed, 46 insertions(+), 119 deletions(-) diff --git a/compiler/src/prog8/optimizer/ExpressionSplitter.kt b/compiler/src/prog8/optimizer/ExpressionSplitter.kt index 38a086d49..9925b97ca 100644 --- a/compiler/src/prog8/optimizer/ExpressionSplitter.kt +++ b/compiler/src/prog8/optimizer/ExpressionSplitter.kt @@ -16,32 +16,17 @@ class ExpressionSplitter(private val program: Program) : AstWalker() { // TODO once this works, integrate it back into expressionsimplifier override fun after(decl: VarDecl, parent: Node): Iterable { - val expr = decl.value as? BinaryExpression - if (expr != null) { - // reduce the complexity of a (binary) expression that has to be evaluated on the eval stack, - // by attempting to splitting it up into individual simple steps: - // X = - // or X = - // split that into X = ; X = X - - // TODO DOES THIS LOOP AS WELL? - if (expr.operator !in comparisonOperators && decl.type==VarDeclType.VAR) { - if (expr.right !is BinaryExpression) { - println("SPLIT VARDECL RIGHT BINEXPR $expr") // TODO -// val firstAssign = Assignment(assignment.target, expr.left, assignment.position) -// val augExpr = BinaryExpression(assignment.target.toExpression(), expr.operator, expr.right, expr.position) -// return listOf( -// IAstModification.InsertBefore(assignment, firstAssign, parent), -// IAstModification.ReplaceNode(assignment.value, augExpr, assignment) -// ) - } else if (expr.left !is BinaryExpression && expr.operator in associativeOperators) { - println("SPLIT VARDECL LEFT BINEXPR $expr") // TODO -// val firstAssign = Assignment(assignment.target, expr.right, assignment.position) -// val augExpr = BinaryExpression(assignment.target.toExpression(), expr.operator, expr.left, expr.position) -// return listOf( -// IAstModification.InsertBefore(assignment, firstAssign, parent), -// IAstModification.ReplaceNode(assignment.value, augExpr, assignment)) - } + 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) + ) } } diff --git a/examples/plasma.p8 b/examples/plasma.p8 index d9c24f274..81d9dc0ed 100644 --- a/examples/plasma.p8 +++ b/examples/plasma.p8 @@ -2,16 +2,11 @@ %import syslib %import textio - -;/*****************************************************************************\ -;** plasma test program for cc65. ** -;** ** -;** (w)2001 by groepaz/hitmen ** -;** ** -;** Cleanup and porting by Ullrich von Bassewitz. ** -;** Converted to prog8 by Irmen de Jong ** -;** ** -;\*****************************************************************************/ +; converted from plasma test program for cc65. +; which is (w)2001 by groepaz/hitmen +; +; Cleanup and porting to C by Ullrich von Bassewitz. +; Converted to prog8 by Irmen de Jong. main { @@ -78,8 +73,7 @@ main { for y in 24 downto 0 { for x in 39 downto 0 { ; using a temp var here to enable expression optimization that can't be done on a 'problematic' ROM/RAM memory location - ubyte cc - cc = xbuf[x] + ybuf[y] ; TODO should be split!! + ubyte cc = xbuf[x] + ybuf[y] @(screen) = cc ; this is the fastest way to do this inner part: ; %asm {{ diff --git a/examples/test.p8 b/examples/test.p8 index 79a80d3ce..4bd2cd86c 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,96 +6,44 @@ main { - -; Color c1 = [11,22,33] ; TODO fix crash -; Color c2 = [11,22,33] ; TODO fix crash -; Color c3 = [11,22,33] ; TODO fix crash -; uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct + struct Color { + ubyte red + ubyte green + ubyte blue + } -; str[] names = ["aap", "noot", "mies", "vuur"] -; uword[] names3 = ["aap", "noot", "mies", "vuur"] -; ubyte[] values = [11,22,33,44] -; uword[] arrays = [names, names3, values] + Color c1 = [11,22,33] + Color c2 = [11,22,33] + Color c3 = [11,22,33] + uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct -; asmsub testX() { -; %asm {{ -; stx _saveX -; lda #13 -; jsr txt.chrout -; lda _saveX -; jsr txt.print_ub -; lda #13 -; jsr txt.chrout -; ldx _saveX -; rts -;_saveX .byte 0 -; }} -; } - sub start() { -; byte bb = 100 -; word ww = 30000 -; float ff1 = 1000 -; float ff2 = -1000 - ubyte[10] xbuf - ubyte[10] ybuf - ubyte x - ubyte y + Color c1 = [11,22,33] + Color c2 = [11,22,33] + Color c3 = [11,22,33] + uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct - ubyte cc = xbuf[x] + ybuf[y] ; TODO should be split!! also fix plasma.p8 - ubyte cc2 - cc2 = xbuf[x] + ybuf[y] +cc ; will be split correctly. - return + c1 = c2 + ; c1 = [11,22,33] ; TODO implement rewrite into individual struct member assignments + } -; ff1 = 1+((-ff1) *3) -; floats.print_f(ff1) -; floats.print_f(1+((-1000) *3)) -; testX() -; ff1 = 1+((-ff2) *3) -; floats.print_f(ff1) -; floats.print_f(1+((- (-1000)) *3)) -; txt.chrout('\n') -; testX() -; return - -; struct Color { -; ubyte red -; ubyte green -; ubyte blue -; } -; -; ;Color c1 = [11,22,33] ; TODO fix struct initializer crash -; Color c1 -; Color c2 -; Color c3 -; ;Color c2 = [11,22,33] -; ;Color c3 = [11,22,33] -; ;uword[] colors = [ c1, c2, c3] ; TODO should contain pointers to (the first element) of each struct -; -; c1 = c2 -; ;c1 = [11,22,33] ; TODO rewrite into individual struct member assignments -; -; -; uword s -; for s in names { -; txt.print(s) -; txt.chrout('\n') -; } -; txt.chrout('\n') -; -; txt.print(names[2]) -; txt.chrout('\n') -; txt.print(names[3]) -; txt.chrout('\n') -; -; repeat { -; txt.print(names3[rnd()&3]) -; txt.chrout(' ') -; } + asmsub testX() { + %asm {{ + stx _saveX + lda #13 + jsr txt.chrout + lda _saveX + jsr txt.print_ub + lda #13 + jsr txt.chrout + ldx _saveX + rts +_saveX .byte 0 + }} } }