mirror of
https://github.com/irmen/prog8.git
synced 2024-07-09 17:29:46 +00:00
attempt to make if-statement not use stack eval anymore
This commit is contained in:
parent
a9b0400d13
commit
857724c7e6
@ -1019,10 +1019,6 @@ class AsmGen(private val program: Program,
|
|||||||
requireComparisonExpression(stmt.condition) // IfStatement: condition must be of form 'x <comparison> <value>'
|
requireComparisonExpression(stmt.condition) // IfStatement: condition must be of form 'x <comparison> <value>'
|
||||||
val booleanCondition = stmt.condition as BinaryExpression
|
val booleanCondition = stmt.condition as BinaryExpression
|
||||||
|
|
||||||
// DISABLED FOR NOW:
|
|
||||||
// if(!booleanCondition.left.isSimple || !booleanCondition.right.isSimple)
|
|
||||||
// throw AssemblyError("both operands for if comparison expression should have been simplified")
|
|
||||||
|
|
||||||
if (stmt.elsepart.isEmpty()) {
|
if (stmt.elsepart.isEmpty()) {
|
||||||
val endLabel = makeLabel("if_end")
|
val endLabel = makeLabel("if_end")
|
||||||
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, endLabel)
|
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, endLabel)
|
||||||
@ -1197,6 +1193,7 @@ $repeatLabel lda $counterVar
|
|||||||
private fun translate(stmt: WhileLoop) {
|
private fun translate(stmt: WhileLoop) {
|
||||||
requireComparisonExpression(stmt.condition) // WhileLoop: condition must be of form 'x <comparison> <value>'
|
requireComparisonExpression(stmt.condition) // WhileLoop: condition must be of form 'x <comparison> <value>'
|
||||||
val booleanCondition = stmt.condition as BinaryExpression
|
val booleanCondition = stmt.condition as BinaryExpression
|
||||||
|
|
||||||
val whileLabel = makeLabel("while")
|
val whileLabel = makeLabel("while")
|
||||||
val endLabel = makeLabel("whileend")
|
val endLabel = makeLabel("whileend")
|
||||||
loopEndLabels.push(endLabel)
|
loopEndLabels.push(endLabel)
|
||||||
@ -1211,6 +1208,7 @@ $repeatLabel lda $counterVar
|
|||||||
private fun translate(stmt: UntilLoop) {
|
private fun translate(stmt: UntilLoop) {
|
||||||
requireComparisonExpression(stmt.condition) // UntilLoop: condition must be of form 'x <comparison> <value>'
|
requireComparisonExpression(stmt.condition) // UntilLoop: condition must be of form 'x <comparison> <value>'
|
||||||
val booleanCondition = stmt.condition as BinaryExpression
|
val booleanCondition = stmt.condition as BinaryExpression
|
||||||
|
|
||||||
val repeatLabel = makeLabel("repeat")
|
val repeatLabel = makeLabel("repeat")
|
||||||
val endLabel = makeLabel("repeatend")
|
val endLabel = makeLabel("repeatend")
|
||||||
loopEndLabels.push(endLabel)
|
loopEndLabels.push(endLabel)
|
||||||
|
@ -30,7 +30,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
is ArrayIndexedExpression -> translateExpression(expression)
|
is ArrayIndexedExpression -> translateExpression(expression)
|
||||||
is TypecastExpression -> translateExpression(expression)
|
is TypecastExpression -> translateExpression(expression)
|
||||||
is AddressOf -> translateExpression(expression)
|
is AddressOf -> translateExpression(expression)
|
||||||
is DirectMemoryRead -> translateDirectMemReadExpression(expression, true)
|
is DirectMemoryRead -> translateDirectMemReadExpressionToRegAorStack(expression, true)
|
||||||
is NumericLiteralValue -> translateExpression(expression)
|
is NumericLiteralValue -> translateExpression(expression)
|
||||||
is IdentifierReference -> translateExpression(expression)
|
is IdentifierReference -> translateExpression(expression)
|
||||||
is FunctionCall -> translateFunctionCallResultOntoStack(expression)
|
is FunctionCall -> translateFunctionCallResultOntoStack(expression)
|
||||||
@ -40,6 +40,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move this function to AsmGen class so that this one only exposes the toplevel translateExpression()
|
||||||
internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
||||||
// This is a helper routine called from while, do-util, and if expressions to generate optimized conditional branching code.
|
// This is a helper routine called from while, do-util, and if expressions to generate optimized conditional branching code.
|
||||||
// First, if it is of the form: <constvalue> <comparison> X , then flip the expression so the constant is always the right operand.
|
// First, if it is of the form: <constvalue> <comparison> X , then flip the expression so the constant is always the right operand.
|
||||||
@ -439,7 +440,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
return if(rightConstVal.number.toInt()!=0) {
|
return if(rightConstVal.number.toInt()!=0) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -663,7 +664,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" beq $jumpIfFalseLabel")
|
asmgen.out(" beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
return if(rightConstVal.number.toInt()!=0)
|
return if(rightConstVal.number.toInt()!=0)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
else
|
else
|
||||||
@ -828,7 +829,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" bne $jumpIfFalseLabel")
|
asmgen.out(" bne $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
return if(rightConstVal.number.toInt()!=0)
|
return if(rightConstVal.number.toInt()!=0)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
else
|
else
|
||||||
@ -996,7 +997,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
if(rightConstVal.number.toInt()!=0) {
|
if(rightConstVal.number.toInt()!=0) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -1139,7 +1140,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" bne $jumpIfFalseLabel")
|
asmgen.out(" bne $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
return if(rightConstVal.number.toInt()!=0)
|
return if(rightConstVal.number.toInt()!=0)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
else
|
else
|
||||||
@ -1176,7 +1177,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" beq $jumpIfFalseLabel")
|
asmgen.out(" beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
else if (left is DirectMemoryRead) {
|
else if (left is DirectMemoryRead) {
|
||||||
translateDirectMemReadExpression(left, false)
|
translateDirectMemReadExpressionToRegAorStack(left, false)
|
||||||
return if(rightConstVal.number.toInt()!=0)
|
return if(rightConstVal.number.toInt()!=0)
|
||||||
code("#${rightConstVal.number}")
|
code("#${rightConstVal.number}")
|
||||||
else
|
else
|
||||||
@ -1766,7 +1767,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" lda #<$name | sta P8ESTACK_LO,x | lda #>$name | sta P8ESTACK_HI,x | dex")
|
asmgen.out(" lda #<$name | sta P8ESTACK_LO,x | lda #>$name | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) {
|
// TODO move this function to another class so that this one only exposes the toplevel translateExpression()
|
||||||
|
internal fun translateDirectMemReadExpressionToRegAorStack(expr: DirectMemoryRead, pushResultOnEstack: Boolean) {
|
||||||
|
|
||||||
fun assignViaExprEval() {
|
fun assignViaExprEval() {
|
||||||
asmgen.assignExpressionToVariable(expr.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
asmgen.assignExpressionToVariable(expr.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
||||||
|
@ -209,7 +209,7 @@ internal class AsmAssignment(val source: AsmAssignSource,
|
|||||||
if(target.register !in arrayOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY))
|
if(target.register !in arrayOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY))
|
||||||
require(source.datatype != DataType.UNDEFINED) { "must not be placeholder/undefined datatype" }
|
require(source.datatype != DataType.UNDEFINED) { "must not be placeholder/undefined datatype" }
|
||||||
require(memsizer.memorySize(source.datatype) <= memsizer.memorySize(target.datatype)) {
|
require(memsizer.memorySize(source.datatype) <= memsizer.memorySize(target.datatype)) {
|
||||||
"source storage size must be less or equal to target datatype storage size"
|
"source storage size must be less or equal to target datatype storage size at $position"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,14 +657,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
private fun inplaceModification_byte_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) {
|
private fun inplaceModification_byte_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
clc
|
clc
|
||||||
adc $name
|
adc $name
|
||||||
sta $name""")
|
sta $name""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sta P8ZP_SCRATCH_B1
|
sta P8ZP_SCRATCH_B1
|
||||||
lda $name
|
lda $name
|
||||||
@ -673,15 +673,15 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta $name""")
|
sta $name""")
|
||||||
}
|
}
|
||||||
"|", "or" -> {
|
"|", "or" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" ora $name | sta $name")
|
asmgen.out(" ora $name | sta $name")
|
||||||
}
|
}
|
||||||
"&", "and" -> {
|
"&", "and" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" and $name | sta $name")
|
asmgen.out(" and $name | sta $name")
|
||||||
}
|
}
|
||||||
"^", "xor" -> {
|
"^", "xor" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" eor $name | sta $name")
|
asmgen.out(" eor $name | sta $name")
|
||||||
}
|
}
|
||||||
// TODO: tuned code for more operators
|
// TODO: tuned code for more operators
|
||||||
@ -694,7 +694,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
private fun inplaceModification_word_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) {
|
private fun inplaceModification_word_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
clc
|
clc
|
||||||
adc $name
|
adc $name
|
||||||
@ -704,7 +704,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sta P8ZP_SCRATCH_B1
|
sta P8ZP_SCRATCH_B1
|
||||||
lda $name
|
lda $name
|
||||||
@ -716,11 +716,11 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
"|", "or" -> {
|
"|", "or" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" ora $name | sta $name")
|
asmgen.out(" ora $name | sta $name")
|
||||||
}
|
}
|
||||||
"&", "and" -> {
|
"&", "and" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" and $name | sta $name")
|
asmgen.out(" and $name | sta $name")
|
||||||
if(dt in WordDatatypes) {
|
if(dt in WordDatatypes) {
|
||||||
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
@ -730,7 +730,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"^", "xor" -> {
|
"^", "xor" -> {
|
||||||
exprAsmGen.translateDirectMemReadExpression(memread, false)
|
exprAsmGen.translateDirectMemReadExpressionToRegAorStack(memread, false)
|
||||||
asmgen.out(" eor $name | sta $name")
|
asmgen.out(" eor $name | sta $name")
|
||||||
}
|
}
|
||||||
// TODO: tuned code for more operators
|
// TODO: tuned code for more operators
|
||||||
|
@ -6,12 +6,14 @@ prog8_lib {
|
|||||||
%asminclude "library:prog8_lib.asm"
|
%asminclude "library:prog8_lib.asm"
|
||||||
%asminclude "library:prog8_funcs.asm"
|
%asminclude "library:prog8_funcs.asm"
|
||||||
|
|
||||||
; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size):
|
; to store intermediary expression results for return values:
|
||||||
; NOTE: these variables are used in the StatementReorderer and StatementOptimizer
|
; NOTE: these variables are used in the StatementReorderer and StatementOptimizer
|
||||||
uword @zp retval_interm_uw
|
uword @zp retval_interm_uw
|
||||||
word @zp retval_interm_w
|
word @zp retval_interm_w
|
||||||
ubyte @zp retval_interm_ub
|
ubyte @zp retval_interm_ub
|
||||||
byte @zp retval_interm_b
|
byte @zp retval_interm_b
|
||||||
|
word retval_interm_w2
|
||||||
|
byte retval_interm_b2
|
||||||
|
|
||||||
|
|
||||||
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A {
|
||||||
|
@ -11,6 +11,7 @@ import prog8.ast.walk.AstWalker
|
|||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compiler.astprocessing.isSubroutineParameter
|
import prog8.compiler.astprocessing.isSubroutineParameter
|
||||||
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
|
|
||||||
|
|
||||||
@ -201,12 +202,74 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
|||||||
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
|
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
|
||||||
}
|
}
|
||||||
|
|
||||||
if((binExpr.operator=="==" || binExpr.operator=="!=") &&
|
if((binExpr.left as? NumericLiteralValue)?.number==0 &&
|
||||||
(binExpr.left as? NumericLiteralValue)?.number==0 &&
|
|
||||||
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||||
throw InternalCompilerException("if 0==X should have been swapped to if X==0")
|
throw FatalAstException("0==X should have been swapped to if X==0")
|
||||||
|
|
||||||
return noModifications
|
// simplify the conditional expression, introduce simple assignments if required.
|
||||||
|
// TODO sometimes this increases code size significantly (Petaxian) !!! FIX THIS
|
||||||
|
val simplify = simplifyConditionalExpression(binExpr)
|
||||||
|
val modifications = mutableListOf<IAstModification>()
|
||||||
|
if(simplify.rightVarAssignment!=null) {
|
||||||
|
modifications += IAstModification.ReplaceNode(binExpr.right, simplify.rightOperandReplacement!!, binExpr)
|
||||||
|
modifications += IAstModification.InsertBefore(ifStatement, simplify.rightVarAssignment, parent as IStatementContainer)
|
||||||
|
}
|
||||||
|
if(simplify.leftVarAssignment!=null) {
|
||||||
|
modifications += IAstModification.ReplaceNode(binExpr.left, simplify.leftOperandReplacement!!, binExpr)
|
||||||
|
modifications += IAstModification.InsertBefore(ifStatement, simplify.leftVarAssignment, parent as IStatementContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return modifications
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CondExprSimplificationResult(
|
||||||
|
val leftVarAssignment: Assignment?,
|
||||||
|
val leftOperandReplacement: Expression?,
|
||||||
|
val rightVarAssignment: Assignment?,
|
||||||
|
val rightOperandReplacement: Expression?
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun simplifyConditionalExpression(expr: BinaryExpression): CondExprSimplificationResult {
|
||||||
|
var leftAssignment: Assignment? = null
|
||||||
|
var leftOperandReplacement: Expression? = null
|
||||||
|
var rightAssignment: Assignment? = null
|
||||||
|
var rightOperandReplacement: Expression? = null
|
||||||
|
if(!expr.left.isSimple) {
|
||||||
|
val dt = expr.left.inferType(program)
|
||||||
|
val name = when {
|
||||||
|
dt.istype(DataType.UBYTE) -> listOf("cx16","r15L")
|
||||||
|
dt.istype(DataType.UWORD) -> listOf("cx16","r15")
|
||||||
|
dt.istype(DataType.BYTE) -> listOf("prog8_lib","retval_interm_b")
|
||||||
|
dt.istype(DataType.WORD) -> listOf("prog8_lib","retval_interm_w")
|
||||||
|
else -> throw AssemblyError("invalid dt")
|
||||||
|
}
|
||||||
|
leftOperandReplacement = IdentifierReference(name, expr.position)
|
||||||
|
leftAssignment = Assignment(
|
||||||
|
AssignTarget(IdentifierReference(name, expr.position), null, null, expr.position),
|
||||||
|
expr.left,
|
||||||
|
expr.position
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if(!expr.right.isSimple) {
|
||||||
|
val dt = expr.right.inferType(program)
|
||||||
|
val name = when {
|
||||||
|
dt.istype(DataType.UBYTE) -> listOf("prog8_lib","retval_interm_ub")
|
||||||
|
dt.istype(DataType.UWORD) -> listOf("prog8_lib","retval_interm_uw")
|
||||||
|
dt.istype(DataType.BYTE) -> listOf("prog8_lib","retval_interm_b2")
|
||||||
|
dt.istype(DataType.WORD) -> listOf("prog8_lib","retval_interm_w2")
|
||||||
|
else -> throw AssemblyError("invalid dt")
|
||||||
|
}
|
||||||
|
rightOperandReplacement = IdentifierReference(name, expr.position)
|
||||||
|
rightAssignment = Assignment(
|
||||||
|
AssignTarget(IdentifierReference(name, expr.position), null, null, expr.position),
|
||||||
|
expr.right,
|
||||||
|
expr.position
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return CondExprSimplificationResult(
|
||||||
|
leftAssignment, leftOperandReplacement,
|
||||||
|
rightAssignment, rightOperandReplacement
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
@ -224,6 +287,13 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
|||||||
val booleanExpr = BinaryExpression(untilLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, untilLoop.condition.position), untilLoop.condition.position)
|
val booleanExpr = BinaryExpression(untilLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, untilLoop.condition.position), untilLoop.condition.position)
|
||||||
return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop))
|
return listOf(IAstModification.ReplaceNode(untilLoop.condition, booleanExpr, untilLoop))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((binExpr.left as? NumericLiteralValue)?.number==0 &&
|
||||||
|
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||||
|
throw FatalAstException("0==X should have been swapped to if X==0")
|
||||||
|
|
||||||
|
// TODO simplify conditional expression like in if-statement
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +312,13 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
|||||||
val booleanExpr = BinaryExpression(whileLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, whileLoop.condition.position), whileLoop.condition.position)
|
val booleanExpr = BinaryExpression(whileLoop.condition, "!=", NumericLiteralValue.optimalInteger(0, whileLoop.condition.position), whileLoop.condition.position)
|
||||||
return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop))
|
return listOf(IAstModification.ReplaceNode(whileLoop.condition, booleanExpr, whileLoop))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((binExpr.left as? NumericLiteralValue)?.number==0 &&
|
||||||
|
(binExpr.right as? NumericLiteralValue)?.number!=0)
|
||||||
|
throw FatalAstException("0==X should have been swapped to if X==0")
|
||||||
|
|
||||||
|
// TODO simplify conditional expression like in if-statement
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
super.visit(forLoop)
|
super.visit(forLoop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun visit(jump: Jump) {
|
override fun visit(jump: Jump) {
|
||||||
val ident = jump.identifier
|
val ident = jump.identifier
|
||||||
if(ident!=null) {
|
if(ident!=null) {
|
||||||
|
@ -3,7 +3,8 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.3)
|
For next compiler release (7.3)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
...
|
- if-statement expression simplification sometimes increases code size (Petaxian) FIX THIS!
|
||||||
|
- add expression simplification to while and until loops as well.
|
||||||
|
|
||||||
|
|
||||||
Blocked by Commander-x16 v39 release
|
Blocked by Commander-x16 v39 release
|
||||||
@ -16,7 +17,6 @@ Future
|
|||||||
^^^^^^
|
^^^^^^
|
||||||
- fix the asm-labels problem (github issue #62)
|
- fix the asm-labels problem (github issue #62)
|
||||||
- find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack?
|
- find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack?
|
||||||
- [complicated?] find a way to optimize if-statement codegen so that "if var & %10000" doesn't use evalstack & subroutine call, but also that the simple case "if X {...}" remains fast
|
|
||||||
- document the various compiler command line options in more detail. See "Compiling program code" in the docs
|
- document the various compiler command line options in more detail. See "Compiling program code" in the docs
|
||||||
- get rid of all TODO's in the code
|
- get rid of all TODO's in the code
|
||||||
- improve testability further, add more tests
|
- improve testability further, add more tests
|
||||||
|
@ -3,16 +3,18 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
uword xw
|
|
||||||
ubyte xb
|
|
||||||
|
|
||||||
sub sub1() -> uword {
|
|
||||||
return xw+xb
|
|
||||||
}
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
xw=sub1()
|
ubyte unused ; TODO FIX : why is this not removed as an unused variable?
|
||||||
|
|
||||||
|
ubyte iteration_in_progress
|
||||||
|
uword num_bytes
|
||||||
|
|
||||||
|
ubyte qq = not iteration_in_progress or not num_bytes ; TODO FIX COMPILER CRASH (STORAGE SIZE)
|
||||||
|
|
||||||
|
if not iteration_in_progress or not num_bytes
|
||||||
|
return
|
||||||
|
|
||||||
; word xx=0
|
; word xx=0
|
||||||
; word[] xarr = [1,2,3]
|
; word[] xarr = [1,2,3]
|
||||||
@ -34,13 +36,14 @@ main {
|
|||||||
; txt.print("xx is zero\n")
|
; txt.print("xx is zero\n")
|
||||||
; }
|
; }
|
||||||
|
|
||||||
; ubyte yy=$30
|
ubyte yy=$30
|
||||||
; ubyte zz=9
|
; ubyte zz=9
|
||||||
; sys.memset(xx+200, yy*2, ~yy)
|
; sys.memset(xx+200, yy*2, ~yy)
|
||||||
;
|
;
|
||||||
; if yy & %10000 {
|
|
||||||
; yy++
|
if yy & %10000 {
|
||||||
; }
|
yy++
|
||||||
|
}
|
||||||
;
|
;
|
||||||
; @($c030) = 10
|
; @($c030) = 10
|
||||||
; @(~xx) *= 2
|
; @(~xx) *= 2
|
||||||
|
Loading…
Reference in New Issue
Block a user