removed special code generation for while and util expression (replaced by jumps)

also added exhaustive parent node checker in validation step
This commit is contained in:
Irmen de Jong 2021-12-27 02:04:28 +01:00
parent 67b0890a6e
commit c55fdd9834
10 changed files with 335 additions and 164 deletions

View File

@ -781,12 +781,12 @@ class AsmGen(private val program: Program,
is BranchStatement -> translate(stmt)
is IfStatement -> translate(stmt)
is ForLoop -> forloopsAsmGen.translate(stmt)
is WhileLoop -> translate(stmt)
is RepeatLoop -> translate(stmt)
is UntilLoop -> translate(stmt)
is WhenStatement -> translate(stmt)
is AnonymousScope -> translate(stmt)
is BuiltinFunctionStatementPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore")
is UntilLoop -> throw AssemblyError("do..until should have been desugared to jumps")
is WhileLoop -> throw AssemblyError("while should have been desugared to jumps")
is Block -> throw AssemblyError("block should have been handled elsewhere")
is Break -> throw AssemblyError("break should have been replaced by goto")
else -> throw AssemblyError("missing asm translation for $stmt")
@ -1268,35 +1268,6 @@ $repeatLabel lda $counterVar
return counterVar
}
private fun translate(stmt: WhileLoop) {
requireComparisonExpression(stmt.condition) // WhileLoop: condition must be of form 'x <comparison> <value>'
val booleanCondition = stmt.condition as BinaryExpression
val whileLabel = makeLabel("while")
val endLabel = makeLabel("whileend")
loopEndLabels.push(endLabel)
out(whileLabel)
translateComparisonExpressionWithJumpIfFalse(booleanCondition, endLabel)
translate(stmt.body)
jmp(whileLabel)
out(endLabel)
loopEndLabels.pop()
}
private fun translate(stmt: UntilLoop) {
requireComparisonExpression(stmt.condition) // UntilLoop: condition must be of form 'x <comparison> <value>'
val booleanCondition = stmt.condition as BinaryExpression
val repeatLabel = makeLabel("repeat")
val endLabel = makeLabel("repeatend")
loopEndLabels.push(endLabel)
out(repeatLabel)
translate(stmt.body)
translateComparisonExpressionWithJumpIfFalse(booleanCondition, repeatLabel)
out(endLabel)
loopEndLabels.pop()
}
private fun translate(stmt: WhenStatement) {
val endLabel = makeLabel("choice_end")
val choiceBlocks = mutableListOf<Pair<String, AnonymousScope>>()

View File

@ -35,6 +35,14 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
throw FatalAstException("break should have been replaced by goto $breakStmt")
}
override fun before(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
throw FatalAstException("while should have been desugared to jumps")
}
override fun before(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
throw FatalAstException("do..until should have been desugared to jumps")
}
override fun before(block: Block, parent: Node): Iterable<IAstModification> {
// move all subroutines to the bottom of the block
val subs = block.statements.filterIsInstance<Subroutine>()
@ -185,7 +193,6 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
return noModifications
}
@Suppress("DuplicatedCode")
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
val prefixExpr = ifStatement.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
@ -282,74 +289,6 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
)
}
@Suppress("DuplicatedCode")
override fun after(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
val prefixExpr = untilLoop.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// until not x -> until x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, untilLoop.condition.position), untilLoop.condition.position)
return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop))
}
val binExpr = untilLoop.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in ComparisonOperators) {
// until x -> until x!=0, until x+5 -> until x+5 != 0
val booleanExpr = BinaryExpression(untilLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, untilLoop.condition.position), untilLoop.condition.position)
return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop))
}
if((binExpr.left as? NumericLiteralValue)?.number==0.0 &&
(binExpr.right as? NumericLiteralValue)?.number!=0.0)
throw FatalAstException("0==X should have been swapped to if X==0")
// simplify the conditional expression, introduce simple assignments if required.
// NOTE: sometimes this increases code size because additional stores/loads are generated for the
// intermediate variables. We assume these are optimized away from the resulting assembly code later.
val simplify = simplifyConditionalExpression(binExpr)
val modifications = mutableListOf<IAstModification>()
if(simplify.rightVarAssignment!=null) {
modifications += IAstModification.ReplaceNode(binExpr.right, simplify.rightOperandReplacement!!, binExpr)
modifications += IAstModification.InsertLast(simplify.rightVarAssignment, untilLoop.body)
}
if(simplify.leftVarAssignment!=null) {
modifications += IAstModification.ReplaceNode(binExpr.left, simplify.leftOperandReplacement!!, binExpr)
modifications += IAstModification.InsertLast(simplify.leftVarAssignment, untilLoop.body)
}
return modifications
}
@Suppress("DuplicatedCode")
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
val prefixExpr = whileLoop.condition as? PrefixExpression
if(prefixExpr!=null && prefixExpr.operator=="not") {
// while not x -> while x==0
val booleanExpr = BinaryExpression(prefixExpr.expression, "==", NumericLiteralValue.optimalInteger(0, whileLoop.condition.position), whileLoop.condition.position)
return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop))
}
val binExpr = whileLoop.condition as? BinaryExpression
if(binExpr==null || binExpr.operator !in ComparisonOperators) {
// while x -> while x!=0, while x+5 -> while x+5 != 0
val booleanExpr = BinaryExpression(whileLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, whileLoop.condition.position), whileLoop.condition.position)
return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop))
}
if((binExpr.left as? NumericLiteralValue)?.number==0.0 &&
(binExpr.right as? NumericLiteralValue)?.number!=0.0)
throw FatalAstException("0==X should have been swapped to if X==0")
// TODO simplify the conditional expression, introduce simple assignments if required.
// make sure to evaluate it only once, but also right at entry of the while loop
// NOTE: sometimes this increases code size because additional stores/loads are generated for the
// intermediate variables. We assume these are optimized away from the resulting assembly code later.
// NOTE: this is nasty for a while-statement as the condition occurs at the top of the loop
// so the expression needs to be evaluated also before the loop is entered...
// but I don't want to duplicate the expression.
// val simplify = simplifyConditionalExpression(binExpr)
return noModifications
}
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(functionCallStatement.target.nameInSource==listOf("cmp")) {
// if the datatype of the arguments of cmp() are different, cast the byte one to word.

View File

@ -305,13 +305,13 @@ private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOpt
program.addTypecasts(errors, compilerOptions)
errors.report()
program.variousCleanups(program, errors)
program.checkValid(errors, compilerOptions) // check if final tree is still valid
errors.report()
val callGraph = CallGraph(program)
callGraph.checkRecursiveCalls(errors)
errors.report()
program.verifyFunctionArgTypes()
program.moveMainAndStartToFirst()
program.checkValid(errors, compilerOptions) // check if final tree is still valid
errors.report()
}
private sealed class WriteAssemblyResult {

View File

@ -16,6 +16,8 @@ import prog8.compilerinterface.IStringEncoding
internal fun Program.checkValid(errors: IErrorReporter, compilerOptions: CompilationOptions) {
val parentChecker = ParentNodeChecker()
parentChecker.visit(this)
val checker = AstChecker(this, errors, compilerOptions)
checker.visit(this)
}

View File

@ -1,10 +1,13 @@
package prog8.compiler.astprocessing
import com.github.michaelbull.result.toResultOr
import prog8.ast.IStatementContainer
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.base.ParentSentinel
import prog8.ast.base.Position
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.PrefixExpression
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
@ -25,18 +28,22 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep
private var generatedLabelSequenceNumber: Int = 0
private val generatedLabelPrefix = "prog8_label_"
private fun makeLabel(postfix: String): String {
private fun makeLabel(postfix: String, position: Position): Label {
generatedLabelSequenceNumber++
return "${generatedLabelPrefix}${generatedLabelSequenceNumber}_$postfix"
return Label("${generatedLabelPrefix}${generatedLabelSequenceNumber}_$postfix", position)
}
private fun jumpLabel(label: Label): Jump {
val ident = IdentifierReference(listOf(label.name), label.position)
return Jump(null, ident, null, label.position)
}
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
val labelName = makeLabel("after")
val ident = IdentifierReference(listOf(labelName), breakStmt.position)
val label = makeLabel("after", breakStmt.position)
return listOf(
IAstModification.ReplaceNode(breakStmt, Jump(null, ident, null, breakStmt.position), parent),
IAstModification.InsertAfter(stmt, Label(labelName, breakStmt.position), stmt.parent as IStatementContainer)
IAstModification.ReplaceNode(breakStmt, jumpLabel(label), parent),
IAstModification.InsertAfter(stmt, label, stmt.parent as IStatementContainer)
)
}
@ -56,4 +63,52 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep
}
}
override fun after(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
/*
do { STUFF } until CONDITION
===>
_loop:
STUFF
if not CONDITION
goto _loop
*/
val pos = untilLoop.position
val loopLabel = makeLabel("untilloop", pos)
val notCondition = PrefixExpression("not", untilLoop.condition, pos)
val replacement = AnonymousScope(mutableListOf(
loopLabel,
untilLoop.body,
IfStatement(notCondition,
AnonymousScope(mutableListOf(jumpLabel(loopLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos)
), pos)
return listOf(IAstModification.ReplaceNode(untilLoop, replacement, parent))
}
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
/*
while CONDITION { STUFF }
==>
goto _whilecond
_whileloop:
STUFF
_whilecond:
if CONDITION goto _whileloop
*/
val pos = whileLoop.position
val condLabel = makeLabel("whilecond", pos)
val loopLabel = makeLabel("whileloop", pos)
val replacement = AnonymousScope(mutableListOf(
jumpLabel(condLabel),
loopLabel,
whileLoop.body,
condLabel,
IfStatement(whileLoop.condition,
AnonymousScope(mutableListOf(jumpLabel(loopLabel)), pos),
AnonymousScope(mutableListOf(), pos),
pos)
), pos)
return listOf(IAstModification.ReplaceNode(whileLoop, replacement, parent))
}
}

View File

@ -0,0 +1,241 @@
package prog8.compiler.astprocessing
import prog8.ast.Module
import prog8.ast.Node
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
internal class ParentNodeChecker: AstWalker() {
override fun before(addressOf: AddressOf, parent: Node): Iterable<IAstModification> {
if(addressOf.parent!==parent)
throw FatalAstException("parent node mismatch at $addressOf")
return noModifications
}
override fun before(array: ArrayLiteralValue, parent: Node): Iterable<IAstModification> {
if(array.parent!==parent)
throw FatalAstException("parent node mismatch at $array")
return noModifications
}
override fun before(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
if(arrayIndexedExpression.parent!==parent)
throw FatalAstException("parent node mismatch at $arrayIndexedExpression")
return noModifications
}
override fun before(assignTarget: AssignTarget, parent: Node): Iterable<IAstModification> {
if(assignTarget.parent!==parent)
throw FatalAstException("parent node mismatch at $assignTarget")
return noModifications
}
override fun before(assignment: Assignment, parent: Node): Iterable<IAstModification> {
if(assignment.parent!==parent)
throw FatalAstException("parent node mismatch at $assignment")
return noModifications
}
override fun before(block: Block, parent: Node): Iterable<IAstModification> {
if(block.parent!==parent)
throw FatalAstException("parent node mismatch at $block")
return noModifications
}
override fun before(branchStatement: BranchStatement, parent: Node): Iterable<IAstModification> {
if(branchStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $branchStatement")
return noModifications
}
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
if(breakStmt.parent!==parent)
throw FatalAstException("parent node mismatch at $breakStmt")
return noModifications
}
override fun before(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if(decl.parent!==parent)
throw FatalAstException("parent node mismatch at $decl")
return noModifications
}
override fun before(directive: Directive, parent: Node): Iterable<IAstModification> {
if(directive.parent!==parent)
throw FatalAstException("parent node mismatch at $directive")
return noModifications
}
override fun before(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
if(expr.parent!==parent)
throw FatalAstException("parent node mismatch at $expr")
return noModifications
}
override fun before(expr: PrefixExpression, parent: Node): Iterable<IAstModification> {
if(expr.parent!==parent)
throw FatalAstException("parent node mismatch at $expr")
return noModifications
}
override fun before(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
if(forLoop.parent!==parent)
throw FatalAstException("parent node mismatch at $forLoop")
return noModifications
}
override fun before(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> {
if(repeatLoop.parent!==parent)
throw FatalAstException("parent node mismatch at $repeatLoop")
return noModifications
}
override fun before(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
if(identifier.parent!==parent)
throw FatalAstException("parent node mismatch at $identifier")
return noModifications
}
override fun before(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
if(ifStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $ifStatement")
return noModifications
}
override fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> {
if(inlineAssembly.parent!==parent)
throw FatalAstException("parent node mismatch at $inlineAssembly")
return noModifications
}
override fun before(jump: Jump, parent: Node): Iterable<IAstModification> {
if(jump.parent!==parent)
throw FatalAstException("parent node mismatch at $jump")
return noModifications
}
override fun before(label: Label, parent: Node): Iterable<IAstModification> {
if(label.parent!==parent)
throw FatalAstException("parent node mismatch at $label")
return noModifications
}
override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> {
if(memread.parent!==parent)
throw FatalAstException("parent node mismatch at $memread")
return noModifications
}
override fun before(memwrite: DirectMemoryWrite, parent: Node): Iterable<IAstModification> {
if(memwrite.parent!==parent)
throw FatalAstException("parent node mismatch at $memwrite")
return noModifications
}
override fun before(module: Module, parent: Node): Iterable<IAstModification> {
if(module.parent!==parent)
throw FatalAstException("parent node mismatch at $module")
return noModifications
}
override fun before(numLiteral: NumericLiteralValue, parent: Node): Iterable<IAstModification> {
if(numLiteral.parent!==parent)
throw FatalAstException("parent node mismatch at $numLiteral")
return noModifications
}
override fun before(postIncrDecr: PostIncrDecr, parent: Node): Iterable<IAstModification> {
if(postIncrDecr.parent!==parent)
throw FatalAstException("parent node mismatch at $postIncrDecr")
return noModifications
}
override fun before(range: RangeExpr, parent: Node): Iterable<IAstModification> {
if(range.parent!==parent)
throw FatalAstException("parent node mismatch at $range")
return noModifications
}
override fun before(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
if(untilLoop.parent!==parent)
throw FatalAstException("parent node mismatch at $untilLoop")
return noModifications
}
override fun before(returnStmt: Return, parent: Node): Iterable<IAstModification> {
if(returnStmt.parent!==parent)
throw FatalAstException("parent node mismatch at $returnStmt")
return noModifications
}
override fun before(char: CharLiteral, parent: Node): Iterable<IAstModification> {
if(char.parent!==parent)
throw FatalAstException("parent node mismatch at $char")
return noModifications
}
override fun before(string: StringLiteralValue, parent: Node): Iterable<IAstModification> {
if(string.parent!==parent)
throw FatalAstException("parent node mismatch at $string")
return noModifications
}
override fun before(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
if(subroutine.parent!==parent)
throw FatalAstException("parent node mismatch at $subroutine")
return noModifications
}
override fun before(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
if(typecast.parent!==parent)
throw FatalAstException("parent node mismatch at $typecast")
return noModifications
}
override fun before(whenChoice: WhenChoice, parent: Node): Iterable<IAstModification> {
if(whenChoice.parent!==parent)
throw FatalAstException("parent node mismatch at $whenChoice")
return noModifications
}
override fun before(whenStatement: WhenStatement, parent: Node): Iterable<IAstModification> {
if(whenStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $whenStatement")
return noModifications
}
override fun before(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
if(whileLoop.parent!==parent)
throw FatalAstException("parent node mismatch at $whileLoop")
return noModifications
}
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
if(functionCall.parent!==parent)
throw FatalAstException("parent node mismatch at $functionCall")
return noModifications
}
override fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(functionCallStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $functionCallStatement")
return noModifications
}
override fun before(nopStatement: NopStatement, parent: Node): Iterable<IAstModification> {
if(nopStatement.parent!==parent)
throw FatalAstException("parent node mismatch at $nopStatement")
return noModifications
}
override fun before(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
if(scope.parent!==parent)
throw FatalAstException("parent node mismatch at $scope")
return noModifications
}
}

View File

@ -19,14 +19,14 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
return listOf(IAstModification.Remove(nopStatement, parent as IStatementContainer))
}
override fun before(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
override fun after(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
return if(parent is IStatementContainer)
listOf(ScopeFlatten(scope, parent as IStatementContainer))
else
noModifications
}
class ScopeFlatten(val scope: AnonymousScope, val into: IStatementContainer) : IAstModification {
private class ScopeFlatten(val scope: AnonymousScope, val into: IStatementContainer) : IAstModification {
override fun perform() {
val idx = into.statements.indexOf(scope)
if(idx>=0) {
@ -37,15 +37,16 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
}
}
override fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
return before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position)
}
override fun before(functionCallStatement: FunctionCallStatement, parent: Node) =
before(functionCallStatement as IFunctionCall, parent, functionCallStatement.position)
override fun before(functionCall: FunctionCall, parent: Node): Iterable<IAstModification> {
return before(functionCall as IFunctionCall, parent, functionCall.position)
}
override fun before(functionCall: FunctionCall, parent: Node) =
before(functionCall as IFunctionCall, parent, functionCall.position)
private fun before(functionCall: IFunctionCall, parent: Node, position: Position): Iterable<IAstModification> {
// TODO move to CodeDesugarer
if(functionCall.target.nameInSource==listOf("peek")) {
// peek(a) is synonymous with @(a)
val memread = DirectMemoryRead(functionCall.args.single(), position)
@ -61,9 +62,6 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
}
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
if(typecast.parent!==parent)
throw FatalAstException("parent node mismatch at $typecast")
if(typecast.expression is NumericLiteralValue) {
val value = (typecast.expression as NumericLiteralValue).cast(typecast.type)
if(value.isValid)
@ -85,16 +83,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
return noModifications
}
override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
if(subroutine.parent!==parent)
throw FatalAstException("parent node mismatch at $subroutine")
return noModifications
}
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
if(assignment.parent!==parent)
throw FatalAstException("parent node mismatch at $assignment")
val nextAssign = assignment.nextSibling() as? Assignment
if(nextAssign!=null && nextAssign.target.isSameAs(assignment.target, program)) {
if(nextAssign.value isSameAs assignment.value)
@ -103,34 +92,4 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter)
return noModifications
}
override fun after(assignTarget: AssignTarget, parent: Node): Iterable<IAstModification> {
if(assignTarget.parent!==parent)
throw FatalAstException("parent node mismatch at $assignTarget")
return noModifications
}
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if(decl.parent!==parent)
throw FatalAstException("parent node mismatch at $decl")
return noModifications
}
override fun after(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
if(scope.parent!==parent)
throw FatalAstException("parent node mismatch at $scope")
return noModifications
}
override fun after(returnStmt: Return, parent: Node): Iterable<IAstModification> {
if(returnStmt.parent!==parent)
throw FatalAstException("parent node mismatch at $returnStmt")
return noModifications
}
override fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> {
if(identifier.parent!==parent)
throw FatalAstException("parent node mismatch at $identifier")
return noModifications
}
}

View File

@ -476,7 +476,12 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed
}
override fun referencesIdentifier(nameInSource: List<String>) = false
override fun constValue(program: Program) = this
override fun constValue(program: Program): NumericLiteralValue {
return copy().also {
if(::parent.isInitialized)
it.parent = parent
}
}
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node)= visitor.visit(this, parent)

View File

@ -3,7 +3,7 @@ TODO
For next compiler release (7.6)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
optimize ifs containing only a jump: reuse old code from AsmGen translateComparisonExpressionWithJumpIfFalse?
Blocked by an official Commander-x16 v39 release
@ -37,10 +37,6 @@ Future
More code optimization ideas
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- remove special code generation for while and util expression
by rewriting while and until expressions into if+jump (just consider them syntactic sugar)
but the result should not produce larger code ofcourse!
- while-expression should now also get the simplifyConditionalExpression() treatment
- byte typed expressions should be evaluated in the accumulator where possible, without (temp)var
for instance value = otherbyte >> 1 --> lda otherbite ; lsr a; sta value
- rewrite multiple choice if into when:

View File

@ -11,6 +11,9 @@ main {
ubyte @shared zz = other[3]
}
sub start() {
txt.print("should print: 10 40 80 20\n")
ubyte @shared xx
repeat {
xx++