mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
do..until condition can now refer to variables defined in the loop's inner scope.
This commit is contained in:
parent
e1d0dbed0c
commit
f5db31b8ff
@ -338,7 +338,7 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
|
||||
output("do ")
|
||||
untilLoop.body.accept(this)
|
||||
output(" until ")
|
||||
untilLoop.untilCondition.accept(this)
|
||||
untilLoop.condition.accept(this)
|
||||
}
|
||||
|
||||
override fun visit(returnStmt: Return) {
|
||||
|
@ -334,8 +334,8 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(untilLoop: UntilLoop) {
|
||||
if(untilLoop.untilCondition.inferType(program).typeOrElse(DataType.STRUCT) !in IntegerDatatypes)
|
||||
errors.err("condition value should be an integer type", untilLoop.untilCondition.position)
|
||||
if(untilLoop.condition.inferType(program).typeOrElse(DataType.STRUCT) !in IntegerDatatypes)
|
||||
errors.err("condition value should be an integer type", untilLoop.condition.position)
|
||||
super.visit(untilLoop)
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ abstract class AstWalker {
|
||||
|
||||
fun visit(untilLoop: UntilLoop, parent: Node) {
|
||||
track(before(untilLoop, parent), untilLoop, parent)
|
||||
untilLoop.untilCondition.accept(this, untilLoop)
|
||||
untilLoop.condition.accept(this, untilLoop)
|
||||
untilLoop.body.accept(this, untilLoop)
|
||||
track(after(untilLoop, parent), untilLoop, parent)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ interface IAstVisitor {
|
||||
}
|
||||
|
||||
fun visit(untilLoop: UntilLoop) {
|
||||
untilLoop.untilCondition.accept(this)
|
||||
untilLoop.condition.accept(this)
|
||||
untilLoop.body.accept(this)
|
||||
}
|
||||
|
||||
|
@ -815,19 +815,19 @@ class RepeatLoop(var iterations: Expression?, var body: AnonymousScope, override
|
||||
}
|
||||
|
||||
class UntilLoop(var body: AnonymousScope,
|
||||
var untilCondition: Expression,
|
||||
var condition: Expression,
|
||||
override val position: Position) : Statement() {
|
||||
override lateinit var parent: Node
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
this.parent = parent
|
||||
untilCondition.linkParents(this)
|
||||
condition.linkParents(this)
|
||||
body.linkParents(this)
|
||||
}
|
||||
|
||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||
when {
|
||||
node===untilCondition -> untilCondition = replacement as Expression
|
||||
node===condition -> condition = replacement as Expression
|
||||
node===body -> body = replacement as AnonymousScope
|
||||
else -> throw FatalAstException("invalid replace")
|
||||
}
|
||||
|
@ -164,4 +164,34 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(ifStatement: IfStatement, parent: Node): Iterable<IAstModification> {
|
||||
val binExpr = ifStatement.condition as? BinaryExpression
|
||||
if(binExpr==null || binExpr.operator !in comparisonOperators) {
|
||||
// if x -> if x!=0, if x+5 -> if x+5 != 0
|
||||
val booleanExpr = BinaryExpression(ifStatement.condition, "!=", NumericLiteralValue.optimalInteger(0, ifStatement.condition.position), ifStatement.condition.position)
|
||||
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
|
||||
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))
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
|
||||
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))
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
@ -845,47 +845,32 @@ $save .byte 0
|
||||
}
|
||||
|
||||
private fun translate(stmt: IfStatement) {
|
||||
when {
|
||||
stmt.elsepart.containsNoCodeNorVars() -> {
|
||||
// empty else
|
||||
expressionsAsmGen.translateExpression(stmt.condition)
|
||||
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
|
||||
val endLabel = makeLabel("if_end")
|
||||
out(" beq $endLabel")
|
||||
translate(stmt.truepart)
|
||||
out(endLabel)
|
||||
}
|
||||
stmt.truepart.containsNoCodeNorVars() -> {
|
||||
// empty true part
|
||||
expressionsAsmGen.translateExpression(stmt.condition)
|
||||
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
|
||||
val endLabel = makeLabel("if_end")
|
||||
out(" bne $endLabel")
|
||||
translate(stmt.elsepart)
|
||||
out(endLabel)
|
||||
}
|
||||
else -> {
|
||||
expressionsAsmGen.translateExpression(stmt.condition)
|
||||
translateTestStack(stmt.condition.inferType(program).typeOrElse(DataType.STRUCT))
|
||||
val elseLabel = makeLabel("if_else")
|
||||
val endLabel = makeLabel("if_end")
|
||||
out(" beq $elseLabel")
|
||||
translate(stmt.truepart)
|
||||
out(" jmp $endLabel")
|
||||
out(elseLabel)
|
||||
translate(stmt.elsepart)
|
||||
out(endLabel)
|
||||
}
|
||||
checkBooleanExpression(stmt.condition) // we require the condition to be of the form 'x <comparison> <value>'
|
||||
val booleanCondition = stmt.condition as BinaryExpression
|
||||
|
||||
if (stmt.elsepart.containsNoCodeNorVars()) {
|
||||
// empty else
|
||||
val endLabel = makeLabel("if_end")
|
||||
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, endLabel)
|
||||
translate(stmt.truepart)
|
||||
out(endLabel)
|
||||
}
|
||||
else {
|
||||
// both true and else parts
|
||||
val elseLabel = makeLabel("if_else")
|
||||
val endLabel = makeLabel("if_end")
|
||||
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, elseLabel)
|
||||
translate(stmt.truepart)
|
||||
out(" jmp $endLabel")
|
||||
out(elseLabel)
|
||||
translate(stmt.elsepart)
|
||||
out(endLabel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateTestStack(dataType: DataType) {
|
||||
when(dataType) {
|
||||
in ByteDatatypes -> out(" inx | lda P8ESTACK_LO,x")
|
||||
in WordDatatypes -> out(" inx | lda P8ESTACK_LO,x | ora P8ESTACK_HI,x")
|
||||
DataType.FLOAT -> throw AssemblyError("conditional value should be an integer (boolean)")
|
||||
else -> throw AssemblyError("non-numerical dt")
|
||||
}
|
||||
private fun checkBooleanExpression(condition: Expression) {
|
||||
if(condition !is BinaryExpression || condition.operator !in comparisonOperators)
|
||||
throw AssemblyError("expected boolean expression $condition")
|
||||
}
|
||||
|
||||
private fun translate(stmt: RepeatLoop) {
|
||||
@ -1004,25 +989,13 @@ $counterVar .byte 0""")
|
||||
}
|
||||
|
||||
private fun translate(stmt: WhileLoop) {
|
||||
checkBooleanExpression(stmt.condition) // we require the condition to be of the form 'x <comparison> <value>'
|
||||
val booleanCondition = stmt.condition as BinaryExpression
|
||||
val whileLabel = makeLabel("while")
|
||||
val endLabel = makeLabel("whileend")
|
||||
loopEndLabels.push(endLabel)
|
||||
out(whileLabel)
|
||||
expressionsAsmGen.translateExpression(stmt.condition)
|
||||
val conditionDt = stmt.condition.inferType(program)
|
||||
if(!conditionDt.isKnown)
|
||||
throw AssemblyError("unknown condition dt")
|
||||
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
||||
out(" inx | lda P8ESTACK_LO,x | beq $endLabel")
|
||||
} else {
|
||||
out("""
|
||||
inx
|
||||
lda P8ESTACK_LO,x
|
||||
bne +
|
||||
lda P8ESTACK_HI,x
|
||||
beq $endLabel
|
||||
+ """)
|
||||
}
|
||||
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, endLabel)
|
||||
translate(stmt.body)
|
||||
out(" jmp $whileLabel")
|
||||
out(endLabel)
|
||||
@ -1030,26 +1003,14 @@ $counterVar .byte 0""")
|
||||
}
|
||||
|
||||
private fun translate(stmt: UntilLoop) {
|
||||
checkBooleanExpression(stmt.condition) // we require the condition to be of the 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)
|
||||
expressionsAsmGen.translateExpression(stmt.untilCondition)
|
||||
val conditionDt = stmt.untilCondition.inferType(program)
|
||||
if(!conditionDt.isKnown)
|
||||
throw AssemblyError("unknown condition dt")
|
||||
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
||||
out(" inx | lda P8ESTACK_LO,x | beq $repeatLabel")
|
||||
} else {
|
||||
out("""
|
||||
inx
|
||||
lda P8ESTACK_LO,x
|
||||
bne +
|
||||
lda P8ESTACK_HI,x
|
||||
beq $repeatLabel
|
||||
+ """)
|
||||
}
|
||||
expressionsAsmGen.translateComparisonExpressionWithJumpIfFalse(booleanCondition, repeatLabel)
|
||||
out(endLabel)
|
||||
loopEndLabels.pop()
|
||||
}
|
||||
|
@ -28,6 +28,220 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
}
|
||||
}
|
||||
|
||||
internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
||||
// first, if it is of the form: <constvalue> <comparison> X , swap the operands around.
|
||||
var left = expr.left
|
||||
var right = expr.right
|
||||
var operator = expr.operator
|
||||
var leftConstVal = left.constValue(program)
|
||||
var rightConstVal = right.constValue(program)
|
||||
if(leftConstVal!=null) {
|
||||
val tmp = left
|
||||
left = right
|
||||
right = tmp
|
||||
val tmp2 = leftConstVal
|
||||
leftConstVal = rightConstVal
|
||||
rightConstVal = tmp2
|
||||
when(expr.operator) {
|
||||
"<" -> operator = ">"
|
||||
"<=" -> operator = ">="
|
||||
">" -> operator = "<"
|
||||
">=" -> operator = "<="
|
||||
}
|
||||
}
|
||||
|
||||
val dt = left.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
when (operator) {
|
||||
"==" -> {
|
||||
when (dt) {
|
||||
in ByteDatatypes -> {
|
||||
translateByteEquals(left, right, leftConstVal, rightConstVal)
|
||||
asmgen.out(" bne $jumpIfFalseLabel")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
translateWordEquals(left, right, leftConstVal, rightConstVal)
|
||||
asmgen.out(" bne $jumpIfFalseLabel")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
TODO("float eq.")
|
||||
}
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
"!=" -> {
|
||||
when (dt) {
|
||||
in ByteDatatypes -> {
|
||||
translateByteEquals(left, right, leftConstVal, rightConstVal)
|
||||
asmgen.out(" beq $jumpIfFalseLabel")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
translateWordEquals(left, right, leftConstVal, rightConstVal)
|
||||
asmgen.out(" beq $jumpIfFalseLabel")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
TODO("float neq.")
|
||||
}
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
"<" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> translateUbyteLess(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.BYTE -> translateByteLess(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.UWORD -> translateUwordLess(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.WORD -> translateWordLess(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.FLOAT -> TODO("float l.")
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
"<=" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> translateUbyteLessOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.BYTE -> translateByteLessOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.UWORD -> translateUwordLessOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.WORD -> translateWordLessOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.FLOAT -> TODO("float l.e.")
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
">" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> translateUbyteGreater(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.BYTE -> translateByteGreater(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.UWORD -> translateUwordGreater(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.WORD -> translateWordGreater(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.FLOAT -> TODO("float g.")
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
">=" -> {
|
||||
when(dt) {
|
||||
DataType.UBYTE -> translateUbyteGreaterOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.BYTE -> translateByteGreaterOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.UWORD -> translateUwordGreaterOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.WORD -> translateWordGreaterOrEqual(left, operator, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||
DataType.FLOAT -> TODO("float g.e.")
|
||||
else -> throw AssemblyError("weird operand datatype")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateUbyteLess(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateByteLess(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUwordLess(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateWordLess(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUbyteLessOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateByteLessOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUwordLessOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateWordLessOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUbyteGreater(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateByteGreater(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUwordGreater(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateWordGreater(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUbyteGreaterOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateByteGreaterOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateUwordGreaterOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateWordGreaterOrEqual(left: Expression, operator: String, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateByteEquals(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?) {
|
||||
if(rightConstVal!=null) {
|
||||
if(leftConstVal!=null) {
|
||||
if(rightConstVal==leftConstVal)
|
||||
asmgen.out(" lda #0 | sec")
|
||||
else
|
||||
asmgen.out(" lda #1 | sec")
|
||||
return
|
||||
} else {
|
||||
when(left) {
|
||||
is IdentifierReference -> {
|
||||
val name = asmgen.asmVariableName(left)
|
||||
asmgen.out(" lda $name | cmp #${rightConstVal.number}")
|
||||
return
|
||||
}
|
||||
// TODO optimize direct mem read here too
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateWordEquals(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?) {
|
||||
if(rightConstVal!=null) {
|
||||
if(leftConstVal!=null) {
|
||||
if(rightConstVal==leftConstVal)
|
||||
asmgen.out(" lda #0 | sec")
|
||||
else
|
||||
asmgen.out(" lda #1 | sec")
|
||||
} else {
|
||||
when(left) {
|
||||
is IdentifierReference -> {
|
||||
val name = asmgen.asmVariableName(left)
|
||||
asmgen.out("""
|
||||
lda $name
|
||||
cmp #<${rightConstVal.number}
|
||||
bne +
|
||||
lda $name+1
|
||||
cmp #>${rightConstVal.number}
|
||||
+""")
|
||||
return
|
||||
}
|
||||
// TODO optimize direct mem read here too
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun translateExpression(expression: FunctionCall) {
|
||||
val functionName = expression.target.nameInSource.last()
|
||||
val builtinFunc = BuiltinFunctions[functionName]
|
||||
@ -100,7 +314,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
DataType.UBYTE, DataType.BYTE -> {}
|
||||
DataType.UWORD, DataType.WORD -> {
|
||||
// sign extend
|
||||
asmgen.out("""
|
||||
asmgen.out("""
|
||||
lda P8ESTACK_LO+1,x
|
||||
ora #$7f
|
||||
bmi +
|
||||
|
@ -249,11 +249,11 @@ internal class StatementOptimizer(private val program: Program,
|
||||
}
|
||||
|
||||
override fun before(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
|
||||
val constvalue = untilLoop.untilCondition.constValue(program)
|
||||
val constvalue = untilLoop.condition.constValue(program)
|
||||
if(constvalue!=null) {
|
||||
if(constvalue.asBooleanValue) {
|
||||
// always true -> keep only the statement block (if there are no break statements)
|
||||
errors.warn("condition is always true", untilLoop.untilCondition.position)
|
||||
errors.warn("condition is always true", untilLoop.condition.position)
|
||||
if(!hasBreak(untilLoop.body))
|
||||
return listOf(IAstModification.ReplaceNode(untilLoop, untilLoop.body, parent))
|
||||
} else {
|
||||
|
@ -4,9 +4,9 @@ TODO
|
||||
|
||||
- get rid of all other TODO's in the code ;-)
|
||||
- line-circle-gfx examples are now a few hundred bytes larger than before (~4.0/4.1 version i think?). Why is that, can it be fixed?
|
||||
- add support? example? for processing arguments to a sys call : sys 999, 1, 2, "aaa"
|
||||
- make it possible for array literals to not only contain compile time constants
|
||||
- further optimize assignment codegeneration
|
||||
- further optimize expression codegeneration, most notably comparisons
|
||||
- implement @stack for asmsub parameters
|
||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||
|
@ -4,15 +4,43 @@
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
main $0900{
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
||||
ubyte x= 1
|
||||
do {
|
||||
ubyte v = x
|
||||
word x= 1
|
||||
|
||||
if x==10 {
|
||||
x=99
|
||||
} else {
|
||||
x=100
|
||||
}
|
||||
|
||||
if x==10 {
|
||||
;nothing
|
||||
} else {
|
||||
x=100
|
||||
}
|
||||
|
||||
if x==10 {
|
||||
x=99
|
||||
} else {
|
||||
; nothing
|
||||
}
|
||||
|
||||
while 1==x {
|
||||
txt.print_w(x)
|
||||
txt.chrout('\n')
|
||||
x++
|
||||
} until v==0
|
||||
}
|
||||
txt.chrout('\n')
|
||||
|
||||
x=0
|
||||
do {
|
||||
x++
|
||||
txt.print_w(x)
|
||||
txt.chrout('\n')
|
||||
} until x==10
|
||||
|
||||
; @($c000) *= 99 ; TODO implement
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user