mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 04:31:20 +00:00
make repeat support 65536 iterations
This commit is contained in:
parent
573cecb087
commit
bf98ceca2c
@ -82,6 +82,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun asConstInteger(): Int? = (this as? PtNumber)?.number?.toInt() ?: (this as? PtBool)?.asInt()
|
fun asConstInteger(): Int? = (this as? PtNumber)?.number?.toInt() ?: (this as? PtBool)?.asInt()
|
||||||
|
fun asConstValue(): Double? = (this as? PtNumber)?.number ?: (this as? PtBool)?.asInt()?.toDouble()
|
||||||
|
|
||||||
fun isSimple(): Boolean {
|
fun isSimple(): Boolean {
|
||||||
return when(this) {
|
return when(this) {
|
||||||
@ -378,7 +379,3 @@ class PtTypeCast(type: DataType, position: Position) : PtExpression(type, positi
|
|||||||
|
|
||||||
// special node that isn't created from compiling user code, but used internally in the Intermediate Code
|
// special node that isn't created from compiling user code, but used internally in the Intermediate Code
|
||||||
class PtIrRegister(val register: Int, type: DataType, position: Position) : PtExpression(type, position)
|
class PtIrRegister(val register: Int, type: DataType, position: Position) : PtExpression(type, position)
|
||||||
|
|
||||||
|
|
||||||
fun constValue(expr: PtExpression): Double? = if(expr is PtNumber) expr.number else if(expr is PtBool) expr.asInt().toDouble() else null
|
|
||||||
fun constIntValue(expr: PtExpression): Int? = if(expr is PtNumber) expr.number.toInt() else if(expr is PtBool) expr.asInt() else null
|
|
||||||
|
@ -790,7 +790,7 @@ class AsmGen6502Internal (
|
|||||||
when {
|
when {
|
||||||
iterations == 0 -> {}
|
iterations == 0 -> {}
|
||||||
iterations == 1 -> translate(stmt.statements)
|
iterations == 1 -> translate(stmt.statements)
|
||||||
iterations<0 || iterations>65535 -> throw AssemblyError("invalid number of iterations")
|
iterations<0 || iterations>65536 -> throw AssemblyError("invalid number of iterations")
|
||||||
iterations <= 256 -> repeatByteCount(iterations, stmt)
|
iterations <= 256 -> repeatByteCount(iterations, stmt)
|
||||||
else -> repeatWordCount(iterations, stmt)
|
else -> repeatWordCount(iterations, stmt)
|
||||||
}
|
}
|
||||||
@ -830,10 +830,10 @@ class AsmGen6502Internal (
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun repeatWordCount(iterations: Int, stmt: PtRepeatLoop) {
|
private fun repeatWordCount(iterations: Int, stmt: PtRepeatLoop) {
|
||||||
require(iterations in 257..65535) { "invalid repeat count ${stmt.position}" }
|
require(iterations in 257..65536) { "invalid repeat count ${stmt.position}" }
|
||||||
val repeatLabel = makeLabel("repeat")
|
val repeatLabel = makeLabel("repeat")
|
||||||
val counterVar = createRepeatCounterVar(DataType.UWORD, isTargetCpu(CpuType.CPU65c02), stmt)
|
val counterVar = createRepeatCounterVar(DataType.UWORD, isTargetCpu(CpuType.CPU65c02), stmt)
|
||||||
val loopcount = if(iterations and 0x00ff == 0) iterations else iterations + 0x0100 // so that the loop can simply use a double-dec
|
val loopcount = if(iterations==65536) 0 else if(iterations and 0x00ff == 0) iterations else iterations + 0x0100 // so that the loop can simply use a double-dec
|
||||||
out("""
|
out("""
|
||||||
ldy #>$loopcount
|
ldy #>$loopcount
|
||||||
lda #<$loopcount
|
lda #<$loopcount
|
||||||
|
@ -359,7 +359,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
val variable = targetArray.variable.name
|
val variable = targetArray.variable.name
|
||||||
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
||||||
|
|
||||||
val fixedIndex = constIntValue(targetArray.index)
|
val fixedIndex = targetArray.index.asConstInteger()
|
||||||
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
||||||
if(zero) {
|
if(zero) {
|
||||||
if(fixedIndex!=null) {
|
if(fixedIndex!=null) {
|
||||||
|
@ -894,7 +894,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
if(binExpr.left.type==DataType.STR || binExpr.right.type==DataType.STR) {
|
if(binExpr.left.type==DataType.STR || binExpr.right.type==DataType.STR) {
|
||||||
throw AssemblyError("str compares should have been replaced with builtin function call to do the compare")
|
throw AssemblyError("str compares should have been replaced with builtin function call to do the compare")
|
||||||
} else {
|
} else {
|
||||||
return if(constValue(binExpr.right)==0.0) {
|
return if(binExpr.right.asConstValue()==0.0) {
|
||||||
val tr = translateExpression(binExpr.left)
|
val tr = translateExpression(binExpr.left)
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
val opcode = if (notEquals) Opcode.SNZ else Opcode.SZ
|
val opcode = if (notEquals) Opcode.SNZ else Opcode.SZ
|
||||||
|
@ -1589,7 +1589,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(repeat: PtRepeatLoop): IRCodeChunks {
|
private fun translate(repeat: PtRepeatLoop): IRCodeChunks {
|
||||||
when (constIntValue(repeat.count)) {
|
when (repeat.count.asConstInteger()) {
|
||||||
0 -> return emptyList()
|
0 -> return emptyList()
|
||||||
1 -> return translateGroup(repeat.children)
|
1 -> return translateGroup(repeat.children)
|
||||||
256 -> {
|
256 -> {
|
||||||
@ -1600,18 +1600,30 @@ class IRCodeGen(
|
|||||||
|
|
||||||
val repeatLabel = createLabelName()
|
val repeatLabel = createLabelName()
|
||||||
val skipRepeatLabel = createLabelName()
|
val skipRepeatLabel = createLabelName()
|
||||||
val irDt = irType(repeat.count.type)
|
val constRepeats = repeat.count.asConstInteger()
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val countTr = expressionEval.translateExpression(repeat.count)
|
if(constRepeats==65536) {
|
||||||
addToResult(result, countTr, countTr.resultReg, -1)
|
// make use of the word wrap around to count to 65536
|
||||||
if(constIntValue(repeat.count)==null) {
|
val resultRegister = registers.nextFree()
|
||||||
// check if the counter is already zero
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, immediate = 0), null)
|
||||||
addInstr(result, IRInstruction(Opcode.BSTEQ, labelSymbol = skipRepeatLabel), null)
|
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||||
}
|
result += IRCodeChunk(null, null).also {
|
||||||
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
it += IRInstruction(Opcode.DEC, IRDataType.WORD, reg1 = resultRegister) // sets status bits
|
||||||
result += IRCodeChunk(null, null).also {
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = repeatLabel)
|
||||||
it += IRInstruction(Opcode.DEC, irDt, reg1 = countTr.resultReg) // sets status bits
|
}
|
||||||
it += IRInstruction(Opcode.BSTNE, labelSymbol = repeatLabel)
|
} else {
|
||||||
|
val irDt = irType(repeat.count.type)
|
||||||
|
val countTr = expressionEval.translateExpression(repeat.count)
|
||||||
|
addToResult(result, countTr, countTr.resultReg, -1)
|
||||||
|
if (repeat.count.asConstValue() == null) {
|
||||||
|
// check if the counter is already zero
|
||||||
|
addInstr(result, IRInstruction(Opcode.BSTEQ, labelSymbol = skipRepeatLabel), null)
|
||||||
|
}
|
||||||
|
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.DEC, irDt, reg1 = countTr.resultReg) // sets status bits
|
||||||
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = repeatLabel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result += IRCodeChunk(skipRepeatLabel, null)
|
result += IRCodeChunk(skipRepeatLabel, null)
|
||||||
return result
|
return result
|
||||||
|
@ -547,7 +547,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
val iterations = repeatLoop.iterations?.constValue(program)
|
val iterations = repeatLoop.iterations?.constValue(program)
|
||||||
if (iterations != null) {
|
if (iterations != null) {
|
||||||
require(floor(iterations.number)==iterations.number)
|
require(floor(iterations.number)==iterations.number)
|
||||||
if (iterations.number.toInt() > 65535) errors.err("repeat cannot go over 65535 iterations", iterations.position)
|
if (iterations.number.toInt() > 65536) errors.err("repeat cannot exceed 65536 iterations", iterations.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ident = repeatLoop.iterations as? IdentifierReference
|
val ident = repeatLoop.iterations as? IdentifierReference
|
||||||
@ -1700,8 +1700,10 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
private fun checkLongType(expression: Expression) {
|
private fun checkLongType(expression: Expression) {
|
||||||
if(expression.inferType(program).istype(DataType.LONG)) {
|
if(expression.inferType(program).istype(DataType.LONG)) {
|
||||||
if(errors.noErrorForLine(expression.position))
|
if(expression.parent !is RepeatLoop) {
|
||||||
errors.err("integer overflow", expression.position)
|
if (errors.noErrorForLine(expression.position))
|
||||||
|
errors.err("integer overflow", expression.position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
make repeat support 65536 iterations
|
scripts/cx16_images : add an option to keep the first palette entry black (or any specific color) (there's already the option to retain the first 16 entries)
|
||||||
|
|
||||||
scripts/cx16_images : add an option to keep the first palette entry black (there's already the option to retain the first 16 entries)
|
|
||||||
|
|
||||||
support this usage of defer:
|
support this usage of defer:
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%address $f200
|
|
||||||
%output raw
|
|
||||||
%launcher none
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.print_uwhex(cbm.MEMTOP(0, true), true)
|
cx16.r0=0
|
||||||
|
repeat 65536 {
|
||||||
|
cx16.r0++
|
||||||
|
}
|
||||||
|
txt.print_uw(cx16.r0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user