diff --git a/codeCore/src/prog8/code/core/IMachineDefinition.kt b/codeCore/src/prog8/code/core/IMachineDefinition.kt index d3b89fd56..11b4e1266 100644 --- a/codeCore/src/prog8/code/core/IMachineDefinition.kt +++ b/codeCore/src/prog8/code/core/IMachineDefinition.kt @@ -16,6 +16,7 @@ interface IMachineDefinition { var ESTACK_LO: UInt var ESTACK_HI: UInt val PROGRAM_LOAD_ADDRESS : UInt + var GOLDEN: UIntRange val opcodeNames: Set var zeropage: Zeropage @@ -31,5 +32,7 @@ interface IMachineDefinition { require(evalStackBaseAddress and 255u == 0u) ESTACK_LO = evalStackBaseAddress ESTACK_HI = evalStackBaseAddress + 256u + require(ESTACK_LO !in GOLDEN && ESTACK_HI !in GOLDEN) { "user-set ESTACK can't be in GOLDEN ram" } } + } diff --git a/codeCore/src/prog8/code/target/atari/AtariMachineDefinition.kt b/codeCore/src/prog8/code/target/atari/AtariMachineDefinition.kt index 5ad3cca39..3cdafc5ee 100644 --- a/codeCore/src/prog8/code/target/atari/AtariMachineDefinition.kt +++ b/codeCore/src/prog8/code/target/atari/AtariMachineDefinition.kt @@ -17,6 +17,7 @@ class AtariMachineDefinition: IMachineDefinition { // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override var ESTACK_LO = 0x1a00u // $1a00-$1aff inclusive // TODO override var ESTACK_HI = 0x1b00u // $1b00-$1bff inclusive // TODO + override var GOLDEN = UIntRange.EMPTY override lateinit var zeropage: Zeropage diff --git a/codeCore/src/prog8/code/target/c128/C128MachineDefinition.kt b/codeCore/src/prog8/code/target/c128/C128MachineDefinition.kt index 63567260a..1d9384ec6 100644 --- a/codeCore/src/prog8/code/target/c128/C128MachineDefinition.kt +++ b/codeCore/src/prog8/code/target/c128/C128MachineDefinition.kt @@ -18,6 +18,7 @@ class C128MachineDefinition: IMachineDefinition { // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override var ESTACK_LO = 0x1a00u // $1a00-$1aff inclusive override var ESTACK_HI = 0x1b00u // $1b00-$1bff inclusive + override var GOLDEN = UIntRange.EMPTY // TODO does the c128 have some of this somewhere? override lateinit var zeropage: Zeropage diff --git a/codeCore/src/prog8/code/target/c64/C64MachineDefinition.kt b/codeCore/src/prog8/code/target/c64/C64MachineDefinition.kt index e3141b531..6aff33562 100644 --- a/codeCore/src/prog8/code/target/c64/C64MachineDefinition.kt +++ b/codeCore/src/prog8/code/target/c64/C64MachineDefinition.kt @@ -18,6 +18,7 @@ class C64MachineDefinition: IMachineDefinition { // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override var ESTACK_LO = 0xce00u // $ce00-$ceff inclusive override var ESTACK_HI = 0xcf00u // $ce00-$ceff inclusive + override var GOLDEN = 0xc000u until ESTACK_LO override lateinit var zeropage: Zeropage diff --git a/codeCore/src/prog8/code/target/cx16/CX16MachineDefinition.kt b/codeCore/src/prog8/code/target/cx16/CX16MachineDefinition.kt index c57ee1162..c804e4dd5 100644 --- a/codeCore/src/prog8/code/target/cx16/CX16MachineDefinition.kt +++ b/codeCore/src/prog8/code/target/cx16/CX16MachineDefinition.kt @@ -17,6 +17,7 @@ class CX16MachineDefinition: IMachineDefinition { // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) override var ESTACK_LO = 0x0400u // $0400-$04ff inclusive override var ESTACK_HI = 0x0500u // $0500-$05ff inclusive + override var GOLDEN = 0x0600u until 0x0800u override lateinit var zeropage: Zeropage diff --git a/codeCore/src/prog8/code/target/virtual/VirtualMachineDefinition.kt b/codeCore/src/prog8/code/target/virtual/VirtualMachineDefinition.kt index 9f7b1a438..75e83341c 100644 --- a/codeCore/src/prog8/code/target/virtual/VirtualMachineDefinition.kt +++ b/codeCore/src/prog8/code/target/virtual/VirtualMachineDefinition.kt @@ -20,6 +20,7 @@ class VirtualMachineDefinition: IMachineDefinition { override var ESTACK_LO = 0u // not actually used override var ESTACK_HI = 0u // not actually used + override var GOLDEN = UIntRange.EMPTY // not actually used override lateinit var zeropage: Zeropage // not actually used diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index c2ee9b101..0c5419214 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -1071,7 +1071,7 @@ $repeatLabel lda $counterVar if(saveA) out(" pha") assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) + assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) // TODO TMP_REG_ISSUE_89 if(saveA) out(" pla") out(" sta (P8ZP_SCRATCH_W2),y") @@ -1083,7 +1083,7 @@ $repeatLabel lda $counterVar } else { // copy the pointer var to zp first assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) + assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) // TODO TMP_REG_ISSUE_89 out(" lda (P8ZP_SCRATCH_W2),y") } } @@ -1579,7 +1579,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1614,7 +1614,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1651,7 +1651,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel") } @@ -1690,7 +1690,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") } @@ -1730,7 +1730,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1767,7 +1767,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1810,7 +1810,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_W2+1", "P8ZP_SCRATCH_W2") } @@ -1854,7 +1854,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) + assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") } @@ -1895,7 +1895,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1932,7 +1932,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -1977,7 +1977,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") } @@ -2025,7 +2025,7 @@ $repeatLabel lda $counterVar } assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) + assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") } @@ -2062,7 +2062,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -2096,7 +2096,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -2132,7 +2132,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) + assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") } @@ -2171,7 +2171,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") } @@ -2207,7 +2207,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel") } @@ -2244,7 +2244,7 @@ $repeatLabel lda $counterVar return assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) + assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 return code("P8ZP_SCRATCH_B1") } @@ -2311,7 +2311,7 @@ $repeatLabel lda $counterVar } else -> { assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 out(""" cmp P8ZP_SCRATCH_W2 bne $jumpIfFalseLabel @@ -2387,7 +2387,7 @@ $repeatLabel lda $counterVar } else -> { assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) + assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 out(""" cmp P8ZP_SCRATCH_W2 bne + diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 266e93a15..af79b9b14 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -255,13 +255,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, asmgen.out(" cmp ${arg2.addressExpression.constValue(program)!!.number.toHex()}") } else { asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 asmgen.out(" cmp P8ZP_SCRATCH_B1") } } else -> { asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 asmgen.out(" cmp P8ZP_SCRATCH_B1") } } @@ -289,7 +289,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, } else -> { asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_W1", DataType.UWORD, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 asmgen.out(""" cpy P8ZP_SCRATCH_W1+1 bne + diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt index 9c0abd521..aab8458ce 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt @@ -10,6 +10,7 @@ import prog8.ast.walk.IAstVisitor import prog8.code.core.ICompilationTarget import prog8.code.core.IErrorReporter import prog8.code.core.Position +import prog8.code.target.VMTarget import prog8.compiler.BuiltinFunctions @@ -107,10 +108,12 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter, errors.err("asmsub can only contain inline assembly (%asm)", subroutine.position) } - if(subroutine.name == subroutine.definingBlock.name) { - // subroutines cannot have the same name as their enclosing block, - // because this causes symbol scoping issues in the resulting assembly source - nameError(subroutine.name, subroutine.position, subroutine.definingBlock) + if(compTarget.name != VMTarget.NAME) { + if (subroutine.name == subroutine.definingBlock.name) { + // subroutines cannot have the same name as their enclosing block, + // because this causes symbol scoping issues in the resulting assembly source + errors.err("name conflict '${subroutine.name}', also defined at ${subroutine.definingBlock.position} (64tass scope nesting limitation)", subroutine.position) + } } } diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index 927c95de1..4cdbef3bc 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -270,4 +270,32 @@ mylabel: } exc.message shouldContain("cannot yet load a label address as a value") } + + test("nesting with overlapping names is ok (doesn't work for 64tass)") { + val src=""" +%import textio +%zeropage basicsafe + +main { + sub start() { + main() + main.start.start() + main.main() + + sub main() { + cx16.r0++ + } + sub start() { + cx16.r0++ + } + } + + sub main() { + cx16.r0++ + } +}""" + + val target = VMTarget() + compileText(target, false, src, writeAssembly = true) shouldNotBe null + } }) \ No newline at end of file diff --git a/docs/source/todo.rst b/docs/source/todo.rst index d6f084c5e..bd022e46a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- AstIdentifiersChecker: can a subroutine really not have the same name as its enclosing block? 64tass problem? -- attempt to fix the expression codegen bug with reused temp vars (github #89) +- attempt to fix the expression codegen bug with reused temp vars (github #89) search for 'TMP_REG_ISSUE_89' - 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen. - create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code @@ -24,7 +23,7 @@ Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ Compiler: -- add a mechanism to allocate variables into golden ram ($0400-$07ff on x16, $c000-$.... on c64 , take care of evalstack) +- add a mechanism to allocate variables into golden ram (see MachineDefinition.GOLDEN) - ir: mechanism to determine for chunks which registers are getting input values from "outside" - ir: mechanism to determine for chunks which registers are passing values out? (i.e. are used again in another chunk) - ir: peephole opt: renumber registers in chunks to start with 1 again every time (but keep entry values in mind!) diff --git a/examples/bsieve.p8 b/examples/bsieve.p8 index e21b3378a..f83f7cffc 100644 --- a/examples/bsieve.p8 +++ b/examples/bsieve.p8 @@ -43,7 +43,7 @@ main { txt.print_uw(count) txt.print(" primes\n") - float time = c64.RDTIM16() / 60.0 + float time = c64.RDTIM16() as float / 60.0 floats.print_f(time) txt.print(" sec total = ") floats.print_f(time/ITERS) diff --git a/examples/test.p8 b/examples/test.p8 index bb44b0352..29d163b4e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,55 +1,23 @@ %import textio %zeropage basicsafe - main { + bool[1] expected = [ true ] -alsostart: + sub get() -> bool { + txt.print("get() called. ") + return true + } - %asm {{ - ; inline asm in block #1 - nop - }} - - %asmbinary "../gradle.properties" - - sub start() { - - internalstart: - ubyte fact = 10 - uword ww = 1<