diff --git a/codeCore/src/prog8/code/SymbolTable.kt b/codeCore/src/prog8/code/SymbolTable.kt index c0a30b2dc..61cd69097 100644 --- a/codeCore/src/prog8/code/SymbolTable.kt +++ b/codeCore/src/prog8/code/SymbolTable.kt @@ -222,7 +222,7 @@ class StMemVar(name: String, init{ require(dt!=DataType.BOOL && dt!=DataType.ARRAY_BOOL) if(dt in ArrayDatatypes || dt == DataType.STR) - require(length!=null) { "memory mapped array or string must have known length" } + requireNotNull(length) } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 5a8ca90b9..d375412cf 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -703,8 +703,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, RegisterOrPair.Y -> "y" else -> TODO("comparison to word register") } - val assignTrue = PtInlineAssembly(" ld${reg} #1", false, assign.target.position) - val assignFalse = PtInlineAssembly(" ld${reg} #0", false, assign.target.position) + val assignTrue = PtInlineAssembly("\tld${reg} #1", false, assign.target.position) + val assignFalse = PtInlineAssembly("\tld${reg} #0", false, assign.target.position) ifPart.add(assignTrue) elsePart.add(assignFalse) val ifelse = PtIfElse(assign.position) @@ -754,7 +754,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, sta ${assign.target.asmVarname}+1""", false, assign.target.position) } } else { - assignTrue = PtInlineAssembly(" lda #1\n sta ${assign.target.asmVarname}", false, assign.target.position) + assignTrue = PtInlineAssembly("\tlda #1\n sta ${assign.target.asmVarname}", false, assign.target.position) } } TargetStorageKind.MEMORY -> { diff --git a/compiler/res/prog8lib/conv.p8 b/compiler/res/prog8lib/conv.p8 index 2310e623c..756855a71 100644 --- a/compiler/res/prog8lib/conv.p8 +++ b/compiler/res/prog8lib/conv.p8 @@ -517,16 +517,16 @@ _stop asmsub internal_ubyte2decimal(ubyte value @A) -> ubyte @Y, ubyte @X, ubyte @A { %asm {{ - ldy #'0'-1 - ldx #'9'+1 + ldy #'0'-1 + ldx #'9'+1 sec - iny - sbc #100 - bcs - + sbc #100 + bcs - - dex - adc #10 - bmi - - adc #'0'-1 + adc #10 + bmi - + adc #'0'-1 rts }} } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index a4a597af4..96d7079af 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -1059,4 +1059,28 @@ main { compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null } + + xtest("optimizing inlined functions must reference proper scopes") { + val src=""" +main { + sub start() { + other.sub1() + } + +} + +other { + sub sub2() { + cx16.r0++ + cx16.r1++ + } + + sub sub1() { + sub2() + } +}""" + + compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null + compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null + } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 0ed7e85be..ede881340 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,11 +1,14 @@ TODO ==== -virtual: txt.cls() gives compile error undefined symbol clear_screen +optimizer bug, see "optimizing inlined functions must reference proper scopes" unittest (skipped for now) +causes compiler error for virtual: just calling txt.cls() gives compile error undefined symbol clear_screen https://github.com/irmen/prog8/issues/136 (string.find register order issue) -optimization: for 65c02 sometimes clc adc #1 is generated, this can be optimized into inc a (always? or not? mind the carry flag!) +optimization: for 65c02 sometimes clc adc #1 is generated (for instance for: cx16.r0L = math.sin8u(cx16.r0L+1)), this can be optimized into inc a (always? or not? mind the carry flag!) + +optimization: for 65c02 sometimes tya pha is generated, could be just phy (mind if A gets used afterwards though!) (same for pla tay etcetera?) if-optimization: if row == NUMQUEENS { diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 87e55f135..e4139934e 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -847,7 +847,7 @@ data class IRInstruction( if(format.fpReg2==OperandDirection.UNUSED) require(fpReg2==null) { "invalid fpReg2" } if(format.immediate) { if(type==IRDataType.FLOAT) - require(immediateFp !=null) {"missing immediate fp value"} + requireNotNull(immediateFp) {"missing immediate fp value"} else require(immediate!=null || labelSymbol!=null) {"missing immediate value or labelsymbol"} } @@ -881,9 +881,7 @@ data class IRInstruction( fpReg2direction = format.fpReg2 if(opcode==Opcode.SYSCALL) { - require(immediate!=null) { - "syscall needs immediate integer for the syscall number" - } + requireNotNull(immediate) { "syscall needs immediate integer for the syscall number" } } } diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 12d3d93d5..049bd9d3f 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -148,7 +148,7 @@ class IRProgram(val name: String, if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.JUMPI && it.opcode!=Opcode.RETURN && it.opcode!=Opcode.RETURNR && it.labelSymbol!=null) { if(it.labelSymbol.startsWith('$') || it.labelSymbol.first().isDigit()) { // it's a call to an address (romsub most likely) - require(it.address!=null) + requireNotNull(it.address) } else { it.branchTarget = labeledChunks.getValue(it.labelSymbol) } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index dff567764..2b1ea0f44 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -624,7 +624,7 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsCALL(i: IRInstruction) { i.fcallArgs!!.arguments.forEach { arg -> - require(arg.address!=null) {"argument variable should have been given its memory address as well"} + requireNotNull(arg.address) {"argument variable should have been given its memory address as well"} when(arg.reg.dt) { IRDataType.BYTE -> memory.setUB(arg.address!!, registers.getUB(arg.reg.registerNum)) IRDataType.WORD -> memory.setUW(arg.address!!, registers.getUW(arg.reg.registerNum)) diff --git a/virtualmachine/src/prog8/vm/VmProgramLoader.kt b/virtualmachine/src/prog8/vm/VmProgramLoader.kt index cd9d830aa..021acf3ad 100644 --- a/virtualmachine/src/prog8/vm/VmProgramLoader.kt +++ b/virtualmachine/src/prog8/vm/VmProgramLoader.kt @@ -70,7 +70,7 @@ class VmProgramLoader { (programChunks + irProgram.globalInits).forEach { it.instructions.forEach { ins -> if (ins.labelSymbol != null && ins.opcode !in OpcodesThatBranch) - require(ins.address != null) { "instruction with labelSymbol for a var should have value set to the memory address" } + requireNotNull(ins.address) { "instruction with labelSymbol for a var should have value set to the memory address" } } }