From b292124f3cbfa58979e275a45a02800a30462c52 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 21 Nov 2021 00:48:23 +0100 Subject: [PATCH] replaced many short/int values by unsigned types if appropriate --- .../src/prog8/compiler/target/C64Target.kt | 2 +- .../src/prog8/compiler/target/Cx16Target.kt | 2 +- .../target/c64/C64MachineDefinition.kt | 48 ++++----- .../compiler/target/cpu6502/codegen/AsmGen.kt | 8 +- .../cpu6502/codegen/BuiltinFunctionsAsmGen.kt | 2 +- .../codegen/assignment/AsmAssignment.kt | 8 +- .../codegen/assignment/AssignmentAsmGen.kt | 26 ++--- .../target/cx16/CX16MachineDefinition.kt | 26 ++--- codeGeneration/test/helpers/Dummies.kt | 2 +- compiler/src/prog8/compiler/ModuleImporter.kt | 2 +- .../compiler/astprocessing/AstChecker.kt | 4 +- .../astprocessing/StatementReorderer.kt | 2 +- compiler/test/TestMemory.kt | 14 +-- compiler/test/TestNumbers.kt | 100 +++++++++--------- compiler/test/ZeropageTests.kt | 85 +++++++-------- compiler/test/helpers/Dummies.kt | 2 +- compilerAst/src/prog8/ast/AstToplevel.kt | 4 +- compilerAst/src/prog8/ast/Extensions.kt | 14 ++- compilerAst/src/prog8/ast/Program.kt | 4 +- .../src/prog8/ast/antlr/Antlr2Kotlin.kt | 8 +- .../prog8/ast/expressions/AstExpressions.kt | 8 ++ .../src/prog8/ast/statements/AstStatements.kt | 10 +- compilerAst/test/helpers/Dummies.kt | 2 +- .../prog8/compilerinterface/AstExtensions.kt | 8 +- .../compilerinterface/BuiltinFunctions.kt | 2 + .../compilerinterface/CompilationOptions.kt | 2 +- .../compilerinterface/IMachineDefinition.kt | 10 +- .../src/prog8/compilerinterface/Zeropage.kt | 44 ++++---- docs/source/todo.rst | 1 - 29 files changed, 238 insertions(+), 212 deletions(-) diff --git a/codeGeneration/src/prog8/compiler/target/C64Target.kt b/codeGeneration/src/prog8/compiler/target/C64Target.kt index c16ecad57..6dc54f620 100644 --- a/codeGeneration/src/prog8/compiler/target/C64Target.kt +++ b/codeGeneration/src/prog8/compiler/target/C64Target.kt @@ -29,7 +29,7 @@ object C64Target: ICompilationTarget { in WordDatatypes -> 2 DataType.FLOAT -> machine.FLOAT_MEM_SIZE in PassByReferenceDatatypes -> machine.POINTER_MEM_SIZE - else -> -9999999 + else -> Int.MIN_VALUE } } } diff --git a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt index 959081946..29192f4f3 100644 --- a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt +++ b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt @@ -29,7 +29,7 @@ object Cx16Target: ICompilationTarget { in WordDatatypes -> 2 DataType.FLOAT -> machine.FLOAT_MEM_SIZE in PassByReferenceDatatypes -> machine.POINTER_MEM_SIZE - else -> -9999999 + else -> Int.MIN_VALUE } } } diff --git a/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt b/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt index 2667c0baa..4244016ad 100644 --- a/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt +++ b/codeGeneration/src/prog8/compiler/target/c64/C64MachineDefinition.kt @@ -16,12 +16,12 @@ object C64MachineDefinition: IMachineDefinition { override val FLOAT_MAX_NEGATIVE = -1.7014118345e+38 // bytes: 255,255,255,255,255 override val FLOAT_MEM_SIZE = 5 override val POINTER_MEM_SIZE = 2 - override val BASIC_LOAD_ADDRESS = 0x0801 - override val RAW_LOAD_ADDRESS = 0xc000 + override val BASIC_LOAD_ADDRESS = 0x0801u + override val RAW_LOAD_ADDRESS = 0xc000u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) - override val ESTACK_LO = 0xce00 // $ce00-$ceff inclusive - override val ESTACK_HI = 0xcf00 // $ce00-$ceff inclusive + override val ESTACK_LO = 0xce00u // $ce00-$ceff inclusive + override val ESTACK_HI = 0xcf00u // $ce00-$ceff inclusive override lateinit var zeropage: Zeropage @@ -56,7 +56,7 @@ object C64MachineDefinition: IMachineDefinition { } } - override fun isIOAddress(address: Int): Boolean = address==0 || address==1 || address in 0xd000..0xdfff + override fun isIOAddress(address: UInt): Boolean = address==0u || address==1u || address in 0xd000u..0xdfffu override fun initializeZeropage(compilerOptions: CompilationOptions) { zeropage = C64Zeropage(compilerOptions) @@ -76,10 +76,10 @@ object C64MachineDefinition: IMachineDefinition { class C64Zeropage(options: CompilationOptions) : Zeropage(options) { - override val SCRATCH_B1 = 0x02 // temp storage for a single byte - override val SCRATCH_REG = 0x03 // temp storage for a register, must be B1+1 - override val SCRATCH_W1 = 0xfb // temp storage 1 for a word $fb+$fc - override val SCRATCH_W2 = 0xfd // temp storage 2 for a word $fb+$fc + override val SCRATCH_B1 = 0x02u // temp storage for a single byte + override val SCRATCH_REG = 0x03u // temp storage for a register, must be B1+1 + override val SCRATCH_W1 = 0xfbu // temp storage 1 for a word $fb+$fc + override val SCRATCH_W2 = 0xfdu // temp storage 2 for a word $fb+$fc init { @@ -87,9 +87,9 @@ object C64MachineDefinition: IMachineDefinition { throw InternalCompilerException("when floats are enabled, zero page type should be 'floatsafe' or 'basicsafe' or 'dontuse'") if (options.zeropage == ZeropageType.FULL) { - free.addAll(0x04..0xf9) - free.add(0xff) - free.removeAll(setOf(0xa0, 0xa1, 0xa2, 0x91, 0xc0, 0xc5, 0xcb, 0xf5, 0xf6)) // these are updated by IRQ + free.addAll(0x04u..0xf9u) + free.add(0xffu) + free.removeAll(setOf(0xa0u, 0xa1u, 0xa2u, 0x91u, 0xc0u, 0xc5u, 0xcbu, 0xf5u, 0xf6u)) // these are updated by IRQ } else { if (options.zeropage == ZeropageType.KERNALSAFE || options.zeropage == ZeropageType.FLOATSAFE) { free.addAll(listOf( @@ -106,19 +106,19 @@ object C64MachineDefinition: IMachineDefinition { 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0xff // 0x90-0xfa is 'kernal work storage area' - )) + ).map{it.toUInt()}) } if (options.zeropage == ZeropageType.FLOATSAFE) { // remove the zeropage locations used for floating point operations from the free list - free.removeAll(setOf( + free.removeAll(listOf( 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x12, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0xff - )) + ).map{it.toUInt()}) } if(options.zeropage!= ZeropageType.DONTUSE) { @@ -126,7 +126,7 @@ object C64MachineDefinition: IMachineDefinition { // these are valid for the C-64 but allow BASIC to keep running fully *as long as you don't use tape I/O* free.addAll(listOf(0x04, 0x05, 0x06, 0x0a, 0x0e, 0x92, 0x96, 0x9b, 0x9c, 0x9e, 0x9f, 0xa5, 0xa6, - 0xb0, 0xb1, 0xbe, 0xbf, 0xf9)) + 0xb0, 0xb1, 0xbe, 0xbf, 0xf9).map{it.toUInt()}) } else { // don't use the zeropage at all free.clear() @@ -137,11 +137,11 @@ object C64MachineDefinition: IMachineDefinition { } } - data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, val b4: Short): + data class Mflpt5(val b0: UByte, val b1: UByte, val b2: UByte, val b3: UByte, val b4: UByte): IMachineFloat { companion object { - val zero = Mflpt5(0, 0, 0, 0, 0) + val zero = Mflpt5(0u, 0u, 0u, 0u, 0u) fun fromNumber(num: Number): Mflpt5 { // see https://en.wikipedia.org/wiki/Microsoft_Binary_Format // and https://sourceforge.net/p/acme-crossass/code-0/62/tree/trunk/ACME_Lib/cbm/mflpt.a @@ -175,11 +175,11 @@ object C64MachineDefinition: IMachineDefinition { else -> { val mantLong = mantissa.toLong() Mflpt5( - exponent.toShort(), - (mantLong.and(0x7f000000L) ushr 24).or(sign).toShort(), - (mantLong.and(0x00ff0000L) ushr 16).toShort(), - (mantLong.and(0x0000ff00L) ushr 8).toShort(), - (mantLong.and(0x000000ffL)).toShort()) + exponent.toUByte(), + (mantLong.and(0x7f000000L) ushr 24).or(sign).toUByte(), + (mantLong.and(0x00ff0000L) ushr 16).toUByte(), + (mantLong.and(0x0000ff00L) ushr 8).toUByte(), + (mantLong.and(0x000000ffL)).toUByte()) } } } @@ -187,7 +187,7 @@ object C64MachineDefinition: IMachineDefinition { override fun toDouble(): Double { if (this == zero) return 0.0 - val exp = b0 - 128 + val exp = b0.toInt() - 128 val sign = (b1.toInt() and 0x80) > 0 val number = 0x80000000L.or(b1.toLong() shl 24).or(b2.toLong() shl 16).or(b3.toLong() shl 8).or(b4.toLong()) val result = number.toDouble() * (2.0).pow(exp) / 0x100000000 diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index 6b2ab6ce9..d3e3c71cd 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -40,7 +40,7 @@ class AsmGen(private val program: Program, private val assemblyLines = mutableListOf() private val globalFloatConsts = mutableMapOf() // all float values in the entire program (value -> varname) - private val allocatedZeropageVariables = mutableMapOf>() + private val allocatedZeropageVariables = mutableMapOf>() private val breakpointLabels = mutableListOf() private val forloopsAsmGen = ForLoopsAsmGen(program, this) private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this) @@ -49,7 +49,7 @@ class AsmGen(private val program: Program, private val assignmentAsmGen = AssignmentAsmGen(program, this) private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) internal val loopEndLabels = ArrayDeque() - internal val slabs = mutableMapOf() + internal val slabs = mutableMapOf() internal val removals = mutableListOf>() private val blockVariableInitializers = program.allBlocks.associateWith { it.statements.filterIsInstance() } @@ -119,7 +119,7 @@ class AsmGen(private val program: Program, out("\n.cpu '$cpu'\n.enc 'none'\n") program.actualLoadAddress = program.definedLoadAddress - if (program.actualLoadAddress == 0) // fix load address + if (program.actualLoadAddress == 0u) // fix load address program.actualLoadAddress = if (options.launcher == LauncherType.BASIC) compTarget.machine.BASIC_LOAD_ADDRESS else compTarget.machine.RAW_LOAD_ADDRESS @@ -134,7 +134,7 @@ class AsmGen(private val program: Program, when { options.launcher == LauncherType.BASIC -> { - if (program.actualLoadAddress != 0x0801) + if (program.actualLoadAddress != 0x0801u) throw AssemblyError("BASIC output must have load address $0801") out("; ---- basic program with sys call ----") out("* = ${program.actualLoadAddress.toHex()}") diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt index 86f2afe9e..c1ee8843c 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/BuiltinFunctionsAsmGen.kt @@ -250,7 +250,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val throw AssemblyError("should not discard result of memory allocation at $fcall") val nameRef = fcall.args[0] as IdentifierReference val name = (nameRef.targetVarDecl(program)!!.value as StringLiteralValue).value - val size = (fcall.args[1] as NumericLiteralValue).number.toInt() + val size = (fcall.args[1] as NumericLiteralValue).number.toUInt() val existingSize = asmgen.slabs[name] if(existingSize!=null && existingSize!=size) diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt index 7a372a3f8..436ba603a 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AsmAssignment.kt @@ -39,8 +39,8 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, val origAstTarget: AssignTarget? = null ) { - val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0} - val constArrayIndexValue by lazy { array?.indexer?.constIndex() } + val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toUInt() ?: 0u} + val constArrayIndexValue by lazy { array?.indexer?.constIndex()?.toUInt() } val asmVarname: String by lazy { if (array == null) variableAsmName!! @@ -111,8 +111,8 @@ internal class AsmAssignSource(val kind: SourceStorageKind, val expression: Expression? = null ) { - val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0} - val constArrayIndexValue by lazy { array?.indexer?.constIndex() } + val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toUInt() ?: 0u} + val constArrayIndexValue by lazy { array?.indexer?.constIndex()?.toUInt() } val asmVarname: String get() = if(array==null) diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index b04e2013f..6d7d32940 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -40,7 +40,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen // simple case: assign a constant number val num = assign.source.number!!.number when (assign.target.datatype) { - DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num.toInt().toShort()) + DataType.UBYTE, DataType.BYTE -> assignConstantByte(assign.target, num.toInt()) DataType.UWORD, DataType.WORD -> assignConstantWord(assign.target, num.toInt()) DataType.FLOAT -> assignConstantFloat(assign.target, num) else -> throw AssemblyError("weird numval type") @@ -128,7 +128,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen val value = assign.source.memory!! when (value.addressExpression) { is NumericLiteralValue -> { - val address = (value.addressExpression as NumericLiteralValue).number.toInt() + val address = (value.addressExpression as NumericLiteralValue).number.toUInt() assignMemoryByte(assign.target, address, null) } is IdentifierReference -> { @@ -342,7 +342,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen when (value.addressExpression) { is NumericLiteralValue -> { - val address = (value.addressExpression as NumericLiteralValue).number.toInt() + val address = (value.addressExpression as NumericLiteralValue).number.toUInt() assignMemoryByteIntoWord(target, address, null) return } @@ -802,7 +802,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } TargetStorageKind.ARRAY -> { if(target.constArrayIndexValue!=null) { - val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype) + val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt() when(target.datatype) { in ByteDatatypes -> { asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname}+$scaledIdx") @@ -1012,7 +1012,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen TargetStorageKind.ARRAY -> { target.array!! if(target.constArrayIndexValue!=null) { - val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype) + val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt() when(target.datatype) { in ByteDatatypes -> { asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx") @@ -1236,7 +1236,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } TargetStorageKind.ARRAY -> { if (target.constArrayIndexValue!=null) { - val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype) + val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt() asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx") } else { @@ -1289,7 +1289,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } TargetStorageKind.ARRAY -> { if (wordtarget.constArrayIndexValue!=null) { - val scaledIdx = wordtarget.constArrayIndexValue!! * 2 + val scaledIdx = wordtarget.constArrayIndexValue!! * 2u asmgen.out(" lda $sourceName") asmgen.signExtendAYlsb(DataType.BYTE) asmgen.out(" sta ${wordtarget.asmVarname}+$scaledIdx | sty ${wordtarget.asmVarname}+$scaledIdx+1") @@ -1357,7 +1357,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } TargetStorageKind.ARRAY -> { if (wordtarget.constArrayIndexValue!=null) { - val scaledIdx = wordtarget.constArrayIndexValue!! * 2 + val scaledIdx = wordtarget.constArrayIndexValue!! * 2u asmgen.out(" lda $sourceName | sta ${wordtarget.asmVarname}+$scaledIdx") if(asmgen.isTargetCpu(CpuType.CPU65c02)) asmgen.out(" stz ${wordtarget.asmVarname}+$scaledIdx+1") @@ -1517,7 +1517,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } TargetStorageKind.ARRAY -> { if (target.constArrayIndexValue!=null) { - val idx = target.constArrayIndexValue!! * 2 + val idx = target.constArrayIndexValue!! * 2u when (regs) { RegisterOrPair.AX -> asmgen.out(" sta ${target.asmVarname}+$idx | stx ${target.asmVarname}+$idx+1") RegisterOrPair.AY -> asmgen.out(" sta ${target.asmVarname}+$idx | sty ${target.asmVarname}+$idx+1") @@ -1738,8 +1738,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } - private fun assignConstantByte(target: AsmAssignTarget, byte: Short) { - if(byte==0.toShort() && asmgen.isTargetCpu(CpuType.CPU65c02)) { + private fun assignConstantByte(target: AsmAssignTarget, byte: Int) { + if(byte==0 && asmgen.isTargetCpu(CpuType.CPU65c02)) { // optimize setting zero value for this cpu when(target.kind) { TargetStorageKind.VARIABLE -> { @@ -1972,7 +1972,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } - private fun assignMemoryByte(target: AsmAssignTarget, address: Int?, identifier: IdentifierReference?) { + private fun assignMemoryByte(target: AsmAssignTarget, address: UInt?, identifier: IdentifierReference?) { if (address != null) { when(target.kind) { TargetStorageKind.VARIABLE -> { @@ -2056,7 +2056,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } - private fun assignMemoryByteIntoWord(wordtarget: AsmAssignTarget, address: Int?, identifier: IdentifierReference?) { + private fun assignMemoryByteIntoWord(wordtarget: AsmAssignTarget, address: UInt?, identifier: IdentifierReference?) { if (address != null) { when(wordtarget.kind) { TargetStorageKind.VARIABLE -> { diff --git a/codeGeneration/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt b/codeGeneration/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt index 141438ed0..6328d9391 100644 --- a/codeGeneration/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt +++ b/codeGeneration/src/prog8/compiler/target/cx16/CX16MachineDefinition.kt @@ -16,12 +16,12 @@ object CX16MachineDefinition: IMachineDefinition { override val FLOAT_MAX_NEGATIVE = -1.7014118345e+38 // bytes: 255,255,255,255,255 override val FLOAT_MEM_SIZE = 5 override val POINTER_MEM_SIZE = 2 - override val BASIC_LOAD_ADDRESS = 0x0801 - override val RAW_LOAD_ADDRESS = 0x8000 + override val BASIC_LOAD_ADDRESS = 0x0801u + override val RAW_LOAD_ADDRESS = 0x8000u // the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations) - override val ESTACK_LO = 0x0400 // $0400-$04ff inclusive - override val ESTACK_HI = 0x0500 // $0500-$05ff inclusive + override val ESTACK_LO = 0x0400u // $0400-$04ff inclusive + override val ESTACK_HI = 0x0500u // $0500-$05ff inclusive override lateinit var zeropage: Zeropage @@ -67,7 +67,7 @@ object CX16MachineDefinition: IMachineDefinition { } } - override fun isIOAddress(address: Int): Boolean = address==0 || address==1 || address in 0x9f00..0x9fff + override fun isIOAddress(address: UInt): Boolean = address==0u || address==1u || address in 0x9f00u..0x9fffu override fun initializeZeropage(compilerOptions: CompilationOptions) { zeropage = CX16Zeropage(compilerOptions) @@ -89,10 +89,10 @@ object CX16MachineDefinition: IMachineDefinition { class CX16Zeropage(options: CompilationOptions) : Zeropage(options) { - override val SCRATCH_B1 = 0x7a // temp storage for a single byte - override val SCRATCH_REG = 0x7b // temp storage for a register, must be B1+1 - override val SCRATCH_W1 = 0x7c // temp storage 1 for a word $7c+$7d - override val SCRATCH_W2 = 0x7e // temp storage 2 for a word $7e+$7f + override val SCRATCH_B1 = 0x7au // temp storage for a single byte + override val SCRATCH_REG = 0x7bu // temp storage for a register, must be B1+1 + override val SCRATCH_W1 = 0x7cu // temp storage 1 for a word $7c+$7d + override val SCRATCH_W2 = 0x7eu // temp storage 2 for a word $7e+$7f init { @@ -103,14 +103,14 @@ object CX16MachineDefinition: IMachineDefinition { when (options.zeropage) { ZeropageType.FULL -> { - free.addAll(0x22..0xff) + free.addAll(0x22u..0xffu) } ZeropageType.KERNALSAFE -> { - free.addAll(0x22..0x7f) - free.addAll(0xa9..0xff) + free.addAll(0x22u..0x7fu) + free.addAll(0xa9u..0xffu) } ZeropageType.BASICSAFE -> { - free.addAll(0x22..0x7f) + free.addAll(0x22u..0x7fu) } ZeropageType.DONTUSE -> { free.clear() // don't use zeropage at all diff --git a/codeGeneration/test/helpers/Dummies.kt b/codeGeneration/test/helpers/Dummies.kt index 412138f78..bc06d2ab8 100644 --- a/codeGeneration/test/helpers/Dummies.kt +++ b/codeGeneration/test/helpers/Dummies.kt @@ -23,7 +23,7 @@ internal val DummyFunctions = object : IBuiltinFunctions { } internal val DummyMemsizer = object : IMemSizer { - override fun memorySize(dt: DataType): Int = 0 + override fun memorySize(dt: DataType) = 0 } internal val DummyStringEncoder = object : IStringEncoding { diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index 1dc8526ae..425f6c0c3 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -51,7 +51,7 @@ class ModuleImporter(private val program: Program, fun importLibraryModule(name: String): Module? { val import = Directive("%import", listOf( - DirectiveArg("", name, 42, position = Position("<<>>", 0, 0, 0)) + DirectiveArg("", name, 42u, position = Position("<<>>", 0, 0, 0)) ), Position("<<>>", 0, 0, 0)) return executeImportDirective(import, null) } diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index df24cb507..5cc40b4fb 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -172,14 +172,14 @@ internal class AstChecker(private val program: Program, } val addr = jump.address - if(addr!=null && (addr < 0 || addr > 65535)) + if(addr!=null && addr > 65535u) errors.err("jump address must be valid integer 0..\$ffff", jump.position) super.visit(jump) } override fun visit(block: Block) { val addr = block.address - if(addr!=null && (addr<0 || addr>65535)) { + if(addr!=null && addr>65535u) { errors.err("block memory address must be valid integer 0..\$ffff", block.position) } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 3bd0b2a8e..b476f08b5 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -26,7 +26,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport override fun after(module: Module, parent: Node): Iterable { val (blocks, other) = module.statements.partition { it is Block } - module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: Int.MAX_VALUE }).toMutableList() + module.statements = other.asSequence().plus(blocks.sortedBy { (it as Block).address ?: UInt.MAX_VALUE }).toMutableList() val mainBlock = module.statements.filterIsInstance().firstOrNull { it.name=="main" } if(mainBlock!=null && mainBlock.address==null) { diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index 3eb982856..648ac99ca 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -109,7 +109,7 @@ class TestMemory: FunSpec({ target.isIOAddress(C64Target.machine) shouldBe true } - fun createTestProgramForMemoryRefViaVar(address: Int, vartype: VarDeclType): AssignTarget { + fun createTestProgramForMemoryRefViaVar(address: UInt, vartype: VarDeclType): AssignTarget { val decl = VarDecl(vartype, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, false, Position.DUMMY) val memexpr = IdentifierReference(listOf("address"), Position.DUMMY) val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) @@ -119,17 +119,17 @@ class TestMemory: FunSpec({ } test("identifier mapped to IO memory on C64") { - var target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.VAR) + var target = createTestProgramForMemoryRefViaVar(0x1000u, VarDeclType.VAR) target.isIOAddress(C64Target.machine) shouldBe false - target = createTestProgramForMemoryRefViaVar(0xd020, VarDeclType.VAR) + target = createTestProgramForMemoryRefViaVar(0xd020u, VarDeclType.VAR) target.isIOAddress(C64Target.machine) shouldBe false - target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.CONST) + target = createTestProgramForMemoryRefViaVar(0x1000u, VarDeclType.CONST) target.isIOAddress(C64Target.machine) shouldBe false - target = createTestProgramForMemoryRefViaVar(0xd020, VarDeclType.CONST) + target = createTestProgramForMemoryRefViaVar(0xd020u, VarDeclType.CONST) target.isIOAddress(C64Target.machine) shouldBe true - target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.MEMORY) + target = createTestProgramForMemoryRefViaVar(0x1000u, VarDeclType.MEMORY) target.isIOAddress(C64Target.machine) shouldBe false - target = createTestProgramForMemoryRefViaVar(0xd020, VarDeclType.MEMORY) + target = createTestProgramForMemoryRefViaVar(0xd020u, VarDeclType.MEMORY) target.isIOAddress(C64Target.machine) shouldBe true } diff --git a/compiler/test/TestNumbers.kt b/compiler/test/TestNumbers.kt index df125939b..1d85706ed 100644 --- a/compiler/test/TestNumbers.kt +++ b/compiler/test/TestNumbers.kt @@ -44,37 +44,37 @@ class TestNumbers: FunSpec({ } test("testFloatToMflpt5") { - Mflpt5.fromNumber(0) shouldBe Mflpt5(0x00, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(3.141592653) shouldBe Mflpt5(0x82, 0x49, 0x0F, 0xDA, 0xA1) - Mflpt5.fromNumber(3.141592653589793) shouldBe Mflpt5(0x82, 0x49, 0x0F, 0xDA, 0xA2) - Mflpt5.fromNumber(32768) shouldBe Mflpt5(0x90, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(-32768) shouldBe Mflpt5(0x90, 0x80, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(1) shouldBe Mflpt5(0x81, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(0.7071067812) shouldBe Mflpt5(0x80, 0x35, 0x04, 0xF3, 0x34) - Mflpt5.fromNumber(0.7071067811865476) shouldBe Mflpt5(0x80, 0x35, 0x04, 0xF3, 0x33) - Mflpt5.fromNumber(1.4142135624) shouldBe Mflpt5(0x81, 0x35, 0x04, 0xF3, 0x34) - Mflpt5.fromNumber(1.4142135623730951) shouldBe Mflpt5(0x81, 0x35, 0x04, 0xF3, 0x33) - Mflpt5.fromNumber(-.5) shouldBe Mflpt5(0x80, 0x80, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(0.69314718061) shouldBe Mflpt5(0x80, 0x31, 0x72, 0x17, 0xF8) - Mflpt5.fromNumber(0.6931471805599453) shouldBe Mflpt5(0x80, 0x31, 0x72, 0x17, 0xF7) - Mflpt5.fromNumber(10) shouldBe Mflpt5(0x84, 0x20, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(1000000000) shouldBe Mflpt5(0x9E, 0x6E, 0x6B, 0x28, 0x00) - Mflpt5.fromNumber(.5) shouldBe Mflpt5(0x80, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(1.4426950408889634) shouldBe Mflpt5(0x81, 0x38, 0xAA, 0x3B, 0x29) - Mflpt5.fromNumber(1.5707963267948966) shouldBe Mflpt5(0x81, 0x49, 0x0F, 0xDA, 0xA2) - Mflpt5.fromNumber(6.283185307179586) shouldBe Mflpt5(0x83, 0x49, 0x0F, 0xDA, 0xA2) - Mflpt5.fromNumber(.25) shouldBe Mflpt5(0x7F, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(123.45678e22) shouldBe Mflpt5(0xd1, 0x02, 0xb7, 0x06, 0xfb) - Mflpt5.fromNumber(-123.45678e-22) shouldBe Mflpt5(0x3e, 0xe9, 0x34, 0x09, 0x1b) + Mflpt5.fromNumber(0) shouldBe Mflpt5(0x00u, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(3.141592653) shouldBe Mflpt5(0x82u, 0x49u, 0x0Fu, 0xDAu, 0xA1u) + Mflpt5.fromNumber(3.141592653589793) shouldBe Mflpt5(0x82u, 0x49u, 0x0Fu, 0xDAu, 0xA2u) + Mflpt5.fromNumber(32768) shouldBe Mflpt5(0x90u, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(-32768) shouldBe Mflpt5(0x90u, 0x80u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(1) shouldBe Mflpt5(0x81u, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(0.7071067812) shouldBe Mflpt5(0x80u, 0x35u, 0x04u, 0xF3u, 0x34u) + Mflpt5.fromNumber(0.7071067811865476) shouldBe Mflpt5(0x80u, 0x35u, 0x04u, 0xF3u, 0x33u) + Mflpt5.fromNumber(1.4142135624) shouldBe Mflpt5(0x81u, 0x35u, 0x04u, 0xF3u, 0x34u) + Mflpt5.fromNumber(1.4142135623730951) shouldBe Mflpt5(0x81u, 0x35u, 0x04u, 0xF3u, 0x33u) + Mflpt5.fromNumber(-.5) shouldBe Mflpt5(0x80u, 0x80u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(0.69314718061) shouldBe Mflpt5(0x80u, 0x31u, 0x72u, 0x17u, 0xF8u) + Mflpt5.fromNumber(0.6931471805599453) shouldBe Mflpt5(0x80u, 0x31u, 0x72u, 0x17u, 0xF7u) + Mflpt5.fromNumber(10) shouldBe Mflpt5(0x84u, 0x20u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(1000000000) shouldBe Mflpt5(0x9Eu, 0x6Eu, 0x6Bu, 0x28u, 0x00u) + Mflpt5.fromNumber(.5) shouldBe Mflpt5(0x80u, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(1.4426950408889634) shouldBe Mflpt5(0x81u, 0x38u, 0xAAu, 0x3Bu, 0x29u) + Mflpt5.fromNumber(1.5707963267948966) shouldBe Mflpt5(0x81u, 0x49u, 0x0Fu, 0xDAu, 0xA2u) + Mflpt5.fromNumber(6.283185307179586) shouldBe Mflpt5(0x83u, 0x49u, 0x0Fu, 0xDAu, 0xA2u) + Mflpt5.fromNumber(.25) shouldBe Mflpt5(0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(123.45678e22) shouldBe Mflpt5(0xd1u, 0x02u, 0xb7u, 0x06u, 0xfbu) + Mflpt5.fromNumber(-123.45678e-22) shouldBe Mflpt5(0x3eu, 0xe9u, 0x34u, 0x09u, 0x1bu) } test("testFloatRange") { - Mflpt5.fromNumber(FLOAT_MAX_POSITIVE) shouldBe Mflpt5(0xff, 0x7f, 0xff, 0xff, 0xff) - Mflpt5.fromNumber(FLOAT_MAX_NEGATIVE) shouldBe Mflpt5(0xff, 0xff, 0xff, 0xff, 0xff) - Mflpt5.fromNumber(1.7e-38) shouldBe Mflpt5(0x03, 0x39, 0x1d, 0x15, 0x63) - Mflpt5.fromNumber(1.7e-39) shouldBe Mflpt5(0x00, 0x00, 0x00, 0x00, 0x00) - Mflpt5.fromNumber(-1.7e-38) shouldBe Mflpt5(0x03, 0xb9, 0x1d, 0x15, 0x63) - Mflpt5.fromNumber(-1.7e-39) shouldBe Mflpt5(0x00, 0x00, 0x00, 0x00, 0x00) + Mflpt5.fromNumber(FLOAT_MAX_POSITIVE) shouldBe Mflpt5(0xffu, 0x7fu, 0xffu, 0xffu, 0xffu) + Mflpt5.fromNumber(FLOAT_MAX_NEGATIVE) shouldBe Mflpt5(0xffu, 0xffu, 0xffu, 0xffu, 0xffu) + Mflpt5.fromNumber(1.7e-38) shouldBe Mflpt5(0x03u, 0x39u, 0x1du, 0x15u, 0x63u) + Mflpt5.fromNumber(1.7e-39) shouldBe Mflpt5(0x00u, 0x00u, 0x00u, 0x00u, 0x00u) + Mflpt5.fromNumber(-1.7e-38) shouldBe Mflpt5(0x03u, 0xb9u, 0x1du, 0x15u, 0x63u) + Mflpt5.fromNumber(-1.7e-39) shouldBe Mflpt5(0x00u, 0x00u, 0x00u, 0x00u, 0x00u) shouldThrow { Mflpt5.fromNumber(1.7014118346e+38) } shouldThrow { Mflpt5.fromNumber(-1.7014118346e+38) } shouldThrow { Mflpt5.fromNumber(1.7014118347e+38) } @@ -84,27 +84,27 @@ class TestNumbers: FunSpec({ test("testMflpt5ToFloat") { val epsilon=0.000000001 - Mflpt5(0x00, 0x00, 0x00, 0x00, 0x00).toDouble() shouldBe 0.0 - Mflpt5(0x82, 0x49, 0x0F, 0xDA, 0xA1).toDouble() shouldBe(3.141592653 plusOrMinus epsilon) - Mflpt5(0x82, 0x49, 0x0F, 0xDA, 0xA2).toDouble() shouldBe(3.141592653589793 plusOrMinus epsilon) - Mflpt5(0x90, 0x00, 0x00, 0x00, 0x00).toDouble() shouldBe 32768.0 - Mflpt5(0x90, 0x80, 0x00, 0x00, 0x00).toDouble() shouldBe -32768.0 - Mflpt5(0x81, 0x00, 0x00, 0x00, 0x00).toDouble() shouldBe 1.0 - Mflpt5(0x80, 0x35, 0x04, 0xF3, 0x34).toDouble() shouldBe(0.7071067812 plusOrMinus epsilon) - Mflpt5(0x80, 0x35, 0x04, 0xF3, 0x33).toDouble() shouldBe(0.7071067811865476 plusOrMinus epsilon) - Mflpt5(0x81, 0x35, 0x04, 0xF3, 0x34).toDouble() shouldBe(1.4142135624 plusOrMinus epsilon) - Mflpt5(0x81, 0x35, 0x04, 0xF3, 0x33).toDouble() shouldBe(1.4142135623730951 plusOrMinus epsilon) - Mflpt5(0x80, 0x80, 0x00, 0x00, 0x00).toDouble() shouldBe -.5 - Mflpt5(0x80, 0x31, 0x72, 0x17, 0xF8).toDouble() shouldBe(0.69314718061 plusOrMinus epsilon) - Mflpt5(0x80, 0x31, 0x72, 0x17, 0xF7).toDouble() shouldBe(0.6931471805599453 plusOrMinus epsilon) - Mflpt5(0x84, 0x20, 0x00, 0x00, 0x00).toDouble() shouldBe 10.0 - Mflpt5(0x9E, 0x6E, 0x6B, 0x28, 0x00).toDouble() shouldBe 1000000000.0 - Mflpt5(0x80, 0x00, 0x00, 0x00, 0x00).toDouble() shouldBe .5 - Mflpt5(0x81, 0x38, 0xAA, 0x3B, 0x29).toDouble() shouldBe(1.4426950408889634 plusOrMinus epsilon) - Mflpt5(0x81, 0x49, 0x0F, 0xDA, 0xA2).toDouble() shouldBe(1.5707963267948966 plusOrMinus epsilon) - Mflpt5(0x83, 0x49, 0x0F, 0xDA, 0xA2).toDouble() shouldBe(6.283185307179586 plusOrMinus epsilon) - Mflpt5(0x7F, 0x00, 0x00, 0x00, 0x00).toDouble() shouldBe .25 - Mflpt5(0xd1, 0x02, 0xb7, 0x06, 0xfb).toDouble() shouldBe(123.45678e22 plusOrMinus 1.0e15) - Mflpt5(0x3e, 0xe9, 0x34, 0x09, 0x1b).toDouble() shouldBe(-123.45678e-22 plusOrMinus epsilon) + Mflpt5(0x00u, 0x00u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe 0.0 + Mflpt5(0x82u, 0x49u, 0x0Fu, 0xDAu, 0xA1u).toDouble() shouldBe(3.141592653 plusOrMinus epsilon) + Mflpt5(0x82u, 0x49u, 0x0Fu, 0xDAu, 0xA2u).toDouble() shouldBe(3.141592653589793 plusOrMinus epsilon) + Mflpt5(0x90u, 0x00u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe 32768.0 + Mflpt5(0x90u, 0x80u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe -32768.0 + Mflpt5(0x81u, 0x00u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe 1.0 + Mflpt5(0x80u, 0x35u, 0x04u, 0xF3u, 0x34u).toDouble() shouldBe(0.7071067812 plusOrMinus epsilon) + Mflpt5(0x80u, 0x35u, 0x04u, 0xF3u, 0x33u).toDouble() shouldBe(0.7071067811865476 plusOrMinus epsilon) + Mflpt5(0x81u, 0x35u, 0x04u, 0xF3u, 0x34u).toDouble() shouldBe(1.4142135624 plusOrMinus epsilon) + Mflpt5(0x81u, 0x35u, 0x04u, 0xF3u, 0x33u).toDouble() shouldBe(1.4142135623730951 plusOrMinus epsilon) + Mflpt5(0x80u, 0x80u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe -.5 + Mflpt5(0x80u, 0x31u, 0x72u, 0x17u, 0xF8u).toDouble() shouldBe(0.69314718061 plusOrMinus epsilon) + Mflpt5(0x80u, 0x31u, 0x72u, 0x17u, 0xF7u).toDouble() shouldBe(0.6931471805599453 plusOrMinus epsilon) + Mflpt5(0x84u, 0x20u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe 10.0 + Mflpt5(0x9Eu, 0x6Eu, 0x6Bu, 0x28u, 0x00u).toDouble() shouldBe 1000000000.0 + Mflpt5(0x80u, 0x00u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe .5 + Mflpt5(0x81u, 0x38u, 0xAAu, 0x3Bu, 0x29u).toDouble() shouldBe(1.4426950408889634 plusOrMinus epsilon) + Mflpt5(0x81u, 0x49u, 0x0Fu, 0xDAu, 0xA2u).toDouble() shouldBe(1.5707963267948966 plusOrMinus epsilon) + Mflpt5(0x83u, 0x49u, 0x0Fu, 0xDAu, 0xA2u).toDouble() shouldBe(6.283185307179586 plusOrMinus epsilon) + Mflpt5(0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u).toDouble() shouldBe .25 + Mflpt5(0xd1u, 0x02u, 0xb7u, 0x06u, 0xfbu).toDouble() shouldBe(123.45678e22 plusOrMinus 1.0e15) + Mflpt5(0x3eu, 0xe9u, 0x34u, 0x09u, 0x1bu).toDouble() shouldBe(-123.45678e-22 plusOrMinus epsilon) } }) diff --git a/compiler/test/ZeropageTests.kt b/compiler/test/ZeropageTests.kt index e95f113a0..2a4af59cf 100644 --- a/compiler/test/ZeropageTests.kt +++ b/compiler/test/ZeropageTests.kt @@ -5,6 +5,7 @@ import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldBeIn import io.kotest.matchers.collections.shouldNotBeIn +import io.kotest.matchers.comparables.shouldBeGreaterThan import io.kotest.matchers.ints.shouldBeGreaterThan import io.kotest.matchers.shouldBe import prog8.ast.base.DataType @@ -38,13 +39,13 @@ class TestAbstractZeropage: FunSpec({ } class DummyZeropage(options: CompilationOptions) : Zeropage(options) { - override val SCRATCH_B1: Int = 0x10 - override val SCRATCH_REG: Int = 0x11 - override val SCRATCH_W1: Int= 0x20 - override val SCRATCH_W2: Int = 0x30 + override val SCRATCH_B1 = 0x10u + override val SCRATCH_REG = 0x11u + override val SCRATCH_W1 = 0x20u + override val SCRATCH_W2 = 0x30u init { - free.addAll(0..255) + free.addAll(0u..255u) removeReservedFromFreePool() } @@ -58,7 +59,7 @@ class TestAbstractZeropage: FunSpec({ OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, - listOf((0x50..0x5f)), + listOf((0x50u..0x5fu)), false, false, compTarget @@ -156,22 +157,22 @@ class TestC64Zeropage: FunSpec({ test("testReservedSpace") { val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target)) zp1.availableBytes() shouldBe 238 - 50 shouldBeIn zp1.free - 100 shouldBeIn zp1.free - 49 shouldBeIn zp1.free - 101 shouldBeIn zp1.free - 200 shouldBeIn zp1.free - 255 shouldBeIn zp1.free - 199 shouldBeIn zp1.free - val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, listOf(50 .. 100, 200..255), false, false, C64Target)) + 50u shouldBeIn zp1.free + 100u shouldBeIn zp1.free + 49u shouldBeIn zp1.free + 101u shouldBeIn zp1.free + 200u shouldBeIn zp1.free + 255u shouldBeIn zp1.free + 199u shouldBeIn zp1.free + val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, listOf(50u .. 100u, 200u..255u), false, false, C64Target)) zp2.availableBytes() shouldBe 139 - 50 shouldNotBeIn zp2.free - 100 shouldNotBeIn zp2.free - 49 shouldBeIn zp2.free - 101 shouldBeIn zp2.free - 200 shouldNotBeIn zp2.free - 255 shouldNotBeIn zp2.free - 199 shouldBeIn zp2.free + 50u shouldNotBeIn zp2.free + 100u shouldNotBeIn zp2.free + 49u shouldBeIn zp2.free + 101u shouldBeIn zp2.free + 200u shouldNotBeIn zp2.free + 255u shouldNotBeIn zp2.free + 199u shouldBeIn zp2.free } test("testBasicsafeAllocation") { @@ -187,7 +188,7 @@ class TestC64Zeropage: FunSpec({ for (i in 0 until zp.availableBytes()) { val loc = zp.allocate("", DataType.UBYTE, null, errors) - loc shouldBeGreaterThan 0 + loc shouldBeGreaterThan 0u } zp.availableBytes() shouldBe 0 zp.hasByteAvailable() shouldBe false @@ -206,7 +207,7 @@ class TestC64Zeropage: FunSpec({ zp.hasByteAvailable() shouldBe true zp.hasWordAvailable() shouldBe true val loc = zp.allocate("", DataType.UWORD, null, errors) - loc shouldBeGreaterThan 3 + loc shouldBeGreaterThan 3u loc shouldNotBeIn zp.free val num = zp.availableBytes() / 2 @@ -236,25 +237,25 @@ class TestC64Zeropage: FunSpec({ test("testEfficientAllocation") { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, C64Target)) zp.availableBytes() shouldBe 18 - zp.allocate("", DataType.WORD, null, errors) shouldBe 0x04 - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x06 - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x0a - zp.allocate("", DataType.UWORD, null, errors) shouldBe 0x9b - zp.allocate("", DataType.UWORD, null, errors) shouldBe 0x9e - zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xa5 - zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xb0 - zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xbe - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x0e - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x92 - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x96 - zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0xf9 + zp.allocate("", DataType.WORD, null, errors) shouldBe 0x04u + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x06u + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x0au + zp.allocate("", DataType.UWORD, null, errors) shouldBe 0x9bu + zp.allocate("", DataType.UWORD, null, errors) shouldBe 0x9eu + zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xa5u + zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xb0u + zp.allocate("", DataType.UWORD, null, errors) shouldBe 0xbeu + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x0eu + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x92u + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0x96u + zp.allocate("", DataType.UBYTE, null, errors) shouldBe 0xf9u zp.availableBytes() shouldBe 0 } test("testReservedLocations") { val zp = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, C64Target)) withClue("zp _B1 and _REG must be next to each other to create a word") { - zp.SCRATCH_B1 + 1 shouldBe zp.SCRATCH_REG + zp.SCRATCH_B1 + 1u shouldBe zp.SCRATCH_REG } } }) @@ -266,7 +267,7 @@ class TestCx16Zeropage: FunSpec({ test("testReservedLocations") { val zp = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), false, false, Cx16Target)) withClue("zp _B1 and _REG must be next to each other to create a word") { - zp.SCRATCH_B1 + 1 shouldBe zp.SCRATCH_REG + zp.SCRATCH_B1 + 1u shouldBe zp.SCRATCH_REG } } @@ -299,10 +300,10 @@ class TestCx16Zeropage: FunSpec({ test("testReservedSpace") { val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, Cx16Target)) zp1.availableBytes() shouldBe 216 - 0x22 shouldBeIn zp1.free - 0x80 shouldBeIn zp1.free - 0xff shouldBeIn zp1.free - 0x02 shouldNotBeIn zp1.free - 0x21 shouldNotBeIn zp1.free + 0x22u shouldBeIn zp1.free + 0x80u shouldBeIn zp1.free + 0xffu shouldBeIn zp1.free + 0x02u shouldNotBeIn zp1.free + 0x21u shouldNotBeIn zp1.free } }) diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt index d6c40dc51..3ab6705c7 100644 --- a/compiler/test/helpers/Dummies.kt +++ b/compiler/test/helpers/Dummies.kt @@ -22,7 +22,7 @@ internal val DummyFunctions = object : IBuiltinFunctions { } internal val DummyMemsizer = object : IMemSizer { - override fun memorySize(dt: DataType): Int = 0 + override fun memorySize(dt: DataType) = 0 } internal val DummyStringEncoder = object : IStringEncoding { diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index 49245a0e3..137bc015e 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -279,8 +279,8 @@ open class Module(final override var statements: MutableList, .substringAfterLast("/") .substringAfterLast("\\") - val loadAddress: Int by lazy { - val address = (statements.singleOrNull { it is Directive && it.directive == "%address" } as? Directive)?.args?.single()?.int ?: 0 + val loadAddress: UInt by lazy { + val address = (statements.singleOrNull { it is Directive && it.directive == "%address" } as? Directive)?.args?.single()?.int ?: 0u address } diff --git a/compilerAst/src/prog8/ast/Extensions.kt b/compilerAst/src/prog8/ast/Extensions.kt index 5d6bf84eb..2cc8b063d 100644 --- a/compilerAst/src/prog8/ast/Extensions.kt +++ b/compilerAst/src/prog8/ast/Extensions.kt @@ -16,4 +16,16 @@ fun Number.toHex(): String { in 0 until 0x10000 -> "$"+integer.toString(16).padStart(4,'0') else -> throw IllegalArgumentException("number too large for 16 bits $this") } -} \ No newline at end of file +} + +fun UInt.toHex(): String { + // 0..15 -> "0".."15" + // 16..255 -> "$10".."$ff" + // 256..65536 -> "$0100".."$ffff" + return when (this) { + in 0u until 16u -> this.toString() + in 0u until 0x100u -> "$"+this.toString(16).padStart(2,'0') + in 0u until 0x10000u -> "$"+this.toString(16).padStart(4,'0') + else -> throw IllegalArgumentException("number too large for 16 bits $this") + } +} diff --git a/compilerAst/src/prog8/ast/Program.kt b/compilerAst/src/prog8/ast/Program.kt index 735c49ac1..22af56151 100644 --- a/compilerAst/src/prog8/ast/Program.kt +++ b/compilerAst/src/prog8/ast/Program.kt @@ -72,10 +72,10 @@ class Program(val name: String, val toplevelModule: Module get() = modules.first { it.name!= internedStringsModuleName } - val definedLoadAddress: Int + val definedLoadAddress: UInt get() = toplevelModule.loadAddress - var actualLoadAddress: Int = 0 + var actualLoadAddress = 0u private val internedStringsUnique = mutableMapOf, List>() fun internString(string: StringLiteralValue): List { diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index 0cdb8da29..fc9660010 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -43,7 +43,7 @@ internal fun Prog8ANTLRParser.BlockContext.toAst(isInLibrary: Boolean) : Block { else -> throw FatalAstException("weird block node $it") } } - return Block(identifier().text, integerliteral()?.toAst()?.number?.toInt(), blockstatements.toMutableList(), isInLibrary, toPosition()) + return Block(identifier().text, integerliteral()?.toAst()?.number?.toUInt(), blockstatements.toMutableList(), isInLibrary, toPosition()) } private fun Prog8ANTLRParser.Statement_blockContext.toAst(): MutableList = @@ -193,7 +193,7 @@ private fun Prog8ANTLRParser.AsmsubroutineContext.toAst(): Subroutine { private fun Prog8ANTLRParser.RomsubroutineContext.toAst(): Subroutine { val subdecl = asmsub_decl().toAst() - val address = integerliteral().toAst().number.toInt() + val address = integerliteral().toAst().number.toUInt() return Subroutine(subdecl.name, subdecl.parameters.toMutableList(), subdecl.returntypes, subdecl.asmParameterRegisters, subdecl.asmReturnvaluesRegisters, subdecl.asmClobbers, address, true, inline = false, statements = mutableListOf(), position = toPosition() @@ -293,7 +293,7 @@ private fun Prog8ANTLRParser.ReturnstmtContext.toAst() : Return { } private fun Prog8ANTLRParser.UnconditionaljumpContext.toAst(): Jump { - val address = integerliteral()?.toAst()?.number?.toInt() + val address = integerliteral()?.toAst()?.number?.toUInt() val identifier = scoped_identifier()?.toAst() return Jump(address, identifier, null, toPosition()) } @@ -354,7 +354,7 @@ private fun Prog8ANTLRParser.DirectiveargContext.toAst() : DirectiveArg { if(str?.ALT_STRING_ENCODING() != null) throw SyntaxError("can't use alternate string s for directive arguments", toPosition()) - return DirectiveArg(stringliteral()?.text, identifier()?.text, integerliteral()?.toAst()?.number?.toInt(), toPosition()) + return DirectiveArg(stringliteral()?.text, identifier()?.text, integerliteral()?.toAst()?.number?.toUInt(), toPosition()) } private fun Prog8ANTLRParser.IntegerliteralContext.toAst(): NumericLiteral { diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 5d8024995..1ea613722 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -456,6 +456,14 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed else -> throw FatalAstException("integer overflow: $dvalue") } } + + fun optimalInteger(value: UInt, position: Position): NumericLiteralValue { + return when (value) { + in 0u..255u -> NumericLiteralValue(DataType.UBYTE, value.toDouble(), position) + in 0u..65535u -> NumericLiteralValue(DataType.UWORD, value.toDouble(), position) + else -> throw FatalAstException("unsigned integer overflow: $value") + } + } } val asBooleanValue: Boolean = number != 0.0 diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 02f5d826b..b7d8d730f 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -70,7 +70,7 @@ class BuiltinFunctionStatementPlaceholder(val name: String, override val positio data class RegisterOrStatusflag(val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?) class Block(override val name: String, - val address: Int?, + val address: UInt?, override var statements: MutableList, val isInLibrary: Boolean, override val position: Position) : Statement(), INameScope { @@ -114,7 +114,7 @@ data class Directive(val directive: String, val args: List, overri override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) } -data class DirectiveArg(val str: String?, val name: String?, val int: Int?, override val position: Position) : Node { +data class DirectiveArg(val str: String?, val name: String?, val int: UInt?, override val position: Position) : Node { override lateinit var parent: Node override fun linkParents(parent: Node) { @@ -520,7 +520,7 @@ class PostIncrDecr(var target: AssignTarget, val operator: String, override val } } -class Jump(val address: Int?, +class Jump(val address: UInt?, val identifier: IdentifierReference?, val generatedLabel: String?, // used in code generation scenarios override val position: Position) : Statement() { @@ -631,7 +631,7 @@ class AsmGenInfo { var usedFloatEvalResultVar1 = false var usedFloatEvalResultVar2 = false - val extraVars = mutableListOf>() + val extraVars = mutableListOf>() } // the subroutine class covers both the normal user-defined subroutines, @@ -643,7 +643,7 @@ class Subroutine(override val name: String, val asmParameterRegisters: List, val asmReturnvaluesRegisters: List, val asmClobbers: Set, - val asmAddress: Int?, + val asmAddress: UInt?, val isAsmSubroutine: Boolean, val inline: Boolean, override var statements: MutableList, diff --git a/compilerAst/test/helpers/Dummies.kt b/compilerAst/test/helpers/Dummies.kt index 92ab96752..d727601bf 100644 --- a/compilerAst/test/helpers/Dummies.kt +++ b/compilerAst/test/helpers/Dummies.kt @@ -22,7 +22,7 @@ internal val DummyFunctions = object : IBuiltinFunctions { } internal val DummyMemsizer = object : IMemSizer { - override fun memorySize(dt: DataType): Int = 0 + override fun memorySize(dt: DataType) = 0 } internal val DummyStringEncoder = object : IStringEncoding { diff --git a/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt b/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt index f8926ed25..49b2bca24 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt @@ -16,12 +16,12 @@ fun AssignTarget.isIOAddress(machine: IMachineDefinition): Boolean { memAddr != null -> { val addr = memAddr.addressExpression.constValue(definingModule.program) if(addr!=null) - return machine.isIOAddress(addr.number.toInt()) + return machine.isIOAddress(addr.number.toUInt()) return when (memAddr.addressExpression) { is IdentifierReference -> { val decl = (memAddr.addressExpression as IdentifierReference).targetVarDecl(definingModule.program) val result = if ((decl?.type == VarDeclType.MEMORY || decl?.type == VarDeclType.CONST) && decl.value is NumericLiteralValue) - machine.isIOAddress((decl.value as NumericLiteralValue).number.toInt()) + machine.isIOAddress((decl.value as NumericLiteralValue).number.toUInt()) else false result @@ -34,7 +34,7 @@ fun AssignTarget.isIOAddress(machine: IMachineDefinition): Boolean { return if (targetStmt?.type == VarDeclType.MEMORY) { val addr = targetStmt.value as? NumericLiteralValue if (addr != null) - machine.isIOAddress(addr.number.toInt()) + machine.isIOAddress(addr.number.toUInt()) else false } else false @@ -42,7 +42,7 @@ fun AssignTarget.isIOAddress(machine: IMachineDefinition): Boolean { ident != null -> { val decl = ident.targetVarDecl(definingModule.program) ?: throw FatalAstException("invalid identifier ${ident.nameInSource}") return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteralValue) - machine.isIOAddress((decl.value as NumericLiteralValue).number.toInt()) + machine.isIOAddress((decl.value as NumericLiteralValue).number.toUInt()) else false } diff --git a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt index 849d44beb..13e92d1bb 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/BuiltinFunctions.kt @@ -513,6 +513,8 @@ private fun builtinSgn(args: List, position: Position, program: Prog return NumericLiteralValue(DataType.BYTE, constval.number.sign, position) } +private fun numericLiteral(value: UInt, position: Position): NumericLiteralValue = numericLiteral(value.toInt(), position) + private fun numericLiteral(value: Number, position: Position): NumericLiteralValue { val floatNum=value.toDouble() val tweakedValue: Number = diff --git a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt index a671603a3..67e75dc61 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/CompilationOptions.kt @@ -21,7 +21,7 @@ enum class ZeropageType { class CompilationOptions(val output: OutputType, val launcher: LauncherType, val zeropage: ZeropageType, - val zpReserved: List, + val zpReserved: List, val floats: Boolean, val noSysInit: Boolean, val compTarget: ICompilationTarget, diff --git a/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt b/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt index e8ad74ea4..22e61ec95 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/IMachineDefinition.kt @@ -18,10 +18,10 @@ interface IMachineDefinition { val FLOAT_MAX_POSITIVE: Double val FLOAT_MEM_SIZE: Int val POINTER_MEM_SIZE: Int - val ESTACK_LO: Int - val ESTACK_HI: Int - val BASIC_LOAD_ADDRESS : Int - val RAW_LOAD_ADDRESS : Int + val ESTACK_LO: UInt + val ESTACK_HI: UInt + val BASIC_LOAD_ADDRESS : UInt + val RAW_LOAD_ADDRESS : UInt val opcodeNames: Set var zeropage: Zeropage @@ -32,5 +32,5 @@ interface IMachineDefinition { fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) - fun isIOAddress(address: Int): Boolean + fun isIOAddress(address: UInt): Boolean } diff --git a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt index 961cad586..2213d1752 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt @@ -8,14 +8,14 @@ class ZeropageDepletedError(message: String) : Exception(message) abstract class Zeropage(protected val options: CompilationOptions) { - abstract val SCRATCH_B1 : Int // temp storage for a single byte - abstract val SCRATCH_REG : Int // temp storage for a register - abstract val SCRATCH_W1 : Int // temp storage 1 for a word $fb+$fc - abstract val SCRATCH_W2 : Int // temp storage 2 for a word $fb+$fc + abstract val SCRATCH_B1 : UInt // temp storage for a single byte + abstract val SCRATCH_REG : UInt // temp storage for a register + abstract val SCRATCH_W1 : UInt // temp storage 1 for a word $fb+$fc + abstract val SCRATCH_W2 : UInt // temp storage 2 for a word $fb+$fc - private val allocations = mutableMapOf>() - val free = mutableListOf() // subclasses must set this to the appropriate free locations. + private val allocations = mutableMapOf>() + val free = mutableListOf() // subclasses must set this to the appropriate free locations. val allowedDatatypes = NumericDatatypes @@ -23,7 +23,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { for (reserved in options.zpReserved) reserve(reserved) - free.removeAll(setOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1, SCRATCH_W2, SCRATCH_W2 + 1)) + free.removeAll(setOf(SCRATCH_B1, SCRATCH_REG, SCRATCH_W1, SCRATCH_W1 + 1u, SCRATCH_W2, SCRATCH_W2 + 1u)) } fun availableBytes() = if(options.zeropage== ZeropageType.DONTUSE) 0 else free.size @@ -32,9 +32,9 @@ abstract class Zeropage(protected val options: CompilationOptions) { if(options.zeropage== ZeropageType.DONTUSE) return 0 - val words = free.windowed(2).filter { it[0] == it[1]-1 } + val words = free.windowed(2).filter { it[0] == it[1]-1u } var nonOverlappingWordsCount = 0 - var prevMsbLoc = -1 + var prevMsbLoc = UInt.MAX_VALUE for(w in words) { if(w[0]!=prevMsbLoc) { nonOverlappingWordsCount++ @@ -47,16 +47,16 @@ abstract class Zeropage(protected val options: CompilationOptions) { if(options.zeropage== ZeropageType.DONTUSE) return false - return free.windowed(2).any { it[0] == it[1] - 1 } + return free.windowed(2).any { it[0] == it[1] - 1u } } - fun allocate(scopedname: String, datatype: DataType, position: Position?, errors: IErrorReporter): Int { + fun allocate(scopedname: String, datatype: DataType, position: Position?, errors: IErrorReporter): UInt { require(scopedname.isEmpty() || !allocations.values.any { it.first==scopedname } ) {"scopedname can't be allocated twice"} if(options.zeropage== ZeropageType.DONTUSE) throw InternalCompilerException("zero page usage has been disabled") - val size = + val size: Int = when (datatype) { in ByteDatatypes -> 1 in WordDatatypes -> 2 @@ -66,7 +66,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { errors.warn("allocated a large value (float) in zeropage", position) else errors.warn("$scopedname: allocated a large value (float) in zeropage", position ?: Position.DUMMY) - 5 + options.compTarget.machine.FLOAT_MEM_SIZE } else throw InternalCompilerException("floating point option not enabled") } else -> throw InternalCompilerException("cannot put datatype $datatype in zeropage") @@ -74,13 +74,13 @@ abstract class Zeropage(protected val options: CompilationOptions) { if(free.size > 0) { if(size==1) { - for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1) { + for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) { if(loneByte(candidate)) return makeAllocation(candidate, 1, datatype, scopedname) } return makeAllocation(free[0], 1, datatype, scopedname) } - for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1) { + for(candidate in free.minOrNull()!! .. free.maxOrNull()!!+1u) { if (sequentialFree(candidate, size)) return makeAllocation(candidate, size, datatype, scopedname) } @@ -89,14 +89,18 @@ abstract class Zeropage(protected val options: CompilationOptions) { throw ZeropageDepletedError("ERROR: no free space in ZP to allocate $size sequential bytes") } - protected fun reserve(range: IntRange) = free.removeAll(range) + protected fun reserve(range: UIntRange) = free.removeAll(range) - private fun makeAllocation(address: Int, size: Int, datatype: DataType, name: String?): Int { - free.removeAll(address until address+size) + private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: String?): UInt { + require(size>=0) + free.removeAll(address until address+size.toUInt()) allocations[address] = (name ?: "") to datatype return address } - private fun loneByte(address: Int) = address in free && address-1 !in free && address+1 !in free - private fun sequentialFree(address: Int, size: Int) = free.containsAll((address until address+size).toList()) + private fun loneByte(address: UInt) = address in free && address-1u !in free && address+1u !in free + private fun sequentialFree(address: UInt, size: Int): Boolean { + require(size>0) + return free.containsAll((address until address+size.toUInt()).toList()) + } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 2ebd173b1..35016d78d 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -16,7 +16,6 @@ Blocked by an official Commander-x16 v39 release Future ^^^^^^ -- use UByte instead of Short - rethink the whole "isAugmentable" business. Because the way this is determined, should always also be exactly mirrorred in the AugmentableAssignmentAsmGen or you'll get a crash at code gen time. - simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation - remove special code generation for while and util expression