diff --git a/compiler/res/version.txt b/compiler/res/version.txt index 318489dff..819e07a22 100644 --- a/compiler/res/version.txt +++ b/compiler/res/version.txt @@ -1 +1 @@ -4.7-SNAPSHOT +5.0 diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 52af33030..cdfe5f225 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -902,7 +902,7 @@ internal class AsmGen(private val program: Program, } } else -> { - translateExpression(stmt.iterations!!) + translateExpression(stmt.iterations!!) // todo directly into AY? val dt = stmt.iterations!!.inferType(program) if(!dt.isKnown) throw AssemblyError("unknown dt") @@ -1008,7 +1008,7 @@ $counterVar .byte 0""") } private fun translate(stmt: WhenStatement) { - expressionsAsmGen.translateExpression(stmt.condition) + expressionsAsmGen.translateExpression(stmt.condition) // TODO directly into AY? val endLabel = makeLabel("choice_end") val choiceBlocks = mutableListOf>() val conditionDt = stmt.condition.inferType(program) @@ -1181,7 +1181,7 @@ $counterVar .byte 0""") out(" lda #<${asmVar} | ldy #>${asmVar} | jsr floats.MOVFM") } else -> { - // todo evaluate directly into fac1 instead of stack + // todo evaluate directly into fac1 instead of via stack intermediate translateExpression(returnvalue) out(" jsr floats.pop_float_fac1") } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 5c8babb19..1ee0be89e 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -74,7 +74,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge is AddressOf, is RangeExpr, is FunctionCall -> { - translateExpression(left) + translateExpression(left) // todo directly into AY reg? if(dt in ByteDatatypes) { asmgen.out(""" inx @@ -91,6 +91,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge bne $jumpIfFalseLabel""") return } + // TODO ....float? } else -> {} } @@ -116,7 +117,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge is AddressOf, is RangeExpr, is FunctionCall -> { - translateExpression(left) + translateExpression(left) // todo directly into AY? if(dt in ByteDatatypes) { asmgen.out(""" inx @@ -133,6 +134,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge beq $jumpIfFalseLabel""") return } + // TODO .... .float? } else -> {} } @@ -153,6 +155,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge DataType.UWORD -> translateUwordLess(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordLess(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> { + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -168,6 +171,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge DataType.UWORD -> translateUwordLessOrEqual(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordLessOrEqual(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> { + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -183,6 +187,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge DataType.UWORD -> translateUwordGreater(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordGreater(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> { + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -198,6 +203,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge DataType.UWORD -> translateUwordGreaterOrEqual(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.WORD -> translateWordGreaterOrEqual(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.FLOAT -> { + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -239,6 +245,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_ub | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -268,6 +275,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -299,6 +307,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_uw | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -329,6 +338,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -364,6 +374,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or registers asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greater_ub | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -394,6 +405,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greater_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -429,6 +441,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greater_uw | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -465,6 +478,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greater_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -507,6 +521,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.lesseq_ub | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -540,6 +555,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.lesseq_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -574,6 +590,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.lesseq_uw | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -610,6 +627,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.lesseq_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -640,6 +658,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greatereq_ub | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -672,6 +691,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greatereq_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -701,6 +721,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greatereq_uw | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -732,6 +753,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.greatereq_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -763,6 +785,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.equal_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -794,6 +817,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.notequal_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -827,6 +851,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.equal_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -862,6 +887,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args or regs asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.notequal_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -907,6 +933,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.equal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -953,6 +980,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // todo via func args translateExpression(left) translateExpression(right) asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -1103,7 +1131,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateExpression(typecast: TypecastExpression) { - translateExpression(typecast.expression) + translateExpression(typecast.expression) // todo avoid stack when(typecast.expression.inferType(program).typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { when(typecast.type) { @@ -1186,7 +1214,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge asmgen.out(" sta P8ESTACK_LO,x | dex") } else -> { - translateExpression(expr.addressExpression) + translateExpression(expr.addressExpression) // todo directly into A asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack") if(pushResultOnEstack) asmgen.out(" sta P8ESTACK_LO+1,x") @@ -1243,6 +1271,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge val leftDt = leftIDt.typeOrElse(DataType.STRUCT) val rightDt = rightIDt.typeOrElse(DataType.STRUCT) // see if we can apply some optimized routines + // TODO avoid using evaluation on stack everywhere when(expr.operator) { "+" -> { if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) { @@ -1518,6 +1547,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateExpression(expr: PrefixExpression) { + // todo avoid using stack translateExpression(expr.expression) val itype = expr.inferType(program) if(!itype.isKnown) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt index 2c872f7bf..105e26b8a 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt @@ -13,6 +13,8 @@ import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind import prog8.compiler.toHex import kotlin.math.absoluteValue +// todo reduce use of stack eval translateExpression() + internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) { internal fun translate(stmt: ForLoop) { diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index e52d838bd..24c159c60 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -213,7 +213,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg """) } else -> { - asmgen.translateExpression(value) + asmgen.translateExpression(value) // todo directly into A asmgen.out(""" inx pha diff --git a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt index eb941401d..7ea9e2030 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt @@ -54,7 +54,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg asmgen.out("+\tdec ${'$'}ffff\t; modified") } else -> { - asmgen.translateExpression(addressExpr) + asmgen.translateExpression(addressExpr) // todo directly into AY? asmgen.out(""" inx lda P8ESTACK_LO,x diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index 4b525444e..9a5f83ab6 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -114,7 +114,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen assignMemoryByte(assign.target, null, value.addressExpression as IdentifierReference) } else -> { - asmgen.translateExpression(value.addressExpression) + asmgen.translateExpression(value.addressExpression) // TODO directly into AY asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | inx") assignRegisterByte(assign.target, CpuRegister.A) } @@ -201,6 +201,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } else -> { // everything else just evaluate via the stack. + // TODO byte and word values not via stack but via A / AY registers? asmgen.translateExpression(value) if(assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes) asmgen.signExtendStackLsb(assign.source.datatype) @@ -267,6 +268,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } // give up, do it via eval stack + // TODO byte and word values not via stack but directly via A or AY registers? asmgen.translateExpression(origAssign.source.expression!!) assignStackValue(target) } @@ -1241,7 +1243,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } else -> { asmgen.out(" lda $ldaInstructionArg | pha") - asmgen.translateExpression(addressExpr) + asmgen.translateExpression(addressExpr) // TODO directly into AY asmgen.out(""" inx lda P8ESTACK_LO,x @@ -1274,7 +1276,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } else -> { asmgen.saveRegister(register, false, memoryAddress.definingSubroutine()!!) - asmgen.translateExpression(addressExpr) + asmgen.translateExpression(addressExpr) // TODO directly into AY asmgen.restoreRegister(CpuRegister.A, false) asmgen.out(""" inx diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt index c724644ca..717eecc71 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -440,7 +440,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, asmgen.out(" lda P8ESTACK_LO+1,x | tay | lda $name | jsr math.divmod_ub_asm | sta $name") } "<<" -> { - asmgen.translateExpression(value) + asmgen.translateExpression(value) // todo directly into Y asmgen.out(""" inx ldy P8ESTACK_LO,x @@ -451,7 +451,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, +""") } ">>" -> { - asmgen.translateExpression(value) + asmgen.translateExpression(value) // todo directly into Y if(dt==DataType.UBYTE) { asmgen.out(""" inx diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 4bf81045b..2ce3b64f9 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -6,8 +6,10 @@ TODO - 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) - see if we can group some errors together for instance the (now single) errors about unidentified symbols -- use VIC banking to move up the graphics bitmap memory location. Don't move it under the ROM though as that would require IRQ disabling and memory bank swapping for every bitmap manipulation -- some support for recursive subroutines? via %option recursive?: allocate all params and local vars on estack, don't allow nested subroutines, can begin by first not allowing any local variables just fixing the parameters +- use VIC banking to move up the graphics bitmap memory location. Move it to $e000 under the kernal rom? +- some support for recursive subroutines? + - via %option recursive?: allocate all params and local vars on estack, don't allow nested subroutines, can begin by first not allowing any local variables just fixing the parameters + - Or via a special recursive call operation that copies the current values of all local vars (including arguments) to the stack, replaces the arguments, jsr subroutine, and after returning copy the stack back to the local variables - get rid of all other TODO's in the code ;-) More optimizations diff --git a/examples/test.p8 b/examples/test.p8 index d68c129de..ece650769 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -13,7 +13,7 @@ main { ; byte c = strcmp(s1, s2) ; txt.print_b(c) ; txt.chrout('\n') - txt.print_ub(s1==s2) + txt.print_ub(s1<=s2) txt.chrout('\n') testX()