easier datatype notation by just using the type objects directly

This commit is contained in:
Irmen de Jong
2025-03-18 23:33:04 +01:00
parent 79cda544c8
commit 3770a4fe0c
48 changed files with 416 additions and 409 deletions
+12 -1
View File
@@ -1,6 +1,6 @@
package prog8.code.core
import java.util.Objects
import java.util.*
enum class BaseDataType {
UBYTE, // pass by value 8 bits unsigned
@@ -80,6 +80,17 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
override fun hashCode(): Int = Objects.hash(base, sub)
companion object {
val UBYTE = DataType(BaseDataType.UBYTE, null)
val BYTE = DataType(BaseDataType.BYTE, null)
val UWORD = DataType(BaseDataType.UWORD, null)
val WORD = DataType(BaseDataType.WORD, null)
val LONG = DataType(BaseDataType.LONG, null)
val FLOAT = DataType(BaseDataType.FLOAT, null)
val BOOL = DataType(BaseDataType.BOOL, null)
val STR = DataType(BaseDataType.STR, BaseDataType.UBYTE)
val UNDEFINED = DataType(BaseDataType.UNDEFINED, null)
private val simpletypes = mapOf(
BaseDataType.UBYTE to DataType(BaseDataType.UBYTE, null),
BaseDataType.BYTE to DataType(BaseDataType.BYTE, null),
+1 -1
View File
@@ -5,7 +5,7 @@ interface IMemSizer {
fun memorySize(dt: BaseDataType): Int {
if(dt.isPassByRef)
return memorySize(DataType.forDt(BaseDataType.UWORD), null) // a pointer size
return memorySize(DataType.UWORD, null) // a pointer size
try {
return memorySize(DataType.forDt(dt), null)
} catch (x: NoSuchElementException) {
@@ -82,7 +82,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
}
datatype.isFloat -> {
if (options.floats) {
val memsize = options.compTarget.memorySize(DataType.forDt(BaseDataType.FLOAT), null)
val memsize = options.compTarget.memorySize(DataType.FLOAT, null)
if(position!=null)
errors.warn("allocating a large value in zeropage; float $memsize bytes", position)
else
@@ -154,7 +154,7 @@ class GoldenRam(options: CompilationOptions, val region: UIntRange): MemoryAlloc
datatype.isArray -> options.compTarget.memorySize(datatype, numElements!!)
datatype.isFloat -> {
if (options.floats) {
options.compTarget.memorySize(DataType.forDt(BaseDataType.FLOAT), null)
options.compTarget.memorySize(DataType.FLOAT, null)
} else return Err(MemAllocationError("floating point option not enabled"))
}
else -> throw MemAllocationError("weird dt")
@@ -85,12 +85,12 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
// The base addres is $04. Unfortunately it cannot be the same as on the Commander X16 ($02).
for(reg in 0..15) {
allocatedVariables["cx16.r${reg}"] = VarAllocation((4+reg*2).toUInt(), DataType.forDt(BaseDataType.UWORD), 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((4+reg*2).toUInt(), DataType.forDt(BaseDataType.WORD), 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((4+reg*2).toUInt(), DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((5+reg*2).toUInt(), DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((4+reg*2).toUInt(), DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((5+reg*2).toUInt(), DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sH .. cx16.r15sH
allocatedVariables["cx16.r${reg}"] = VarAllocation((4+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((4+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((4+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((5+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((4+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((5+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
free.remove((4+reg*2).toUInt())
free.remove((5+reg*2).toUInt())
}
@@ -57,12 +57,12 @@ class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
// However, to be able for the compiler to "see" them as zeropage variables, we have to register them here as well.
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
for(reg in 0..15) {
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.forDt(BaseDataType.UWORD), 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((2+reg*2).toUInt(), DataType.forDt(BaseDataType.WORD), 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((2+reg*2).toUInt(), DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((3+reg*2).toUInt(), DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((2+reg*2).toUInt(), DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((3+reg*2).toUInt(), DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sH .. cx16.r15sH
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((2+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((2+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((3+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
}
}
}
@@ -1,6 +1,9 @@
package prog8.code.target.zp
import prog8.code.core.*
import prog8.code.core.CompilationOptions
import prog8.code.core.DataType
import prog8.code.core.Zeropage
import prog8.code.core.ZeropageType
class ConfigurableZeropage(
override val SCRATCH_B1: UInt, // temp storage for a single byte
@@ -46,12 +49,12 @@ class ConfigurableZeropage(
for(reg in 0..15) {
val address = virtualRegistersStart + (2*reg).toUInt()
if(address<=0xffu) {
allocatedVariables["cx16.r${reg}"] = VarAllocation(address, DataType.forDt(BaseDataType.UWORD), 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation(address, DataType.forDt(BaseDataType.WORD), 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation(address, DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation(address+1u, DataType.forDt(BaseDataType.UBYTE), 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation(address, DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation(address+1u, DataType.forDt(BaseDataType.BYTE), 1) // cx16.r0sH .. cx16.r15sH
allocatedVariables["cx16.r${reg}"] = VarAllocation(address, DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation(address, DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation(address, DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation(address+1u, DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation(address, DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation(address+1u, DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
}
}
}
@@ -131,7 +131,7 @@ class AsmGen6502(val prefixSymbols: Boolean, private val lastGeneratedLabelSeque
functionCallsToPrefix.reversed().forEach { (parent, index) ->
val node = parent.children[index]
if(node is PtFunctionCall) {
val prefixedName = PtIdentifier(node.name, DataType.forDt(BaseDataType.UNDEFINED), Position.DUMMY).prefix(parent, st)
val prefixedName = PtIdentifier(node.name, DataType.UNDEFINED, Position.DUMMY).prefix(parent, st)
val prefixedNode = node.withNewName(prefixedName.name)
parent.children[index] = prefixedNode
} else {
@@ -1081,7 +1081,7 @@ $repeatLabel""")
else {
if(evaluateAddressExpression) {
// we can do the address evaluation right now and just use a temporary pointer variable
assignExpressionToVariable(jump.target, "P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(jump.target, "P8ZP_SCRATCH_W1", DataType.UWORD)
return JumpTarget("P8ZP_SCRATCH_W1", true, false)
} else {
return JumpTarget("PROG8_JUMP_TARGET_IS_UNEVALUATED_ADDRESS_EXPRESSION", true, true)
@@ -1294,13 +1294,13 @@ $repeatLabel""")
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
if(saveA) out(" pha")
if(ptrAndIndex.second.isSimple()) {
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
if(saveA) out(" pla")
out(" sta (P8ZP_SCRATCH_W2),y")
} else {
pushCpuStack(BaseDataType.UBYTE, ptrAndIndex.second)
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
restoreRegisterStack(CpuRegister.Y, true)
if(saveA) out(" pla")
out(" sta (P8ZP_SCRATCH_W2),y")
@@ -1337,12 +1337,12 @@ $repeatLabel""")
} else {
// copy the pointer var to zp first
if(ptrAndIndex.second.isSimple()) {
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
out(" lda (P8ZP_SCRATCH_W2),y")
} else {
pushCpuStack(BaseDataType.UBYTE, ptrAndIndex.second)
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
restoreRegisterStack(CpuRegister.Y, false)
out(" lda (P8ZP_SCRATCH_W2),y")
}
@@ -1382,7 +1382,7 @@ $repeatLabel""")
} else {
// copy the pointer var to zp first
out(" pha")
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
out(" ldy #${256-constOffset} ; negative offset $constOffset")
out(" dec P8ZP_SCRATCH_W2+1 | pla | sta (P8ZP_SCRATCH_W2),y") // temporarily make MSB 1 less to be able to use the negative Y offset
return true
@@ -1412,7 +1412,7 @@ $repeatLabel""")
return true
} else {
// copy the pointer var to zp first
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD)
out(" ldy #${256-constOffset} ; negative offset $constOffset")
out(" dec P8ZP_SCRATCH_W2+1 | lda (P8ZP_SCRATCH_W2),y") // temporarily make MSB 1 less to be able to use the negative Y offset
return true
@@ -1434,22 +1434,22 @@ $repeatLabel""")
internal fun assignByteOperandsToAAndVar(left: PtExpression, right: PtExpression, rightVarName: String) {
if(left.isSimple()) {
assignExpressionToVariable(right, rightVarName, DataType.forDt(BaseDataType.UBYTE))
assignExpressionToVariable(right, rightVarName, DataType.UBYTE)
assignExpressionToRegister(left, RegisterOrPair.A)
} else {
pushCpuStack(BaseDataType.UBYTE, left)
assignExpressionToVariable(right, rightVarName, DataType.forDt(BaseDataType.UBYTE))
assignExpressionToVariable(right, rightVarName, DataType.UBYTE)
out(" pla")
}
}
internal fun assignWordOperandsToAYAndVar(left: PtExpression, right: PtExpression, rightVarname: String) {
if(left.isSimple()) {
assignExpressionToVariable(right, rightVarname, DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(right, rightVarname, DataType.UWORD)
assignExpressionToRegister(left, RegisterOrPair.AY)
} else {
pushCpuStack(BaseDataType.UWORD, left)
assignExpressionToVariable(right, rightVarname, DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(right, rightVarname, DataType.UWORD)
restoreRegisterStack(CpuRegister.Y, false)
restoreRegisterStack(CpuRegister.A, false)
}
@@ -1458,7 +1458,7 @@ $repeatLabel""")
internal fun translateDirectMemReadExpressionToRegA(expr: PtMemoryByte) {
fun assignViaExprEval() {
assignExpressionToVariable(expr.address, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(expr.address, "P8ZP_SCRATCH_W2", DataType.UWORD)
if (isTargetCpu(CpuType.CPU65C02)) {
out(" lda (P8ZP_SCRATCH_W2)")
} else {
@@ -1654,7 +1654,7 @@ $repeatLabel""")
is PtIdentifier -> equalf(asmVariableName(left), asmVariableName(right))
is PtNumber -> equalf(asmVariableName(left), allocator.getFloatAsmConst(right.number))
else -> {
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.forDt(BaseDataType.FLOAT))
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT)
equalf(asmVariableName(left), subroutineFloatEvalResultVar1)
subroutineExtra(left.definingISub()!!).usedFloatEvalResultVar1 = true
}
@@ -1664,7 +1664,7 @@ $repeatLabel""")
is PtIdentifier -> equalf(left, asmVariableName(right))
is PtNumber -> equalf(left, allocator.getFloatAsmConst(right.number))
else -> {
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.forDt(BaseDataType.FLOAT))
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT)
equalf(left, subroutineFloatEvalResultVar1)
subroutineExtra(left.definingISub()!!).usedFloatEvalResultVar1 = true
}
@@ -1699,7 +1699,7 @@ $repeatLabel""")
is PtIdentifier -> lessf(asmVariableName(left), asmVariableName(right))
is PtNumber -> lessf(asmVariableName(left), allocator.getFloatAsmConst(right.number))
else -> {
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.forDt(BaseDataType.FLOAT))
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT)
lessf(asmVariableName(left), subroutineFloatEvalResultVar1)
subroutineExtra(left.definingISub()!!).usedFloatEvalResultVar1 = true
}
@@ -1709,7 +1709,7 @@ $repeatLabel""")
is PtIdentifier -> lessf(left, asmVariableName(right))
is PtNumber -> lessf(left, allocator.getFloatAsmConst(right.number))
else -> {
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.forDt(BaseDataType.FLOAT))
assignExpressionToVariable(right, subroutineFloatEvalResultVar1, DataType.FLOAT)
lessf(left, subroutineFloatEvalResultVar1)
subroutineExtra(left.definingISub()!!).usedFloatEvalResultVar1 = true
}
@@ -55,7 +55,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
memread.parent = fcall
asmgen.assignExpressionToRegister(memread, RegisterOrPair.A, false)
asmgen.out(" pha")
val memtarget = AsmAssignTarget(TargetStorageKind.MEMORY, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingISub(), fcall.position, memory=memread)
val memtarget = AsmAssignTarget(TargetStorageKind.MEMORY, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.position, memory=memread)
asmgen.assignExpressionTo(fcall.args[1], memtarget)
asmgen.out(" pla")
}
@@ -107,8 +107,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.out(" jsr prog8_math.divmod_ub_asm")
val var2name = asmgen.asmVariableName(fcall.args[2] as PtIdentifier)
val var3name = asmgen.asmVariableName(fcall.args[3] as PtIdentifier)
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingISub(), fcall.args[2].position, var2name)
val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingISub(), fcall.args[3].position, var3name)
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name)
val remainderTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[3].position, var3name)
assignAsmGen.assignRegisterByte(remainderTarget, CpuRegister.A, false, false)
assignAsmGen.assignRegisterByte(divisionTarget, CpuRegister.Y, false, false)
}
@@ -120,7 +120,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
// output: P8ZP_SCRATCH_W2 in ZP: 16-bit remainder, A/Y: 16 bit division result
asmgen.out(" jsr prog8_math.divmod_uw_asm")
val var2name = asmgen.asmVariableName(fcall.args[2] as PtIdentifier)
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingISub(), fcall.args[2].position, var2name)
val divisionTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingISub(), fcall.args[2].position, var2name)
val remainderVar = asmgen.asmVariableName(fcall.args[3] as PtIdentifier)
assignAsmGen.assignRegisterpairWord(divisionTarget, RegisterOrPair.AY)
asmgen.out("""
@@ -196,7 +196,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
return
}
asmgen.assignExpressionToVariable(fcall.args[0], asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.forDt(BaseDataType.UWORD)) // jump address
asmgen.assignExpressionToVariable(fcall.args[0], asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD) // jump address
asmgen.out("""
; push a return address so the jmp becomes indirect jsr
lda #>((+)-1)
@@ -376,11 +376,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
throw AssemblyError("should not discard result of memory allocation at $fcall")
val name = (fcall.args[0] as PtString).value
require(name.all { it.isLetterOrDigit() || it=='_' }) {"memory name should be a valid symbol name ${fcall.position}"}
val slabname = PtIdentifier("prog8_slabs.prog8_memoryslab_$name", DataType.forDt(BaseDataType.UWORD), fcall.position)
val slabname = PtIdentifier("prog8_slabs.prog8_memoryslab_$name", DataType.UWORD, fcall.position)
val addressOf = PtAddressOf(fcall.position)
addressOf.add(slabname)
addressOf.parent = fcall
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.forDt(BaseDataType.UWORD), expression = addressOf)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UWORD, expression = addressOf)
val target = AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, fcall.position, null, asmgen)
val assign = AsmAssignment(src, listOf(target), program.memsizer, fcall.position)
asmgen.translateNormalAssignment(assign, fcall.definingISub())
@@ -646,7 +646,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when(fcall.args[0]) {
is PtIdentifier -> {
val varname = asmgen.asmVariableName(fcall.args[0] as PtIdentifier) + if(msb) "+1" else ""
target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingSub(), fcall.position, variableAsmName = varname)
target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, fcall.definingSub(), fcall.position, variableAsmName = varname)
}
is PtArrayIndexer -> {
val indexer = fcall.args[0] as PtArrayIndexer
@@ -688,7 +688,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
multipliedIndex.parent=indexer
}
}
target = AsmAssignTarget(TargetStorageKind.ARRAY, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingSub(), fcall.position, array = indexer)
target = AsmAssignTarget(TargetStorageKind.ARRAY, asmgen, DataType.UBYTE, fcall.definingSub(), fcall.position, array = indexer)
}
else -> throw AssemblyError("setlsb/setmsb on weird target ${fcall.args[0]}")
}
@@ -760,7 +760,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}
else -> {
val tempvar = asmgen.getTempVarName(BaseDataType.FLOAT)
asmgen.assignExpressionToVariable(fcall.args[1], tempvar, DataType.forDt(BaseDataType.FLOAT))
asmgen.assignExpressionToVariable(fcall.args[1], tempvar, DataType.FLOAT)
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
asmgen.out("""
pha
@@ -835,7 +835,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.out(" jsr floats.MOVFM")
if(resultRegister!=null) {
assignAsmGen.assignFAC1float(
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.forDt(BaseDataType.FLOAT), fcall.definingISub(), fcall.position, null, null, null, resultRegister, null))
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.FLOAT, fcall.definingISub(), fcall.position, null, null, null, resultRegister, null))
}
}
@@ -1309,11 +1309,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
throw AssemblyError("cannot use float arguments outside of a subroutine scope")
asmgen.subroutineExtra(scope).usedFloatEvalResultVar2 = true
val variable = PtIdentifier(subroutineFloatEvalResultVar2, DataType.forDt(BaseDataType.FLOAT), value.position)
val variable = PtIdentifier(subroutineFloatEvalResultVar2, DataType.FLOAT, value.position)
val addr = PtAddressOf(value.position)
addr.add(variable)
addr.parent = call
asmgen.assignExpressionToVariable(value, asmgen.asmVariableName(variable), DataType.forDt(BaseDataType.FLOAT))
asmgen.assignExpressionToVariable(value, asmgen.asmVariableName(variable), DataType.FLOAT)
AsmAssignSource.fromAstSource(addr, program, asmgen)
}
}
@@ -432,7 +432,7 @@ $loopLabel sty $indexVar
}
if(numElements>=16) {
// allocate index var on ZP if possible
val result = zeropage.allocate(indexVar, DataType.forDt(BaseDataType.UBYTE), null, stmt.position, asmgen.errors)
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { (address, _, _)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }
@@ -470,7 +470,7 @@ $loopLabel sty $indexVar
}
if(numElements>=16) {
// allocate index var on ZP if possible
val result = zeropage.allocate(indexVar, DataType.forDt(BaseDataType.UBYTE), null, stmt.position, asmgen.errors)
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { (address,_,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }
@@ -511,7 +511,7 @@ $loopLabel sty $indexVar
}
if(length>=16) {
// allocate index var on ZP if possible
val result = zeropage.allocate(indexVar, DataType.forDt(BaseDataType.UBYTE), null, stmt.position, asmgen.errors)
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { (address,_,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }
@@ -325,7 +325,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
register!!
if(requiredDt.largerSizeThan(value.type)) {
// we need to sign extend the source, do this via temporary word variable
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", DataType.UBYTE)
asmgen.signExtendVariableLsb("P8ZP_SCRATCH_W1", value.type.base)
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, Position.DUMMY)
} else {
@@ -243,7 +243,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
}
}
in LogicalOperators -> {
val regAtarget = AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.forDt(BaseDataType.BOOL), stmt.definingISub(), condition.position, register=RegisterOrPair.A)
val regAtarget = AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.BOOL, stmt.definingISub(), condition.position, register=RegisterOrPair.A)
if (assignmentAsmGen.optimizedLogicalExpr(condition, regAtarget)) {
if (jumpAfterIf != null)
translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope)
@@ -82,7 +82,7 @@ internal class IfExpressionAsmGen(private val asmgen: AsmGen6502Internal, privat
asmgen.out(" beq $falseLabel")
}
in LogicalOperators -> {
val regAtarget = AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.forDt(BaseDataType.BOOL), condition.definingISub(), condition.position, register=RegisterOrPair.A)
val regAtarget = AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.BOOL, condition.definingISub(), condition.position, register=RegisterOrPair.A)
if (assignmentAsmGen.optimizedLogicalExpr(condition, regAtarget)) {
asmgen.out(" beq $falseLabel")
} else {
@@ -2,7 +2,10 @@ package prog8.codegen.cpu6502.assignment
import prog8.code.ast.PtBinaryExpression
import prog8.code.ast.PtExpression
import prog8.code.core.*
import prog8.code.core.AssemblyError
import prog8.code.core.ComparisonOperators
import prog8.code.core.DataType
import prog8.code.core.RegisterOrPair
import prog8.code.target.C64Target
import prog8.code.target.Cx16Target
import prog8.codegen.cpu6502.AsmGen6502Internal
@@ -52,7 +55,7 @@ internal class AnyExprAsmGen(
"+" -> {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
asmgen.out(" pha")
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla | clc | adc P8ZP_SCRATCH_B1")
asmgen.assignRegister(RegisterOrPair.A, assign.target)
return true
@@ -60,7 +63,7 @@ internal class AnyExprAsmGen(
"-" -> {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
asmgen.out(" pha")
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla | sec | sbc P8ZP_SCRATCH_B1")
asmgen.assignRegister(RegisterOrPair.A, assign.target)
return true
@@ -75,7 +78,7 @@ internal class AnyExprAsmGen(
"&" -> {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
asmgen.out(" pha")
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla | and P8ZP_SCRATCH_B1")
asmgen.assignRegister(RegisterOrPair.A, assign.target)
return true
@@ -83,7 +86,7 @@ internal class AnyExprAsmGen(
"|" -> {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
asmgen.out(" pha")
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla | ora P8ZP_SCRATCH_B1")
asmgen.assignRegister(RegisterOrPair.A, assign.target)
return true
@@ -91,7 +94,7 @@ internal class AnyExprAsmGen(
"^", "xor" -> {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
asmgen.out(" pha")
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla | eor P8ZP_SCRATCH_B1")
asmgen.assignRegister(RegisterOrPair.A, assign.target)
return true
@@ -197,7 +200,7 @@ internal class AnyExprAsmGen(
private fun setupFloatComparisonFAC1vsVarAY(expr: PtBinaryExpression) {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.FAC1, true)
if(!expr.right.isSimple()) asmgen.pushFAC1()
asmgen.assignExpressionToVariable(expr.right, "floats.floats_temp_var", DataType.forDt(BaseDataType.FLOAT))
asmgen.assignExpressionToVariable(expr.right, "floats.floats_temp_var", DataType.FLOAT)
if(!expr.right.isSimple()) asmgen.popFAC1()
asmgen.out(" lda #<floats.floats_temp_var | ldy #>floats.floats_temp_var")
}
@@ -52,7 +52,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
fun fromAstAssignmentMulti(targets: List<PtAssignTarget>, definingSub: IPtSubroutine?, asmgen: AsmGen6502Internal): List<AsmAssignTarget> {
return targets.map {
if(it.void)
AsmAssignTarget(TargetStorageKind.VOID, asmgen, DataType.forDt(BaseDataType.UNDEFINED), null, it.position)
AsmAssignTarget(TargetStorageKind.VOID, asmgen, DataType.UNDEFINED, null, it.position)
else
fromAstAssignment(it, definingSub, asmgen)
}
@@ -87,18 +87,18 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
RegisterOrPair.A,
RegisterOrPair.X,
RegisterOrPair.Y -> {
val dt = DataType.forDt(if(signed) BaseDataType.BYTE else BaseDataType.UBYTE)
val dt = if(signed) DataType.BYTE else DataType.UBYTE
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, dt, scope, pos, register = registers)
}
RegisterOrPair.AX,
RegisterOrPair.AY,
RegisterOrPair.XY -> {
val dt = DataType.forDt(if(signed) BaseDataType.WORD else BaseDataType.UWORD)
val dt = if(signed) DataType.WORD else DataType.UWORD
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, dt, scope, pos, register = registers)
}
RegisterOrPair.FAC1,
RegisterOrPair.FAC2 -> {
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.forDt(BaseDataType.FLOAT), scope, pos, register = registers)
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.FLOAT, scope, pos, register = registers)
}
RegisterOrPair.R0,
RegisterOrPair.R1,
@@ -116,7 +116,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
RegisterOrPair.R13,
RegisterOrPair.R14,
RegisterOrPair.R15 -> {
val dt = DataType.forDt(if(signed) BaseDataType.WORD else BaseDataType.UWORD)
val dt = if(signed) DataType.WORD else DataType.UWORD
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, dt, scope, pos, register = registers)
}
}
@@ -170,7 +170,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv)
val bv = value as? PtBool
if(bv!=null)
return AsmAssignSource(SourceStorageKind.LITERALBOOLEAN, program, asmgen, DataType.forDt(BaseDataType.BOOL), boolean = bv)
return AsmAssignSource(SourceStorageKind.LITERALBOOLEAN, program, asmgen, DataType.BOOL, boolean = bv)
return when(value) {
// checked above: is PtNumber -> throw AssemblyError("should have been constant value")
@@ -191,7 +191,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
}
}
is PtMemoryByte -> {
AsmAssignSource(SourceStorageKind.MEMORY, program, asmgen, DataType.forDt(BaseDataType.UBYTE), memory = value)
AsmAssignSource(SourceStorageKind.MEMORY, program, asmgen, DataType.UBYTE, memory = value)
}
is PtArrayIndexer -> {
AsmAssignSource(SourceStorageKind.ARRAY, program, asmgen, value.type, array = value)
@@ -204,7 +204,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
val sub = symbol.astNode as IPtSubroutine
val returnType =
if(sub is PtSub && sub.returns.size>1)
DataType.forDt(BaseDataType.UNDEFINED) // TODO list of types instead?
DataType.UNDEFINED // TODO list of types instead?
else
sub.returnsWhatWhere().firstOrNull { rr -> rr.first.registerOrPair != null || rr.first.statusflag!=null }?.second
?: throw AssemblyError("can't translate zero return values in assignment")
@@ -1,10 +1,6 @@
package prog8.codegen.cpu6502.assignment
import prog8.code.StMemVar
import prog8.code.StExtSub
import prog8.code.StExtSubParameter
import prog8.code.StStaticVariable
import prog8.code.StSub
import prog8.code.*
import prog8.code.ast.*
import prog8.code.core.*
import prog8.codegen.cpu6502.AsmGen6502Internal
@@ -382,7 +378,7 @@ internal class AssignmentAsmGen(
}
// fallback assignmen through temporary pointer var
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
assignRegisterByte(target, CpuRegister.A, false, true)
}
@@ -433,7 +429,7 @@ internal class AssignmentAsmGen(
// }
}
if(saveA) asmgen.out(" pha")
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.UWORD)
if(saveA) asmgen.out(" pla")
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
}
@@ -985,7 +981,7 @@ internal class AssignmentAsmGen(
expr.type.isUnsignedWord -> {
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
asmgen.out(" jsr prog8_math.divmod_uw_asm")
assignVariableWord(target, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
assignVariableWord(target, "P8ZP_SCRATCH_W2", DataType.UWORD)
return true
}
else -> return false
@@ -1501,7 +1497,7 @@ internal class AssignmentAsmGen(
if(right.type.isWord && castedValue.type.isByte && castedValue is PtIdentifier) {
if(right.type.isSigned) {
// we need to sign extend, do this via temporary word variable
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.WORD))
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.WORD)
assignExpressionToRegister(left, RegisterOrPair.AY, dt.isSigned)
if(expr.operator=="+") {
asmgen.out("""
@@ -1638,7 +1634,7 @@ internal class AssignmentAsmGen(
asmgen.out(" sty P8ZP_SCRATCH_B1")
} else {
asmgen.out(" pha")
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla")
}
when (expr.operator) {
@@ -1691,7 +1687,7 @@ internal class AssignmentAsmGen(
asmgen.out(" sty P8ZP_SCRATCH_B1")
} else {
asmgen.out(" pha")
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
asmgen.out(" pla")
}
when (operator) {
@@ -1964,27 +1960,27 @@ $endLabel""")
val (dt, numElements) = when(symbol) {
is StStaticVariable -> symbol.dt to symbol.length!!
is StMemVar -> symbol.dt to symbol.length!!
else -> DataType.forDt(BaseDataType.UNDEFINED) to 0
else -> DataType.UNDEFINED to 0
}
when {
dt.isString -> {
assignExpressionToRegister(containment.needle, RegisterOrPair.A, elementDt.isSigned)
asmgen.out(" pha") // need to keep the scratch var safe so we have to do it in this order
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UWORD), containment.definingISub(), containment.position,"P8ZP_SCRATCH_W1"), symbolName, false, null, null)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position,"P8ZP_SCRATCH_W1"), symbolName, false, null, null)
asmgen.out(" pla")
asmgen.out(" ldy #${numElements-1}")
asmgen.out(" jsr prog8_lib.containment_bytearray")
}
dt.isFloatArray -> {
assignExpressionToRegister(containment.needle, RegisterOrPair.FAC1, true)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UWORD), containment.definingISub(), containment.position, "P8ZP_SCRATCH_W1"), symbolName, false, null, null)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W1"), symbolName, false, null, null)
asmgen.out(" ldy #$numElements")
asmgen.out(" jsr floats.containment_floatarray")
}
dt.isByteArray -> {
assignExpressionToRegister(containment.needle, RegisterOrPair.A, elementDt.isSigned)
asmgen.out(" pha") // need to keep the scratch var safe so we have to do it in this order
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UWORD), containment.definingISub(), containment.position, "P8ZP_SCRATCH_W1"), symbolName, false, null, null)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W1"), symbolName, false, null, null)
asmgen.out(" pla")
asmgen.out(" ldy #$numElements")
asmgen.out(" jsr prog8_lib.containment_bytearray")
@@ -1992,11 +1988,11 @@ $endLabel""")
dt.isWordArray -> {
assignExpressionToVariable(containment.needle, "P8ZP_SCRATCH_W1", elementDt)
if(dt.isSplitWordArray) {
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UWORD), containment.definingISub(), containment.position, "P8ZP_SCRATCH_W2"), symbolName+"_lsb", false, null, null)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W2"), symbolName+"_lsb", false, null, null)
asmgen.out(" ldy #$numElements")
asmgen.out(" jsr prog8_lib.containment_splitwordarray")
} else {
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.forDt(BaseDataType.UWORD), containment.definingISub(), containment.position, "P8ZP_SCRATCH_W2"), symbolName, false, null, null)
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W2"), symbolName, false, null, null)
asmgen.out(" ldy #$numElements")
asmgen.out(" jsr prog8_lib.containment_linearwordarray")
}
@@ -2060,7 +2056,7 @@ $endLabel""")
if(targetDt.isWord) {
fun assignViaExprEval(addressExpression: PtExpression) {
asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
asmgen.out(" ldy #0")
assignRegisterpairWord(target, RegisterOrPair.AY)
@@ -2287,10 +2283,10 @@ $endLabel""")
}
private fun assignCastViaLsbFunc(value: PtExpression, target: AsmAssignTarget) {
val lsb = PtBuiltinFunctionCall("lsb", false, true, DataType.forDt(BaseDataType.UBYTE), value.position)
val lsb = PtBuiltinFunctionCall("lsb", false, true, DataType.UBYTE, value.position)
lsb.parent = value.parent
lsb.add(value)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.forDt(BaseDataType.UBYTE), expression = lsb)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb)
val assign = AsmAssignment(src, listOf(target), program.memsizer, value.position)
translateNormalAssignment(assign, value.definingISub())
}
@@ -2614,7 +2610,7 @@ $endLabel""")
val arrayName = if(arrayDt!!.isSplitWordArray) sourceName+"_lsb" else sourceName // the _lsb split array comes first in memory
val constIndex = arrayIndexExpr.asConstInteger()
if(constIndex!=null) {
if (arrayDt?.isUnsignedWord==true) {
if (arrayDt.isUnsignedWord ==true) {
require(!msb)
assignVariableToRegister(sourceName, RegisterOrPair.AY, false, arrayIndexExpr.definingISub(), arrayIndexExpr.position)
if(constIndex>0)
@@ -2636,12 +2632,12 @@ $endLabel""")
assignRegisterpairWord(target, RegisterOrPair.AY)
return
} else {
if (arrayDt?.isUnsignedWord==true) {
if (arrayDt.isUnsignedWord ==true) {
require(!msb)
assignVariableToRegister(sourceName, RegisterOrPair.AY, false, arrayIndexExpr.definingISub(), arrayIndexExpr.position)
asmgen.saveRegisterStack(CpuRegister.A, false)
asmgen.saveRegisterStack(CpuRegister.Y, false)
assignExpressionToVariable(arrayIndexExpr, "P8ZP_SCRATCH_REG", DataType.forDt(BaseDataType.UBYTE))
assignExpressionToVariable(arrayIndexExpr, "P8ZP_SCRATCH_REG", DataType.UBYTE)
asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.restoreRegisterStack(CpuRegister.A, false)
asmgen.out("""
@@ -4092,7 +4088,7 @@ $endLabel""")
asmgen.storeAIntoPointerVar(memory.address as PtIdentifier)
}
else -> {
asmgen.assignExpressionToVariable(memory.address, "P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD))
asmgen.assignExpressionToVariable(memory.address, "P8ZP_SCRATCH_W2", DataType.UWORD)
if(asmgen.isTargetCpu(CpuType.CPU65C02)) {
asmgen.out("""
lda (P8ZP_SCRATCH_W2)
@@ -4154,8 +4150,8 @@ $endLabel""")
val target = assign.target
val datatype = if(ignoreDatatype) {
when {
target.datatype.isByte -> DataType.forDt(BaseDataType.BYTE)
target.datatype.isWord -> DataType.forDt(BaseDataType.WORD)
target.datatype.isByte -> DataType.BYTE
target.datatype.isWord -> DataType.WORD
else -> target.datatype
}
} else target.datatype
@@ -131,18 +131,18 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
is PtNumber -> {
val addr = (memory.address as PtNumber).number.toInt()
when(value.kind) {
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationByteWithLiteralval(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteWithLiteralval(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.number!!.number.toInt())
SourceStorageKind.LITERALBOOLEAN -> inplacemodificationByteWithLiteralval(addr.toHex(), DataType.UBYTE, operator, value.boolean!!.asInt())
SourceStorageKind.LITERALNUMBER -> inplacemodificationByteWithLiteralval(addr.toHex(), DataType.UBYTE, operator, value.number!!.number.toInt())
SourceStorageKind.VARIABLE -> inplacemodificationByteWithVariable(addr.toHex(), false, operator, value.asmVarname)
SourceStorageKind.REGISTER -> inplacemodificationByteWithVariable(addr.toHex(), false, operator, regName(value))
SourceStorageKind.MEMORY -> inplacemodificationByteWithValue(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.memory!!)
SourceStorageKind.ARRAY -> inplacemodificationByteWithValue(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.array!!)
SourceStorageKind.MEMORY -> inplacemodificationByteWithValue(addr.toHex(), DataType.UBYTE, operator, value.memory!!)
SourceStorageKind.ARRAY -> inplacemodificationByteWithValue(addr.toHex(), DataType.UBYTE, operator, value.array!!)
SourceStorageKind.EXPRESSION -> {
if(value.expression is PtTypeCast) {
if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return
inplacemodificationByteWithValue(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.expression)
inplacemodificationByteWithValue(addr.toHex(), DataType.UBYTE, operator, value.expression)
} else {
inplacemodificationByteWithValue(addr.toHex(), DataType.forDt(BaseDataType.UBYTE), operator, value.expression!!)
inplacemodificationByteWithValue(addr.toHex(), DataType.UBYTE, operator, value.expression!!)
}
}
}
@@ -196,21 +196,21 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
SourceStorageKind.MEMORY -> {
asmgen.out(" sta P8ZP_SCRATCH_B1")
inplacemodificationByteWithValue("P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE), operator, value.memory!!)
inplacemodificationByteWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.memory!!)
asmgen.out(" ldx P8ZP_SCRATCH_B1")
}
SourceStorageKind.ARRAY -> {
asmgen.out(" sta P8ZP_SCRATCH_B1")
inplacemodificationByteWithValue("P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE), operator, value.array!!)
inplacemodificationByteWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.array!!)
asmgen.out(" ldx P8ZP_SCRATCH_B1")
}
SourceStorageKind.EXPRESSION -> {
val tempVar = asmgen.getTempVarName(BaseDataType.UBYTE)
asmgen.out(" sta $tempVar")
if(value.expression is PtTypeCast)
inplacemodificationByteWithValue(tempVar, DataType.forDt(BaseDataType.UBYTE), operator, value.expression)
inplacemodificationByteWithValue(tempVar, DataType.UBYTE, operator, value.expression)
else
inplacemodificationByteWithValue(tempVar, DataType.forDt(BaseDataType.UBYTE), operator, value.expression!!)
inplacemodificationByteWithValue(tempVar, DataType.UBYTE, operator, value.expression!!)
asmgen.out(" ldx $tempVar")
}
}
@@ -592,7 +592,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
fun assignValueToA() {
val assignValue = AsmAssignment(value,
listOf(
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.forDt(BaseDataType.UBYTE),
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE,
address.definingISub(), Position.DUMMY, register = RegisterOrPair.A)
),
program.memsizer, Position.DUMMY)
@@ -898,7 +898,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
private fun inplacemodificationBytePointerWithValue(pointervar: PtIdentifier, operator: String, value: PtExpression) {
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE))
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE)
inplacemodificationBytePointerWithVariable(pointervar, operator, "P8ZP_SCRATCH_B1")
}
+10 -10
View File
@@ -52,7 +52,7 @@ class TestCodegen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"pi",
DataType.forDt(BaseDataType.UBYTE),
DataType.UBYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -79,7 +79,7 @@ class TestCodegen: FunSpec({
))
sub.add(PtVariable(
"xx",
DataType.forDt(BaseDataType.WORD),
DataType.WORD,
ZeropageWish.DONTCARE,
0u,
null,
@@ -89,13 +89,13 @@ class TestCodegen: FunSpec({
val assign = PtAugmentedAssign("+=", Position.DUMMY)
val target = PtAssignTarget(false, Position.DUMMY).also {
val targetIdx = PtArrayIndexer(DataType.forDt(BaseDataType.UBYTE), Position.DUMMY).also { idx ->
val targetIdx = PtArrayIndexer(DataType.UBYTE, Position.DUMMY).also { idx ->
idx.add(PtIdentifier("main.start.particleX", DataType.arrayFor(BaseDataType.UBYTE), Position.DUMMY))
idx.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
}
it.add(targetIdx)
}
val value = PtArrayIndexer(DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val value = PtArrayIndexer(DataType.UBYTE, Position.DUMMY)
value.add(PtIdentifier("main.start.particleDX", DataType.arrayFor(BaseDataType.UBYTE), Position.DUMMY))
value.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
assign.add(target)
@@ -104,15 +104,15 @@ class TestCodegen: FunSpec({
val prefixAssign = PtAugmentedAssign("-", Position.DUMMY)
val prefixTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
prefixAssign.add(prefixTarget)
prefixAssign.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
prefixAssign.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
sub.add(prefixAssign)
val numberAssign = PtAugmentedAssign("-=", Position.DUMMY)
val numberAssignTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
numberAssign.add(numberAssignTarget)
numberAssign.add(PtNumber(BaseDataType.WORD, 42.0, Position.DUMMY))
@@ -120,10 +120,10 @@ class TestCodegen: FunSpec({
val cxregAssign = PtAugmentedAssign("+=", Position.DUMMY)
val cxregAssignTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
cxregAssign.add(cxregAssignTarget)
cxregAssign.add(PtIdentifier("cx16.r0", DataType.forDt(BaseDataType.UWORD), Position.DUMMY))
cxregAssign.add(PtIdentifier("cx16.r0", DataType.UWORD, Position.DUMMY))
sub.add(cxregAssign)
block.add(sub)
@@ -131,7 +131,7 @@ class TestCodegen: FunSpec({
// define the "cx16.r0" virtual register
val cx16block = PtBlock("cx16", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
cx16block.add(PtMemMapped("r0", DataType.forDt(BaseDataType.UWORD), 100u, null, Position.DUMMY))
cx16block.add(PtMemMapped("r0", DataType.UWORD, 100u, null, Position.DUMMY))
program.add(cx16block)
val options = getTestOptions()
@@ -514,7 +514,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
addToResult(result, tr, tr.resultReg, -1)
return Pair(result, tr.resultReg)
}
val mult: PtExpression = PtBinaryExpression("*", DataType.forDt(BaseDataType.UBYTE), array.position)
val mult: PtExpression = PtBinaryExpression("*", DataType.UBYTE, array.position)
mult.children += array.index
mult.children += PtNumber(BaseDataType.UBYTE, itemsize.toDouble(), array.position)
val tr = expressionEval.translateExpression(mult)
+57 -57
View File
@@ -49,7 +49,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"pi",
DataType.forDt(BaseDataType.UBYTE),
DataType.UBYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -76,7 +76,7 @@ class TestVmCodeGen: FunSpec({
))
sub.add(PtVariable(
"xx",
DataType.forDt(BaseDataType.WORD),
DataType.WORD,
ZeropageWish.DONTCARE,
0u,
null,
@@ -86,7 +86,7 @@ class TestVmCodeGen: FunSpec({
val assign = PtAugmentedAssign("+=", Position.DUMMY)
val target = PtAssignTarget(false, Position.DUMMY).also {
val targetIdx = PtArrayIndexer(DataType.forDt(BaseDataType.UBYTE), Position.DUMMY).also { idx ->
val targetIdx = PtArrayIndexer(DataType.UBYTE, Position.DUMMY).also { idx ->
idx.add(PtIdentifier("main.start.particleX",
DataType.arrayFor(BaseDataType.UBYTE),
Position.DUMMY))
@@ -94,7 +94,7 @@ class TestVmCodeGen: FunSpec({
}
it.add(targetIdx)
}
val value = PtArrayIndexer(DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val value = PtArrayIndexer(DataType.UBYTE, Position.DUMMY)
value.add(PtIdentifier("main.start.particleDX",
DataType.arrayFor(BaseDataType.UBYTE),
Position.DUMMY))
@@ -105,15 +105,15 @@ class TestVmCodeGen: FunSpec({
val prefixAssign = PtAugmentedAssign("-", Position.DUMMY)
val prefixTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
prefixAssign.add(prefixTarget)
prefixAssign.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
prefixAssign.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
sub.add(prefixAssign)
val numberAssign = PtAugmentedAssign("+=", Position.DUMMY)
val numberAssignTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
numberAssign.add(numberAssignTarget)
numberAssign.add(PtNumber(BaseDataType.WORD, 42.0, Position.DUMMY))
@@ -121,10 +121,10 @@ class TestVmCodeGen: FunSpec({
val cxregAssign = PtAugmentedAssign("+=", Position.DUMMY)
val cxregAssignTarget = PtAssignTarget(false, Position.DUMMY).also {
it.add(PtIdentifier("main.start.xx", DataType.forDt(BaseDataType.WORD), Position.DUMMY))
it.add(PtIdentifier("main.start.xx", DataType.WORD, Position.DUMMY))
}
cxregAssign.add(cxregAssignTarget)
cxregAssign.add(PtIdentifier("cx16.r0", DataType.forDt(BaseDataType.UWORD), Position.DUMMY))
cxregAssign.add(PtIdentifier("cx16.r0", DataType.UWORD, Position.DUMMY))
sub.add(cxregAssign)
block.add(sub)
@@ -132,7 +132,7 @@ class TestVmCodeGen: FunSpec({
// define the "cx16.r0" virtual register
val cx16block = PtBlock("cx16", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
cx16block.add(PtMemMapped("r0", DataType.forDt(BaseDataType.UWORD), 100u, null, Position.DUMMY))
cx16block.add(PtMemMapped("r0", DataType.UWORD, 100u, null, Position.DUMMY))
program.add(cx16block)
val options = getTestOptions()
@@ -164,7 +164,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"f1",
DataType.forDt(BaseDataType.FLOAT),
DataType.FLOAT,
ZeropageWish.DONTCARE,
0u,
null,
@@ -172,32 +172,32 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.FLOAT, 0.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp2 = PtBinaryExpression("!=", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.FLOAT, 0.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2)
val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp3 = PtBinaryExpression("<", DataType.BOOL, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp3.add(PtNumber(BaseDataType.FLOAT, 0.0, Position.DUMMY))
if3.add(cmp3)
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3)
val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp4 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp4.add(PtNumber(BaseDataType.FLOAT, 0.0, Position.DUMMY))
if4.add(cmp4)
if4.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
@@ -235,7 +235,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"f1",
DataType.forDt(BaseDataType.FLOAT),
DataType.FLOAT,
ZeropageWish.DONTCARE,
0u,
null,
@@ -243,32 +243,32 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp2 = PtBinaryExpression("!=", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2)
val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp3 = PtBinaryExpression("<", DataType.BOOL, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp3.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if3.add(cmp3)
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3)
val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp4 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp4.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if4.add(cmp4)
if4.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
@@ -302,7 +302,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"f1",
DataType.forDt(BaseDataType.FLOAT),
DataType.FLOAT,
ZeropageWish.DONTCARE,
0u,
null,
@@ -310,16 +310,16 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtJump(Position.DUMMY).also { it.add(PtNumber(BaseDataType.UWORD, 0xc000.toDouble(), Position.DUMMY)) }) })
if1.add(PtNodeGroup())
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.forDt(BaseDataType.FLOAT), Position.DUMMY))
val cmp2 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.FLOAT, 42.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtJump(Position.DUMMY).also { it.add(PtNumber(BaseDataType.UWORD, 0xc000.toDouble(), Position.DUMMY)) }) })
@@ -357,7 +357,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"sb1",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -365,32 +365,32 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.BYTE, 0.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp2 = PtBinaryExpression("!=", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.BYTE, 0.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2)
val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp3 = PtBinaryExpression("<", DataType.BOOL, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp3.add(PtNumber(BaseDataType.BYTE, 0.0, Position.DUMMY))
if3.add(cmp3)
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3)
val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp4 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp4.add(PtNumber(BaseDataType.BYTE, 0.0, Position.DUMMY))
if4.add(cmp4)
if4.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
@@ -428,7 +428,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"sb1",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -436,32 +436,32 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.BYTE, 42.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp2 = PtBinaryExpression("!=", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.BYTE, 42.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2)
val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp3 = PtBinaryExpression("<", DataType.BOOL, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp3.add(PtNumber(BaseDataType.BYTE, 42.0, Position.DUMMY))
if3.add(cmp3)
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3)
val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.forDt(BaseDataType.BYTE), Position.DUMMY))
val cmp4 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp4.add(PtNumber(BaseDataType.BYTE, 42.0, Position.DUMMY))
if4.add(cmp4)
if4.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
@@ -495,7 +495,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
sub.add(PtVariable(
"ub1",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -503,16 +503,16 @@ class TestVmCodeGen: FunSpec({
Position.DUMMY
))
val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp1.add(PtIdentifier("main.start.ub1", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY))
val cmp1 = PtBinaryExpression("==", DataType.BOOL, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY))
cmp1.add(PtNumber(BaseDataType.UBYTE, 42.0, Position.DUMMY))
if1.add(cmp1)
if1.add(PtNodeGroup().also { it.add(PtJump(Position.DUMMY).also { it.add(PtNumber(BaseDataType.UWORD, 0xc000.toDouble(), Position.DUMMY)) }) })
if1.add(PtNodeGroup())
sub.add(if1)
val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression(">", DataType.forDt(BaseDataType.BOOL), Position.DUMMY)
cmp2.add(PtIdentifier("main.start.ub1", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY))
val cmp2 = PtBinaryExpression(">", DataType.BOOL, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY))
cmp2.add(PtNumber(BaseDataType.UBYTE, 42.0, Position.DUMMY))
if2.add(cmp2)
if2.add(PtNodeGroup().also { it.add(PtJump(Position.DUMMY).also {it.add(PtNumber(BaseDataType.UWORD, 0xc000.toDouble(), Position.DUMMY)) }) })
@@ -543,7 +543,7 @@ class TestVmCodeGen: FunSpec({
val extsub = PtAsmSub("routine", PtAsmSub.Address(null, null, 0x5000u), setOf(CpuRegister.Y), emptyList(), emptyList(), false, Position.DUMMY)
block.add(extsub)
val sub = PtSub("start", emptyList(), emptyList(), Position.DUMMY)
val call = PtFunctionCall("main.routine", true, DataType.forDt(BaseDataType.UNDEFINED), Position.DUMMY)
val call = PtFunctionCall("main.routine", true, DataType.UNDEFINED, Position.DUMMY)
sub.add(call)
block.add(sub)
program.add(block)
@@ -1,11 +1,6 @@
package prog8.optimizer
import prog8.ast.FatalAstException
import prog8.ast.IFunctionCall
import prog8.ast.IStatementContainer
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.UndefinedSymbolError
import prog8.ast.*
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
@@ -457,7 +452,7 @@ internal class ConstantIdentifierReplacer(
if(declArraySize!=null && declArraySize!=rangeExpr.size())
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
if(constRange!=null) {
val rangeType = rangeExpr.inferType(program).getOr(DataType.forDt(BaseDataType.UBYTE))
val rangeType = rangeExpr.inferType(program).getOr(DataType.UBYTE)
return if(rangeType.isByte) {
ArrayLiteral(InferredTypes.InferredType.known(decl.datatype),
constRange.map { NumericLiteral(rangeType.base, it.toDouble(), decl.value!!.position) }.toTypedArray(),
@@ -531,7 +531,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
// useless msb() of byte value that was typecasted to word, replace with 0
return listOf(IAstModification.ReplaceNode(
functionCallExpr,
NumericLiteral(valueDt.getOr(DataType.forDt(BaseDataType.UBYTE)).base, 0.0, arg.expression.position),
NumericLiteral(valueDt.getOr(DataType.UBYTE).base, 0.0, arg.expression.position),
parent))
}
} else {
@@ -546,7 +546,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
// useless msb() of byte value, replace with 0
return listOf(IAstModification.ReplaceNode(
functionCallExpr,
NumericLiteral(argDt.getOr(DataType.forDt(BaseDataType.UBYTE)).base, 0.0, arg.position),
NumericLiteral(argDt.getOr(DataType.UBYTE).base, 0.0, arg.position),
parent))
}
}
@@ -1,8 +1,6 @@
package prog8.compiler.astprocessing
import prog8.ast.*
import prog8.ast.FatalAstException
import prog8.ast.SyntaxError
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
@@ -1124,7 +1122,7 @@ internal class AstChecker(private val program: Program,
}
override fun visit(string: StringLiteral) {
checkValueTypeAndRangeString(DataType.forDt(BaseDataType.STR), string)
checkValueTypeAndRangeString(DataType.STR, string)
try { // just *try* if it can be encoded, don't actually do it
val bytes = compilerOptions.compTarget.encodeString(string.value, string.encoding)
@@ -1570,7 +1568,7 @@ internal class AstChecker(private val program: Program,
}
if(target.returntypes.size>1) {
if (DataType.forDt(BaseDataType.FLOAT) in target.returntypes) {
if (DataType.FLOAT in target.returntypes) {
errors.err("floats cannot be used as part of a multi-value result", target.position)
}
}
@@ -222,7 +222,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
for(directive in directives.filter { it.directive == "%jmptable" }) {
val table = PtJmpTable(directive.position)
directive.args.forEach {
table.add(PtIdentifier(it.string!!, DataType.forDt(BaseDataType.UNDEFINED), it.position))
table.add(PtIdentifier(it.string!!, DataType.UNDEFINED, it.position))
}
block.add(table)
}
@@ -338,7 +338,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
val (target, _) = srcCall.target.targetNameAndType(program)
val iType = srcCall.inferType(program)
val call = PtFunctionCall(target, iType.isUnknown && srcCall.parent !is Assignment, iType.getOrElse { DataType.forDt(BaseDataType.UNDEFINED) }, srcCall.position)
val call = PtFunctionCall(target, iType.isUnknown && srcCall.parent !is Assignment, iType.getOrElse { DataType.UNDEFINED }, srcCall.position)
for (arg in srcCall.args)
call.add(transformExpression(arg))
return call
@@ -389,8 +389,8 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
val endLabel = program.makeLabel("cend")
val scopedElseLabel = (srcIf.definingScope.scopedName + elseLabel).joinToString(".")
val scopedEndLabel = (srcIf.definingScope.scopedName + endLabel).joinToString(".")
val elseLbl = PtIdentifier(scopedElseLabel, DataType.forDt(BaseDataType.UNDEFINED), srcIf.position)
val endLbl = PtIdentifier(scopedEndLabel, DataType.forDt(BaseDataType.UNDEFINED), srcIf.position)
val elseLbl = PtIdentifier(scopedElseLabel, DataType.UNDEFINED, srcIf.position)
val endLbl = PtIdentifier(scopedEndLabel, DataType.UNDEFINED, srcIf.position)
ifScope.add(PtJump(srcIf.position).also { it.add(elseLbl) })
val elseScope = PtNodeGroup()
branch.add(ifScope)
@@ -548,7 +548,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
val (vardecls, statements) = srcSub.statements.partition { it is VarDecl }
// if a sub returns 'str', replace with uword. Simplified AST and I.R. don't contain 'str' datatype anymore.
var returnTypes = srcSub.returntypes.map {
if(it.isString) DataType.forDt(BaseDataType.UWORD) else it
if(it.isString) DataType.UWORD else it
}
// do not bother about the 'inline' hint of the source subroutine.
val sub = PtSub(srcSub.name,
@@ -651,27 +651,27 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
fun desugar(range: RangeExpression): PtExpression {
require(range.from.inferType(program)==range.to.inferType(program))
val expr = PtBinaryExpression("and", DataType.forDt(BaseDataType.BOOL), srcCheck.position)
val expr = PtBinaryExpression("and", DataType.BOOL, srcCheck.position)
val x1 = transformExpression(srcCheck.element)
val x2 = transformExpression(srcCheck.element)
val eltDt = srcCheck.element.inferType(program)
if(eltDt.isInteger) {
val low = PtBinaryExpression("<=", DataType.forDt(BaseDataType.BOOL), srcCheck.position)
val low = PtBinaryExpression("<=", DataType.BOOL, srcCheck.position)
low.add(transformExpression(range.from))
low.add(x1)
expr.add(low)
val high = PtBinaryExpression("<=", DataType.forDt(BaseDataType.BOOL), srcCheck.position)
val high = PtBinaryExpression("<=", DataType.BOOL, srcCheck.position)
high.add(x2)
high.add(transformExpression(range.to))
expr.add(high)
} else {
val low = PtBinaryExpression("<=", DataType.forDt(BaseDataType.BOOL), srcCheck.position)
val low = PtBinaryExpression("<=", DataType.BOOL, srcCheck.position)
val lowFloat = PtTypeCast(BaseDataType.FLOAT, range.from.position)
lowFloat.add(transformExpression(range.from))
low.add(lowFloat)
low.add(x1)
expr.add(low)
val high = PtBinaryExpression("<=", DataType.forDt(BaseDataType.BOOL), srcCheck.position)
val high = PtBinaryExpression("<=", DataType.BOOL, srcCheck.position)
high.add(x2)
val highFLoat = PtTypeCast(BaseDataType.FLOAT, range.to.position)
highFLoat.add(transformExpression(range.to))
@@ -43,7 +43,7 @@ private fun setDeferMasks(program: PtProgram, errors: IErrorReporter): Map<PtSub
// define the bitmask variable and set it to zero
val deferVariable = PtVariable(
maskVarName,
DataType.forDt(BaseDataType.UBYTE),
DataType.UBYTE,
ZeropageWish.NOT_IN_ZEROPAGE,
0u,
null,
@@ -52,7 +52,7 @@ private fun setDeferMasks(program: PtProgram, errors: IErrorReporter): Map<PtSub
)
val assignZero = PtAssignment(sub.position)
assignZero.add(PtAssignTarget(false, sub.position).also {
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.forDt(BaseDataType.UBYTE), sub.position))
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, sub.position))
})
assignZero.add(PtNumber(BaseDataType.UBYTE, 0.0, sub.position))
sub.add(0, assignZero)
@@ -64,7 +64,7 @@ private fun setDeferMasks(program: PtProgram, errors: IErrorReporter): Map<PtSub
val idx = scope.children.indexOf(defer)
val enableDefer = PtAugmentedAssign("|=", defer.position)
val target = PtAssignTarget(true, defer.position)
target.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.forDt(BaseDataType.UBYTE), defer.position))
target.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, defer.position))
enableDefer.add(target)
// enable the bit for this defer (beginning with high bits so the handler can simply shift right to check them in reverse order)
enableDefer.add(PtNumber(BaseDataType.UBYTE, (1 shl (defers.size-1 - deferIndex)).toDouble(), defer.position))
@@ -111,7 +111,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
fun invokedeferbefore(node: PtNode) {
val idx = node.parent.children.indexOf(node)
val invokedefer = PtFunctionCall(node.definingSub()!!.scopedName+"."+invokeDefersRoutineName, true, DataType.forDt(BaseDataType.UNDEFINED), node.position)
val invokedefer = PtFunctionCall(node.definingSub()!!.scopedName+"."+invokeDefersRoutineName, true, DataType.UNDEFINED, node.position)
node.parent.add(idx, invokedefer)
}
@@ -157,7 +157,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
val group = PtNodeGroup()
pushCalls.forEach { group.add(it) }
popCalls.forEach { newRet.add(it) }
group.add(PtFunctionCall(ret.definingSub()!!.scopedName+"."+invokeDefersRoutineName, true,DataType.forDt(BaseDataType.UNDEFINED), ret.position))
group.add(PtFunctionCall(ret.definingSub()!!.scopedName+"."+invokeDefersRoutineName, true,DataType.UNDEFINED, ret.position))
group.add(newRet)
group.parent = ret.parent
val idx = ret.parent.children.indexOf(ret)
@@ -171,7 +171,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
val idx = sub.children.indexOfLast { it !is PtDefer }
val ret = PtReturn(sub.position)
sub.add(idx+1, ret)
val invokedefer = PtFunctionCall(sub.scopedName+"."+invokeDefersRoutineName, true, DataType.forDt(BaseDataType.UNDEFINED), sub.position)
val invokedefer = PtFunctionCall(sub.scopedName+"."+invokeDefersRoutineName, true, DataType.UNDEFINED, sub.position)
sub.add(idx+1, invokedefer)
}
}
@@ -184,7 +184,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
for((idx, defer) in defers.reversed().withIndex()) {
val shift = PtAugmentedAssign(">>=", Position.DUMMY)
shift.add(PtAssignTarget(false, sub.position).also {
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.forDt(BaseDataType.UBYTE), sub.position))
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, sub.position))
})
shift.add(PtNumber(BaseDataType.UBYTE, 1.0, sub.position))
defersRoutine.add(shift)
@@ -192,7 +192,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
val branchcc = PtConditionalBranch(BranchCondition.CC, Position.DUMMY)
branchcc.add(PtNodeGroup().also {
val jump = PtJump(Position.DUMMY)
jump.add(PtIdentifier(defersRoutine.scopedName+"."+skiplabel, DataType.forDt(BaseDataType.UBYTE), Position.DUMMY))
jump.add(PtIdentifier(defersRoutine.scopedName+"."+skiplabel, DataType.UBYTE, Position.DUMMY))
it.add(jump)
})
branchcc.add(PtNodeGroup())
@@ -207,13 +207,13 @@ internal class StatementReorderer(
// change 'str' and 'ubyte[]' parameters into 'uword' (just treat it as an address)
val stringParams = subroutine.parameters.filter { it.type.isString || it.type.isUnsignedByteArray }
val parameterChanges = stringParams.map {
val uwordParam = SubroutineParameter(it.name, DataType.forDt(BaseDataType.UWORD), it.zp, it.registerOrPair, it.position)
val uwordParam = SubroutineParameter(it.name, DataType.UWORD, it.zp, it.registerOrPair, it.position)
IAstModification.ReplaceNode(it, uwordParam, subroutine)
}
// change 'str' and 'ubyte[]' return types into 'uword' (just treat it as an address)
subroutine.returntypes.withIndex().forEach { (index, type) ->
if(type.isString || type.isUnsignedByteArray)
subroutine.returntypes[index] = DataType.forDt(BaseDataType.UWORD)
subroutine.returntypes[index] = DataType.UWORD
}
val varsChanges = mutableListOf<IAstModification>()
@@ -226,7 +226,7 @@ internal class StatementReorderer(
.filterIsInstance<VarDecl>()
.filter { it.origin==VarDeclOrigin.SUBROUTINEPARAM && it.name in stringParamsByNames }
.map {
val newvar = VarDecl(it.type, it.origin, DataType.forDt(BaseDataType.UWORD),
val newvar = VarDecl(it.type, it.origin, DataType.UWORD,
it.zeropage,
it.splitwordarray,
null,
@@ -1,9 +1,9 @@
package prog8.compiler.astprocessing
import prog8.ast.FatalAstException
import prog8.ast.IFunctionCall
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
@@ -300,7 +300,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
// make sure the memory address is an uword
val modifications = mutableListOf<IAstModification>()
val dt = memread.addressExpression.inferType(program)
if(dt.isKnown && !dt.getOr(DataType.forDt(BaseDataType.UWORD)).isUnsignedWord) {
if(dt.isKnown && !dt.getOr(DataType.UWORD).isUnsignedWord) {
val castedValue = (memread.addressExpression as? NumericLiteral)?.cast(BaseDataType.UWORD, true)?.valueOrZero()
if(castedValue!=null)
modifications += IAstModification.ReplaceNode(memread.addressExpression, castedValue, memread)
@@ -314,7 +314,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
// make sure the memory address is an uword
val modifications = mutableListOf<IAstModification>()
val dt = memwrite.addressExpression.inferType(program)
if(dt.isKnown && !dt.getOr(DataType.forDt(BaseDataType.UWORD)).isUnsignedWord) {
if(dt.isKnown && !dt.getOr(DataType.UWORD).isUnsignedWord) {
val castedValue = (memwrite.addressExpression as? NumericLiteral)?.cast(BaseDataType.UWORD, true)?.valueOrZero()
if(castedValue!=null)
modifications += IAstModification.ReplaceNode(memwrite.addressExpression, castedValue, memwrite)
@@ -37,7 +37,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
val pushFunc = if(pushFloat) "floats.push" else if(pushWord) "sys.pushw" else "sys.push"
val popFunc = if(pushFloat) "floats.pop" else if(pushWord) "sys.popw" else "sys.pop"
val pushCall = PtFunctionCall(pushFunc, true, DataType.forDt(BaseDataType.UNDEFINED), value.position)
val pushCall = PtFunctionCall(pushFunc, true, DataType.UNDEFINED, value.position)
if(pushTypecast!=null) {
val typecast = PtTypeCast(pushTypecast, value.position).also {
it.add(value)
@@ -48,7 +48,7 @@ internal fun makePushPopFunctionCalls(value: PtExpression): Pair<PtFunctionCall,
}
val popCall = if(popTypecast!=null) {
PtTypeCast(popTypecast, value.position).also {
val returnDt = if(pushWord) DataType.forDt(BaseDataType.UWORD) else DataType.forDt(BaseDataType.UBYTE)
val returnDt = if(pushWord) DataType.UWORD else DataType.UBYTE
it.add(PtFunctionCall(popFunc, false, returnDt, value.position))
}
} else
+2 -2
View File
@@ -81,7 +81,7 @@ class TestCompilerOnCharLit: FunSpec({
val arg = funCall.args[0] as IdentifierReference
val decl = arg.targetVarDecl(program)!!
decl.type shouldBe VarDeclType.VAR
decl.datatype shouldBe DataType.forDt(BaseDataType.UBYTE)
decl.datatype shouldBe DataType.UBYTE
withClue("initializer value should have been moved to separate assignment"){
decl.value shouldBe null
@@ -117,7 +117,7 @@ class TestCompilerOnCharLit: FunSpec({
is IdentifierReference -> {
val decl = arg.targetVarDecl(program)!!
decl.type shouldBe VarDeclType.CONST
decl.datatype shouldBe DataType.forDt(BaseDataType.UBYTE)
decl.datatype shouldBe DataType.UBYTE
(decl.value as NumericLiteral).number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0]
}
is NumericLiteral -> {
+4 -8
View File
@@ -14,11 +14,7 @@ import prog8.ast.expressions.NumericLiteral
import prog8.ast.expressions.RangeExpression
import prog8.ast.statements.ForLoop
import prog8.ast.statements.VarDecl
import prog8.code.ast.PtBinaryExpression
import prog8.code.ast.PtBool
import prog8.code.ast.PtIdentifier
import prog8.code.ast.PtIfElse
import prog8.code.ast.PtNumber
import prog8.code.ast.*
import prog8.code.core.BaseDataType
import prog8.code.core.DataType
import prog8.code.core.Encoding
@@ -233,7 +229,7 @@ class TestCompilerOnRanges: FunSpec({
.map { it.iterable }
.filterIsInstance<IdentifierReference>()[0]
iterable.inferType(program).getOrUndef() shouldBe DataType.forDt(BaseDataType.STR)
iterable.inferType(program).getOrUndef() shouldBe DataType.STR
}
test("testRangeExprNumericSize") {
@@ -493,11 +489,11 @@ main {
val left = cond.left as PtBinaryExpression
val right = cond.right as PtBinaryExpression
left.operator shouldBe "<="
(left.left as PtNumber).type shouldBe DataType.forDt(BaseDataType.WORD)
(left.left as PtNumber).type shouldBe DataType.WORD
(left.left as PtNumber).number shouldBe 325.0
left.right shouldBe instanceOf<PtIdentifier>()
right.operator shouldBe "<="
(right.right as PtNumber).type shouldBe DataType.forDt(BaseDataType.WORD)
(right.right as PtNumber).type shouldBe DataType.WORD
(right.right as PtNumber).number shouldBe 477.0
right.left shouldBe instanceOf<PtIdentifier>()
}
+7 -7
View File
@@ -28,7 +28,7 @@ class TestGoldenRam: FunSpec({
test("empty golden ram allocations") {
val errors = ErrorReporterForTests()
val golden = GoldenRam(options, UIntRange.EMPTY)
val result = golden.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
val result = golden.allocate("test", DataType.UBYTE, null, null, errors)
result.expectError { "should not be able to allocate anything" }
}
@@ -36,28 +36,28 @@ class TestGoldenRam: FunSpec({
val errors = ErrorReporterForTests()
val golden = GoldenRam(options, 0x400u until 0x800u)
var result = golden.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
var result = golden.allocate("test", DataType.UBYTE, null, null, errors)
var alloc = result.getOrThrow()
alloc.size shouldBe 1
alloc.address shouldBe 0x400u
result = golden.allocate("test", DataType.forDt(BaseDataType.STR), 100, null, errors)
result = golden.allocate("test", DataType.STR, 100, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 100
alloc.address shouldBe 0x401u
repeat(461) {
result = golden.allocate("test", DataType.forDt(BaseDataType.UWORD), null, null, errors)
result = golden.allocate("test", DataType.UWORD, null, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 2
}
result = golden.allocate("test", DataType.forDt(BaseDataType.UWORD), null, null, errors)
result = golden.allocate("test", DataType.UWORD, null, null, errors)
result.expectError { "just 1 more byte available" }
result = golden.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 1
alloc.address shouldBe golden.region.last
result = golden.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
result.expectError { "nothing more available" }
}
+12 -12
View File
@@ -117,7 +117,7 @@ class TestMemory: FunSpec({
}
fun createTestProgramForMemoryRefViaVar(address: UInt, vartype: VarDeclType): AssignTarget {
val decl = VarDecl(vartype, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.BYTE), ZeropageWish.DONTCARE,
val decl = VarDecl(vartype, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, 0u, false, Position.DUMMY)
val memexpr = IdentifierReference(listOf("address"), Position.DUMMY)
val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), null, false, Position.DUMMY)
@@ -156,7 +156,7 @@ class TestMemory: FunSpec({
}
test("regular variable not in mapped IO ram on C64") {
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.BYTE), ZeropageWish.DONTCARE,
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "address", emptyList(), null, false, 0u, false, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, null, false, Position.DUMMY)
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
@@ -169,7 +169,7 @@ class TestMemory: FunSpec({
test("memory mapped variable not in mapped IO ram on C64") {
val address = 0x1000u
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UBYTE), ZeropageWish.DONTCARE,
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, 0u, false, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, null, false, Position.DUMMY)
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
@@ -182,7 +182,7 @@ class TestMemory: FunSpec({
test("memory mapped variable in mapped IO ram on C64") {
val address = 0xd020u
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UBYTE), ZeropageWish.DONTCARE,
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, 0u, false, Position.DUMMY)
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, null, false, Position.DUMMY)
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
@@ -270,12 +270,12 @@ class TestMemory: FunSpec({
target.memorySize(BaseDataType.WORD) shouldBe 2
target.memorySize(BaseDataType.FLOAT) shouldBe target.FLOAT_MEM_SIZE
target.memorySize(DataType.forDt(BaseDataType.BOOL), null) shouldBe 1
target.memorySize(DataType.forDt(BaseDataType.WORD), null) shouldBe 2
target.memorySize(DataType.forDt(BaseDataType.FLOAT), null) shouldBe target.FLOAT_MEM_SIZE
target.memorySize(DataType.BOOL, null) shouldBe 1
target.memorySize(DataType.WORD, null) shouldBe 2
target.memorySize(DataType.FLOAT, null) shouldBe target.FLOAT_MEM_SIZE
target.memorySize(DataType.forDt(BaseDataType.STR), null) shouldBe 2
target.memorySize(DataType.forDt(BaseDataType.STR), 50) shouldBe 50
target.memorySize(DataType.STR, null) shouldBe 2
target.memorySize(DataType.STR, 50) shouldBe 50
target.memorySize(BaseDataType.STR) shouldBe 2
target.memorySize(BaseDataType.ARRAY) shouldBe 2
target.memorySize(BaseDataType.ARRAY_SPLITW) shouldBe 2
@@ -288,9 +288,9 @@ class TestMemory: FunSpec({
target.memorySize(DataType.arrayFor(BaseDataType.WORD, true), 10) shouldBe 20
target.memorySize(DataType.arrayFor(BaseDataType.UWORD, true), 10) shouldBe 20
target.memorySize(DataType.forDt(BaseDataType.BOOL), 10) shouldBe 10
target.memorySize(DataType.forDt(BaseDataType.UWORD), 10) shouldBe 20
target.memorySize(DataType.forDt(BaseDataType.FLOAT), 10) shouldBe 10*target.FLOAT_MEM_SIZE
target.memorySize(DataType.BOOL, 10) shouldBe 10
target.memorySize(DataType.UWORD, 10) shouldBe 20
target.memorySize(DataType.FLOAT, 10) shouldBe 10*target.FLOAT_MEM_SIZE
}
}
})
+8 -9
View File
@@ -10,7 +10,6 @@ import io.kotest.matchers.types.instanceOf
import prog8.ast.IFunctionCall
import prog8.ast.expressions.IdentifierReference
import prog8.ast.statements.*
import prog8.code.core.BaseDataType
import prog8.code.core.DataType
import prog8.code.target.C64Target
import prog8.code.target.VMTarget
@@ -71,12 +70,12 @@ class TestSubroutines: FunSpec({
asmfunc.statements.isEmpty() shouldBe true
func.isAsmSubroutine shouldBe false
withClue("str param for subroutines should be changed into UWORD") {
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
func.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
asmfunc.parameters.single().type shouldBe DataType.UWORD
func.parameters.single().type shouldBe DataType.UWORD
func.statements.size shouldBe 4
val paramvar = func.statements[0] as VarDecl
paramvar.name shouldBe "thing"
paramvar.datatype shouldBe DataType.forDt(BaseDataType.UWORD)
paramvar.datatype shouldBe DataType.UWORD
}
val assign = func.statements[2] as Assignment
assign.target.identifier!!.nameInSource shouldBe listOf("t2")
@@ -132,8 +131,8 @@ class TestSubroutines: FunSpec({
asmfunc.hasRtsInAsm(false) shouldBe true
func.isAsmSubroutine shouldBe false
withClue("str param should have been changed to uword") {
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
func.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
asmfunc.parameters.single().type shouldBe DataType.UWORD
func.parameters.single().type shouldBe DataType.UWORD
}
func.statements.size shouldBe 5
@@ -141,7 +140,7 @@ class TestSubroutines: FunSpec({
val paramvar = func.statements[0] as VarDecl
paramvar.name shouldBe "thing"
withClue("pre-asmgen should have changed str to uword type") {
paramvar.datatype shouldBe DataType.forDt(BaseDataType.UWORD)
paramvar.datatype shouldBe DataType.UWORD
}
val assign = func.statements[2] as Assignment
assign.target.identifier!!.nameInSource shouldBe listOf("t2")
@@ -187,8 +186,8 @@ class TestSubroutines: FunSpec({
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
withClue("ubyte array param should have been replaced by UWORD pointer") {
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
func.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
asmfunc.parameters.single().type shouldBe DataType.UWORD
func.parameters.single().type shouldBe DataType.UWORD
}
}
+24 -21
View File
@@ -7,7 +7,10 @@ import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.types.shouldBeSameInstanceAs
import prog8.code.*
import prog8.code.ast.*
import prog8.code.core.*
import prog8.code.core.BaseDataType
import prog8.code.core.DataType
import prog8.code.core.Position
import prog8.code.core.ZeropageWish
import prog8.code.source.SourceCode
import prog8tests.helpers.DummyMemsizer
import prog8tests.helpers.DummyStringEncoder
@@ -38,9 +41,9 @@ class TestSymbolTable: FunSpec({
st.lookupUnscoped("undefined") shouldBe null
st.lookup("undefined") shouldBe null
st.lookup("undefined.undefined") shouldBe null
var default = st.lookupUnscopedOrElse("undefined") { StNode("default", StNodeType.LABEL, PtIdentifier("default", DataType.forDt(BaseDataType.BYTE), Position.DUMMY)) }
var default = st.lookupUnscopedOrElse("undefined") { StNode("default", StNodeType.LABEL, PtIdentifier("default", DataType.BYTE, Position.DUMMY)) }
default.name shouldBe "default"
default = st.lookupUnscopedOrElse("undefined") { StNode("default", StNodeType.LABEL, PtIdentifier("default", DataType.forDt(BaseDataType.BYTE), Position.DUMMY)) }
default = st.lookupUnscopedOrElse("undefined") { StNode("default", StNodeType.LABEL, PtIdentifier("default", DataType.BYTE, Position.DUMMY)) }
default.name shouldBe "default"
val msbFunc = st.lookupUnscopedOrElse("msb") { fail("msb must be found") }
@@ -62,7 +65,7 @@ class TestSymbolTable: FunSpec({
val v1 = sub1.lookupUnscopedOrElse("v1") { fail("v1 must be found") } as StStaticVariable
v1.type shouldBe StNodeType.STATICVAR
v1.name shouldBe "v1"
v1.dt shouldBe DataType.forDt(BaseDataType.BYTE)
v1.dt shouldBe DataType.BYTE
val blockc = sub1.lookupUnscopedOrElse("blockc") { fail("blockc") } as StConstant
blockc.type shouldBe StNodeType.CONSTANT
@@ -82,10 +85,10 @@ class TestSymbolTable: FunSpec({
}
test("static vars") {
val node = PtIdentifier("dummy", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val stVar1 = StStaticVariable("initialized", DataType.forDt(BaseDataType.UBYTE), null, null, null, ZeropageWish.DONTCARE, 0, node)
val node = PtIdentifier("dummy", DataType.UBYTE, Position.DUMMY)
val stVar1 = StStaticVariable("initialized", DataType.UBYTE, null, null, null, ZeropageWish.DONTCARE, 0, node)
stVar1.setOnetimeInitNumeric(99.0)
val stVar2 = StStaticVariable("uninitialized", DataType.forDt(BaseDataType.UBYTE), null, null, null, ZeropageWish.DONTCARE, 0, node)
val stVar2 = StStaticVariable("uninitialized", DataType.UBYTE, null, null, null, ZeropageWish.DONTCARE, 0, node)
val arrayInitNonzero = listOf(StArrayElement(1.1, null, null), StArrayElement(2.2, null, null), StArrayElement(3.3, null, null))
val arrayInitAllzero = listOf(StArrayElement(0.0, null, null), StArrayElement(0.0, null, null), StArrayElement(0.0, null, null))
val stVar3 = StStaticVariable("initialized", DataType.arrayFor(BaseDataType.UWORD), null, arrayInitNonzero, 3, ZeropageWish.DONTCARE, 0, node)
@@ -111,15 +114,15 @@ private fun makeSt(): SymbolTable {
// first build the AST
val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val astBlock1 = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY)
val astConstant1 = PtConstant("c1", DataType.forDt(BaseDataType.UWORD), 12345.0, Position.DUMMY)
val astConstant2 = PtConstant("blockc", DataType.forDt(BaseDataType.UWORD), 999.0, Position.DUMMY)
val astConstant1 = PtConstant("c1", DataType.UWORD, 12345.0, Position.DUMMY)
val astConstant2 = PtConstant("blockc", DataType.UWORD, 999.0, Position.DUMMY)
astBlock1.add(astConstant1)
astBlock1.add(astConstant2)
val astSub1 = PtSub("sub1", emptyList(), emptyList(), Position.DUMMY)
val astSub2 = PtSub("sub2", emptyList(), emptyList(), Position.DUMMY)
val astSub1v1 = PtVariable(
"v1",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -128,7 +131,7 @@ private fun makeSt(): SymbolTable {
)
val astSub1v2 = PtVariable(
"v2",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -137,7 +140,7 @@ private fun makeSt(): SymbolTable {
)
val astSub1v3 = PtVariable(
"v3",
DataType.forDt(BaseDataType.FLOAT),
DataType.FLOAT,
ZeropageWish.DONTCARE,
0u,
null,
@@ -146,7 +149,7 @@ private fun makeSt(): SymbolTable {
)
val astSub1v4 = PtVariable(
"slab1",
DataType.forDt(BaseDataType.UWORD),
DataType.UWORD,
ZeropageWish.DONTCARE,
0u,
null,
@@ -155,7 +158,7 @@ private fun makeSt(): SymbolTable {
)
val astSub2v1 = PtVariable(
"v1",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -164,7 +167,7 @@ private fun makeSt(): SymbolTable {
)
val astSub2v2 = PtVariable(
"v2",
DataType.forDt(BaseDataType.BYTE),
DataType.BYTE,
ZeropageWish.DONTCARE,
0u,
null,
@@ -179,7 +182,7 @@ private fun makeSt(): SymbolTable {
astSub2.add(astSub2v2)
astBlock1.add(astSub1)
astBlock1.add(astSub2)
val astBfunc = PtIdentifier("msb", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val astBfunc = PtIdentifier("msb", DataType.UBYTE, Position.DUMMY)
astBlock1.add(astBfunc)
val astBlock2 = PtBlock("block2", false, SourceCode.Generated("block2"), PtBlock.Options(), Position.DUMMY)
val astSub21 = PtSub("sub1", emptyList(), emptyList(), Position.DUMMY)
@@ -202,12 +205,12 @@ private fun makeSt(): SymbolTable {
block1.add(sub12)
block1.add(StConstant("c1", BaseDataType.UWORD, 12345.0, astConstant1))
block1.add(StConstant("blockc", BaseDataType.UWORD, 999.0, astConstant2))
sub11.add(StStaticVariable("v1", DataType.forDt(BaseDataType.BYTE), null, null, null, ZeropageWish.DONTCARE, 0, astSub1v1))
sub11.add(StStaticVariable("v2", DataType.forDt(BaseDataType.BYTE), null, null, null, ZeropageWish.DONTCARE, 0, astSub1v2))
sub11.add(StMemVar("v3", DataType.forDt(BaseDataType.FLOAT), 12345u, null, astSub1v3))
sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0, astSub1v1))
sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0, astSub1v2))
sub11.add(StMemVar("v3", DataType.FLOAT, 12345u, null, astSub1v3))
sub11.add(StMemorySlab("slab1", 200u, 64u, astSub1v4))
sub12.add(StStaticVariable("v1", DataType.forDt(BaseDataType.BYTE), null, null, null, ZeropageWish.DONTCARE, 0, astSub2v1))
sub12.add(StStaticVariable("v2", DataType.forDt(BaseDataType.BYTE), null, null, null, ZeropageWish.DONTCARE, 0, astSub2v2))
sub12.add(StStaticVariable("v1", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0, astSub2v1))
sub12.add(StStaticVariable("v2", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0, astSub2v2))
val block2 = StNode("block2", StNodeType.BLOCK, astBlock2)
val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21)
val sub22 = StNode("sub2", StNodeType.SUBROUTINE, astSub22)
+4 -4
View File
@@ -805,11 +805,11 @@ main {
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = true)!!
val main = result.codegenAst!!.allBlocks().first()
val derp = main.children.single { it is PtSub && it.name=="main.derp"} as PtSub
derp.returns shouldBe listOf(DataType.forDt(BaseDataType.UWORD))
derp.parameters.single().type shouldBe DataType.forDt(BaseDataType.UWORD)
derp.returns shouldBe listOf(DataType.UWORD)
derp.parameters.single().type shouldBe DataType.UWORD
val mult3 = main.children.single { it is PtAsmSub && it.name=="main.mult3"} as PtAsmSub
mult3.parameters.single().second.type shouldBe DataType.forDt(BaseDataType.UWORD)
mult3.returns.single().second shouldBe DataType.forDt(BaseDataType.UWORD)
mult3.parameters.single().second.type shouldBe DataType.UWORD
mult3.returns.single().second shouldBe DataType.UWORD
}
test("return 0 for str converted to uword") {
+34 -34
View File
@@ -72,26 +72,26 @@ class TestC64Zeropage: FunSpec({
compTarget = c64target, loadAddress = 999u, memtopAddress = 0xffffu
))
var result = zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
var result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate("varname", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = zp.allocate("varname", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
shouldThrow<IllegalArgumentException> { zp.allocate("varname", DataType.forDt(BaseDataType.UBYTE),null, null, errors) }
result = zp.allocate("varname2", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
shouldThrow<IllegalArgumentException> { zp.allocate("varname", DataType.UBYTE,null, null, errors) }
result = zp.allocate("varname2", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
}
test("testZpFloatEnable") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), CompilationOptions.AllZeropageAllowed, false, false, false, c64target, 999u, 0xffffu))
var result = zp.allocate("", DataType.forDt(BaseDataType.FLOAT), null, null, errors)
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled floats" }
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), CompilationOptions.AllZeropageAllowed, true, false, false, c64target, 999u, 0xffffu))
result = zp2.allocate("", DataType.forDt(BaseDataType.FLOAT), null, null, errors)
result = zp2.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled ZP use" }
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), CompilationOptions.AllZeropageAllowed, true, false, false, c64target, 999u, 0xffffu))
zp3.allocate("", DataType.forDt(BaseDataType.FLOAT), null, null, errors)
zp3.allocate("", DataType.FLOAT, null, null, errors)
}
test("testZpModesWithFloats") {
@@ -113,7 +113,7 @@ class TestC64Zeropage: FunSpec({
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), CompilationOptions.AllZeropageAllowed, false, false, false, c64target, 999u, 0xffffu))
println(zp.free)
zp.availableBytes() shouldBe 0
val result = zp.allocate("", DataType.forDt(BaseDataType.BYTE), null, null, errors)
val result = zp.allocate("", DataType.BYTE, null, null, errors)
result.expectError { "expected error due to disabled ZP use" }
}
@@ -126,9 +126,9 @@ class TestC64Zeropage: FunSpec({
zp3.availableBytes() shouldBe 96
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), CompilationOptions.AllZeropageAllowed, false, false, false, c64target, 999u, 0xffffu))
zp4.availableBytes() shouldBe 207
zp4.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
zp4.allocate("test", DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 206
zp4.allocate("test2", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
zp4.allocate("test2", DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 205
}
@@ -167,19 +167,19 @@ class TestC64Zeropage: FunSpec({
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate("", DataType.forDt(BaseDataType.FLOAT), null, null, errors)
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
(0 until zp.availableBytes()).forEach {
val alloc = zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
val alloc = zp.allocate("", DataType.UBYTE, null, null, errors)
alloc.getOrElse { throw it }
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.expectError { "expected allocation error" }
result = zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors)
result = zp.allocate("", DataType.UWORD, null, null, errors)
result.expectError { "expected allocation error" }
}
@@ -188,47 +188,47 @@ class TestC64Zeropage: FunSpec({
zp.availableBytes() shouldBe 207
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors)
var result = zp.allocate("", DataType.UWORD, null, null, errors)
val loc = result.getOrElse { throw it } .address
loc shouldBeGreaterThan 3u
loc shouldNotBeIn zp.free
val num = zp.availableBytes() / 2
(0..num-3).forEach {
zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors)
zp.allocate("", DataType.UWORD, null, null, errors)
}
zp.availableBytes() shouldBe 5
// can't allocate because no more sequential bytes, only fragmented
result = zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors)
result = zp.allocate("", DataType.UWORD, null, null, errors)
result.expectError { "should give allocation error" }
(0..4).forEach {
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
zp.allocate("", DataType.UBYTE, null, null, errors)
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.expectError { "should give allocation error" }
}
test("testEfficientAllocation") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), CompilationOptions.AllZeropageAllowed, true, false, false, c64target, 999u, 0xffffu))
zp.availableBytes() shouldBe 17
zp.allocate("", DataType.forDt(BaseDataType.WORD), null, null, errors).getOrElse{throw it}.address shouldBe 0x04u
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0x06u
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0x0au
zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors).getOrElse{throw it}.address shouldBe 0x9bu
zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors).getOrElse{throw it}.address shouldBe 0x9eu
zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors).getOrElse{throw it}.address shouldBe 0xb0u
zp.allocate("", DataType.forDt(BaseDataType.UWORD), null, null, errors).getOrElse{throw it}.address shouldBe 0xbeu
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0x0eu
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0x92u
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0x96u
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0xa6u
zp.allocate("", DataType.forDt(BaseDataType.UBYTE), null, null, errors).getOrElse{throw it}.address shouldBe 0xf9u
zp.allocate("", DataType.WORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x04u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x06u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0au
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9bu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9eu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xb0u
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xbeu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0eu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x92u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x96u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0xa6u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0xf9u
zp.availableBytes() shouldBe 0
}
@@ -259,9 +259,9 @@ class TestCx16Zeropage: FunSpec({
zp2.availableBytes() shouldBe 175
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), CompilationOptions.AllZeropageAllowed, false, false, false, cx16target, 999u, 0xffffu))
zp3.availableBytes() shouldBe 216
zp3.allocate("test", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
zp3.allocate("test", DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 215
zp3.allocate("test2", DataType.forDt(BaseDataType.UBYTE), null, null, errors)
zp3.allocate("test2", DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 214
}
+10 -10
View File
@@ -758,9 +758,9 @@ class TestProg8Parser: FunSpec( {
val expr = bb2.value as BinaryExpression
println(expr)
expr.operator shouldBe "or"
expr.left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.UBYTE)
expr.right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.UWORD)
expr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.BOOL)
expr.left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE
expr.right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
expr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
}
test("inferred type for typecasted expressions with logical operators") {
@@ -783,16 +783,16 @@ class TestProg8Parser: FunSpec( {
val zz = (stmts[3] as VarDecl).value as BinaryExpression
val bb2 = (stmts[4] as VarDecl).value as BinaryExpression
val zz2 = (stmts[5] as VarDecl).value as BinaryExpression
qq.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.UWORD)
zz.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.BOOL)
bb2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.BOOL)
qq.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
zz.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
bb2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
zz2.operator shouldBe "or"
val left = zz2.left as TypecastExpression
val right = zz2.right as PrefixExpression
left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.UWORD)
right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.BOOL)
zz2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.BOOL)
left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
zz2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
}
test("type cast from byte to ubyte as desired target type") {
@@ -807,7 +807,7 @@ class TestProg8Parser: FunSpec( {
val stmts = (module.statements.single() as Block).statements
stmts.size shouldBe 2
val ubexpr = (stmts[1] as VarDecl).value as TypecastExpression
ubexpr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.forDt(BaseDataType.UBYTE)
ubexpr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE
}
test("assignment isAugmented correctness") {
+6 -6
View File
@@ -11,28 +11,28 @@ import prog8.code.core.Position
class TestSimplifiedAst: FunSpec({
test("isSame on binaryExpressions") {
val expr1 = PtBinaryExpression("/", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr1 = PtBinaryExpression("/", DataType.UBYTE, Position.DUMMY)
expr1.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
expr1.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
val expr2 = PtBinaryExpression("/", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr2 = PtBinaryExpression("/", DataType.UBYTE, Position.DUMMY)
expr2.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
expr2.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
(expr1 isSameAs expr2) shouldBe true
val expr3 = PtBinaryExpression("/", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr3 = PtBinaryExpression("/", DataType.UBYTE, Position.DUMMY)
expr3.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
expr3.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
(expr1 isSameAs expr3) shouldBe false
}
test("isSame on binaryExpressions with associative operators") {
val expr1 = PtBinaryExpression("+", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr1 = PtBinaryExpression("+", DataType.UBYTE, Position.DUMMY)
expr1.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
expr1.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
val expr2 = PtBinaryExpression("+", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr2 = PtBinaryExpression("+", DataType.UBYTE, Position.DUMMY)
expr2.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
expr2.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
(expr1 isSameAs expr2) shouldBe true
val expr3 = PtBinaryExpression("+", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val expr3 = PtBinaryExpression("+", DataType.UBYTE, Position.DUMMY)
expr3.add(PtNumber(BaseDataType.UBYTE, 2.0, Position.DUMMY))
expr3.add(PtNumber(BaseDataType.UBYTE, 1.0, Position.DUMMY))
(expr1 isSameAs expr3) shouldBe true
+2 -2
View File
@@ -41,10 +41,10 @@ class TestSubroutines: FunSpec({
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
asmfunc.isAsmSubroutine shouldBe true
asmfunc.parameters.single().type shouldBe DataType.forDt(BaseDataType.STR)
asmfunc.parameters.single().type shouldBe DataType.STR
asmfunc.statements.isEmpty() shouldBe true
func.isAsmSubroutine shouldBe false
func.parameters.single().type shouldBe DataType.forDt(BaseDataType.STR)
func.parameters.single().type shouldBe DataType.STR
func.statements.isEmpty() shouldBe true
}
@@ -875,6 +875,13 @@ main {
}
test("datatype consistencies") {
DataType.UNDEFINED.isUndefined shouldBe true
DataType.LONG.isLong shouldBe true
DataType.WORD.isWord shouldBe true
DataType.UWORD.isWord shouldBe true
DataType.BYTE.isByte shouldBe true
DataType.UBYTE.isByte shouldBe true
DataType.forDt(BaseDataType.UNDEFINED).isUndefined shouldBe true
DataType.forDt(BaseDataType.LONG).isLong shouldBe true
DataType.forDt(BaseDataType.WORD).isWord shouldBe true
@@ -50,9 +50,9 @@ class TestAsmGenSymbols: StringSpec({
}
*/
val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UWORD), ZeropageWish.DONTCARE,
val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "localvar", emptyList(), null, false, 0u, false, Position.DUMMY)
val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UWORD), ZeropageWish.DONTCARE,
val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "tgt", emptyList(), null, false, 0u, false, Position.DUMMY)
val labelInSub = Label("locallabel", Position.DUMMY)
@@ -69,7 +69,7 @@ class TestAsmGenSymbols: StringSpec({
val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8)
val subroutine = Subroutine("start", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY)
val labelInBlock = Label("label_outside", Position.DUMMY)
val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UWORD), ZeropageWish.DONTCARE,
val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "var_outside", emptyList(),null, false, 0u, false, Position.DUMMY)
val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY)
@@ -159,8 +159,8 @@ main {
asmgen.asmSymbolName("prog8_lib.P8ZP_SCRATCH_W2") shouldBe "P8ZP_SCRATCH_W2"
asmgen.asmSymbolName(listOf("prog8_lib","P8ZP_SCRATCH_REG")) shouldBe "P8ZP_SCRATCH_REG"
asmgen.asmSymbolName(listOf("prog8_lib","P8ZP_SCRATCH_W2")) shouldBe "P8ZP_SCRATCH_W2"
val id1 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_REG", DataType.forDt(BaseDataType.UBYTE), Position.DUMMY)
val id2 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD), Position.DUMMY)
val id1 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_REG", DataType.UBYTE, Position.DUMMY)
val id2 = PtIdentifier("prog8_lib.P8ZP_SCRATCH_W2", DataType.UWORD, Position.DUMMY)
id1.parent = PtProgram("test", DummyMemsizer, DummyStringEncoder)
id2.parent = PtProgram("test", DummyMemsizer, DummyStringEncoder)
asmgen.asmSymbolName(id1) shouldBe "P8ZP_SCRATCH_REG"
+1 -1
View File
@@ -87,7 +87,7 @@ class Program(val name: String,
fun addNewInternedStringvar(string: StringLiteral): Pair<List<String>, VarDecl> {
val varName = "string_${internedStringsBlock.statements.size}"
val decl = VarDecl(
VarDeclType.VAR, VarDeclOrigin.STRINGLITERAL, DataType.forDt(BaseDataType.STR), ZeropageWish.NOT_IN_ZEROPAGE,
VarDeclType.VAR, VarDeclOrigin.STRINGLITERAL, DataType.STR, ZeropageWish.NOT_IN_ZEROPAGE,
SplitWish.DONTCARE, null, varName, emptyList(), string,
sharedWithAsm = false, alignment = 0u, dirty = false, position = string.position
)
@@ -1,15 +1,11 @@
package prog8.ast.expressions
import prog8.ast.ExpressionError
import prog8.ast.FatalAstException
import prog8.ast.IFunctionCall
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import prog8.code.INTERNED_STRINGS_MODULENAME
import prog8.code.core.*
import prog8.code.target.encodings.JapaneseCharacterConverter
import java.io.CharConversionException
import java.util.*
@@ -201,17 +197,17 @@ class BinaryExpression(
try {
val dt = InferredTypes.knownFor(
commonDatatype(
leftDt.getOr(DataType.forDt(BaseDataType.BYTE)),
rightDt.getOr(DataType.forDt(BaseDataType.BYTE)),
leftDt.getOr(DataType.BYTE),
rightDt.getOr(DataType.BYTE),
null, null
).first
)
if(operator=="*") {
// if both operands are the same, X*X is always positive.
if(left isSameAs right) {
if(dt istype DataType.forDt(BaseDataType.BYTE))
if(dt istype DataType.BYTE)
InferredTypes.knownFor(BaseDataType.UBYTE)
else if(dt istype DataType.forDt(BaseDataType.WORD))
else if(dt istype DataType.WORD)
InferredTypes.knownFor(BaseDataType.UWORD)
else
dt
@@ -225,9 +221,9 @@ class BinaryExpression(
}
}
"&", "|", "^" -> when(leftDt.getOrUndef()) {
DataType.forDt(BaseDataType.BYTE) -> InferredTypes.knownFor(BaseDataType.UBYTE)
DataType.forDt(BaseDataType.WORD) -> InferredTypes.knownFor(BaseDataType.UWORD)
DataType.forDt(BaseDataType.BOOL) -> InferredTypes.knownFor(BaseDataType.UBYTE)
DataType.BYTE -> InferredTypes.knownFor(BaseDataType.UBYTE)
DataType.WORD -> InferredTypes.knownFor(BaseDataType.UWORD)
DataType.BOOL -> InferredTypes.knownFor(BaseDataType.UBYTE)
else -> leftDt
}
"and", "or", "xor", "not", "in", "not in",
@@ -245,7 +241,7 @@ class BinaryExpression(
left: Expression?, right: Expression?): Pair<DataType, Expression?> {
if(leftDt.isUndefined || rightDt.isUndefined)
return DataType.forDt(BaseDataType.UNDEFINED) to null
return DataType.UNDEFINED to null
// byte + byte -> byte
// byte + word -> word
@@ -275,52 +271,52 @@ class BinaryExpression(
return when (leftDt.base) {
BaseDataType.BOOL -> {
return if(rightDt.isBool)
Pair(DataType.forDt(BaseDataType.BOOL), null)
Pair(DataType.BOOL, null)
else
Pair(DataType.forDt(BaseDataType.BOOL), right)
Pair(DataType.BOOL, right)
}
BaseDataType.UBYTE -> {
when (rightDt.base) {
BaseDataType.UBYTE -> Pair(DataType.forDt(BaseDataType.UBYTE), null)
BaseDataType.BYTE -> Pair(DataType.forDt(BaseDataType.BYTE), left)
BaseDataType.UWORD -> Pair(DataType.forDt(BaseDataType.UWORD), left)
BaseDataType.WORD -> Pair(DataType.forDt(BaseDataType.WORD), left)
BaseDataType.FLOAT -> Pair(DataType.forDt(BaseDataType.FLOAT), left)
BaseDataType.UBYTE -> Pair(DataType.UBYTE, null)
BaseDataType.BYTE -> Pair(DataType.BYTE, left)
BaseDataType.UWORD -> Pair(DataType.UWORD, left)
BaseDataType.WORD -> Pair(DataType.WORD, left)
BaseDataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> Pair(leftDt, null) // non-numeric datatype
}
}
BaseDataType.BYTE -> {
when (rightDt.base) {
BaseDataType.UBYTE -> Pair(DataType.forDt(BaseDataType.BYTE), right)
BaseDataType.BYTE -> Pair(DataType.forDt(BaseDataType.BYTE), null)
BaseDataType.UWORD -> Pair(DataType.forDt(BaseDataType.WORD), left)
BaseDataType.WORD -> Pair(DataType.forDt(BaseDataType.WORD), left)
BaseDataType.FLOAT -> Pair(DataType.forDt(BaseDataType.FLOAT), left)
BaseDataType.UBYTE -> Pair(DataType.BYTE, right)
BaseDataType.BYTE -> Pair(DataType.BYTE, null)
BaseDataType.UWORD -> Pair(DataType.WORD, left)
BaseDataType.WORD -> Pair(DataType.WORD, left)
BaseDataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> Pair(leftDt, null) // non-numeric datatype
}
}
BaseDataType.UWORD -> {
when (rightDt.base) {
BaseDataType.UBYTE -> Pair(DataType.forDt(BaseDataType.UWORD), right)
BaseDataType.BYTE -> Pair(DataType.forDt(BaseDataType.WORD), right)
BaseDataType.UWORD -> Pair(DataType.forDt(BaseDataType.UWORD), null)
BaseDataType.WORD -> Pair(DataType.forDt(BaseDataType.WORD), left)
BaseDataType.FLOAT -> Pair(DataType.forDt(BaseDataType.FLOAT), left)
BaseDataType.UBYTE -> Pair(DataType.UWORD, right)
BaseDataType.BYTE -> Pair(DataType.WORD, right)
BaseDataType.UWORD -> Pair(DataType.UWORD, null)
BaseDataType.WORD -> Pair(DataType.WORD, left)
BaseDataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> Pair(leftDt, null) // non-numeric datatype
}
}
BaseDataType.WORD -> {
when (rightDt.base) {
BaseDataType.UBYTE -> Pair(DataType.forDt(BaseDataType.WORD), right)
BaseDataType.BYTE -> Pair(DataType.forDt(BaseDataType.WORD), right)
BaseDataType.UWORD -> Pair(DataType.forDt(BaseDataType.WORD), right)
BaseDataType.WORD -> Pair(DataType.forDt(BaseDataType.WORD), null)
BaseDataType.FLOAT -> Pair(DataType.forDt(BaseDataType.FLOAT), left)
BaseDataType.UBYTE -> Pair(DataType.WORD, right)
BaseDataType.BYTE -> Pair(DataType.WORD, right)
BaseDataType.UWORD -> Pair(DataType.WORD, right)
BaseDataType.WORD -> Pair(DataType.WORD, null)
BaseDataType.FLOAT -> Pair(DataType.FLOAT, left)
else -> Pair(leftDt, null) // non-numeric datatype
}
}
BaseDataType.FLOAT -> {
Pair(DataType.forDt(BaseDataType.FLOAT), right)
Pair(DataType.FLOAT, right)
}
else -> Pair(leftDt, null) // non-numeric datatype
}
@@ -995,19 +991,19 @@ class ArrayLiteral(val type: InferredTypes.InferredType, // inferred because
return InferredTypes.InferredType.unknown()
val dts = datatypesInArray.map { it.getOrUndef() }
return when {
dts.any { it.isFloat } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.FLOAT).elementToArray())
dts.any { it.isString } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.UWORD).elementToArray())
dts.any { it.isSignedWord } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.WORD).elementToArray())
dts.any { it.isUnsignedWord } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.UWORD).elementToArray())
dts.any { it.isSignedByte } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.BYTE).elementToArray())
dts.any { it.isFloat } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.FLOAT))
dts.any { it.isString } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.UWORD))
dts.any { it.isSignedWord } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.WORD))
dts.any { it.isUnsignedWord } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.UWORD))
dts.any { it.isSignedByte } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.BYTE))
dts.any { it.isBool } -> {
if(dts.all { it.isBool})
InferredTypes.InferredType.known(DataType.forDt(BaseDataType.BOOL).elementToArray())
InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.BOOL))
else
InferredTypes.InferredType.unknown()
}
dts.any { it.isUnsignedByte } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.UBYTE).elementToArray())
dts.any { it.isArray } -> InferredTypes.InferredType.known(DataType.forDt(BaseDataType.UWORD).elementToArray())
dts.any { it.isUnsignedByte } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.UBYTE))
dts.any { it.isArray } -> InferredTypes.InferredType.known(DataType.arrayFor(BaseDataType.UWORD))
else -> InferredTypes.InferredType.unknown()
}
}
@@ -1105,11 +1101,11 @@ class RangeExpression(var from: Expression,
val toDt=to.inferType(program)
return when {
!fromDt.isKnown || !toDt.isKnown -> InferredTypes.unknown()
fromDt istype DataType.forDt(BaseDataType.UBYTE) && toDt istype DataType.forDt(BaseDataType.UBYTE) -> InferredTypes.knownFor(DataType.forDt(BaseDataType.UBYTE).elementToArray())
fromDt istype DataType.forDt(BaseDataType.UWORD) && toDt istype DataType.forDt(BaseDataType.UWORD) -> InferredTypes.knownFor(DataType.forDt(BaseDataType.UWORD).elementToArray())
fromDt istype DataType.forDt(BaseDataType.STR) && toDt istype DataType.forDt(BaseDataType.STR) -> InferredTypes.knownFor(BaseDataType.STR)
fromDt istype DataType.forDt(BaseDataType.WORD) || toDt istype DataType.forDt(BaseDataType.WORD) -> InferredTypes.knownFor(DataType.forDt(BaseDataType.WORD).elementToArray())
fromDt istype DataType.forDt(BaseDataType.BYTE) || toDt istype DataType.forDt(BaseDataType.BYTE) -> InferredTypes.knownFor(DataType.forDt(BaseDataType.BYTE).elementToArray())
fromDt istype DataType.UBYTE && toDt istype DataType.UBYTE -> InferredTypes.knownFor(DataType.arrayFor(BaseDataType.UBYTE))
fromDt istype DataType.UWORD && toDt istype DataType.UWORD -> InferredTypes.knownFor(DataType.arrayFor(BaseDataType.UWORD))
fromDt istype DataType.STR && toDt istype DataType.STR -> InferredTypes.knownFor(BaseDataType.STR)
fromDt istype DataType.WORD || toDt istype DataType.WORD -> InferredTypes.knownFor(DataType.arrayFor(BaseDataType.WORD))
fromDt istype DataType.BYTE || toDt istype DataType.BYTE -> InferredTypes.knownFor(DataType.arrayFor(BaseDataType.BYTE))
else -> {
val fdt = fromDt.getOrUndef()
val tdt = toDt.getOrUndef()
@@ -13,7 +13,7 @@ object InferredTypes {
val isKnown get() = datatype!=null && !datatype.isUndefined
fun getOr(default: DataType) = if(isUnknown || isVoid) default else datatype!!
fun getOrUndef() = if(isUnknown || isVoid) DataType.forDt(BaseDataType.UNDEFINED) else datatype!!
fun getOrUndef() = if(isUnknown || isVoid) DataType.UNDEFINED else datatype!!
fun getOrElse(transform: (InferredType) -> DataType): DataType =
if(isUnknown || isVoid) transform(this) else datatype!!
infix fun istype(type: DataType): Boolean = if(isUnknown || isVoid) false else this.datatype==type // strict equality if known
@@ -271,7 +271,7 @@ class VarDecl(val type: VarDeclType,
decltype = VarDeclType.MEMORY
value = AddressOf(IdentifierReference(regname, param.position), null, false, param.position)
}
val dt = if(param.type.isArray) DataType.forDt(BaseDataType.UWORD) else param.type
val dt = if(param.type.isArray) DataType.UWORD else param.type
return VarDecl(decltype, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, SplitWish.DONTCARE, null, param.name, emptyList(), value,
sharedWithAsm = false,
alignment = 0u,
@@ -556,13 +556,13 @@ class IRFileReader {
}
} else {
return when(type) {
"bool" -> DataType.forDt(BaseDataType.BOOL)
"byte" -> DataType.forDt(BaseDataType.BYTE)
"ubyte" -> DataType.forDt(BaseDataType.UBYTE)
"word" -> DataType.forDt(BaseDataType.WORD)
"uword" -> DataType.forDt(BaseDataType.UWORD)
"float" -> DataType.forDt(BaseDataType.FLOAT)
"long" -> DataType.forDt(BaseDataType.LONG)
"bool" -> DataType.BOOL
"byte" -> DataType.BYTE
"ubyte" -> DataType.UBYTE
"word" -> DataType.WORD
"uword" -> DataType.UWORD
"float" -> DataType.FLOAT
"long" -> DataType.LONG
// note: 'str' should not occur anymore in IR. Should be 'uword'
else -> throw IRParseException("invalid dt $type")
}
+4 -4
View File
@@ -23,10 +23,10 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
if(options.compTarget.name != VMTarget.NAME) {
listOf(
PtMemMapped("P8ZP_SCRATCH_B1", DataType.forDt(BaseDataType.UBYTE), options.compTarget.zeropage.SCRATCH_B1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_REG", DataType.forDt(BaseDataType.UBYTE), options.compTarget.zeropage.SCRATCH_REG, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W1", DataType.forDt(BaseDataType.UWORD), options.compTarget.zeropage.SCRATCH_W1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W2", DataType.forDt(BaseDataType.UWORD), options.compTarget.zeropage.SCRATCH_W2, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_B1", DataType.UBYTE, options.compTarget.zeropage.SCRATCH_B1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_REG", DataType.UBYTE, options.compTarget.zeropage.SCRATCH_REG, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W1", DataType.UWORD, options.compTarget.zeropage.SCRATCH_W1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W2", DataType.UWORD, options.compTarget.zeropage.SCRATCH_W2, null, Position.DUMMY),
).forEach {
it.parent = program
st.add(StMemVar(it.name, it.type, it.address, it.arraySize?.toInt(), it))
@@ -137,7 +137,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
*/
}
class PtAddressOf(position: Position, val isMsbForSplitArray: Boolean=false) : PtExpression(DataType.forDt(BaseDataType.UWORD), position) {
class PtAddressOf(position: Position, val isMsbForSplitArray: Boolean=false) : PtExpression(DataType.UWORD, position) {
val identifier: PtIdentifier
get() = children[0] as PtIdentifier
val arrayIndexExpr: PtExpression?
@@ -216,7 +216,7 @@ class PtIfExpression(type: DataType, position: Position): PtExpression(type, pos
}
class PtContainmentCheck(position: Position): PtExpression(DataType.forDt(BaseDataType.BOOL), position) {
class PtContainmentCheck(position: Position): PtExpression(DataType.BOOL, position) {
val needle: PtExpression
get() = children[0] as PtExpression
val haystackHeapVar: PtIdentifier?
@@ -256,13 +256,13 @@ class PtIdentifier(val name: String, type: DataType, position: Position) : PtExp
}
class PtMemoryByte(position: Position) : PtExpression(DataType.forDt(BaseDataType.UBYTE), position) {
class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position) {
val address: PtExpression
get() = children.single() as PtExpression
}
class PtBool(val value: Boolean, position: Position) : PtExpression(DataType.forDt(BaseDataType.BOOL), position) {
class PtBool(val value: Boolean, position: Position) : PtExpression(DataType.BOOL, position) {
override fun hashCode(): Int = Objects.hash(type, value)
override fun equals(other: Any?): Boolean {
@@ -366,7 +366,7 @@ class PtRange(type: DataType, position: Position) : PtExpression(type, position)
}
class PtString(val value: String, val encoding: Encoding, position: Position) : PtExpression(DataType.forDt(BaseDataType.STR), position) {
class PtString(val value: String, val encoding: Encoding, position: Position) : PtExpression(DataType.STR, position) {
override fun hashCode(): Int = Objects.hash(value, encoding)
override fun equals(other: Any?): Boolean {
if(other==null || other !is PtString)
@@ -59,7 +59,7 @@ private fun optimizeAssignTargets(program: PtProgram, st: SymbolTable): Int {
if(node.children.dropLast(1).all { (it as PtAssignTarget).void }) {
// all targets are now void, the whole assignment can be discarded and replaced by just a (void) call to the subroutine
val index = node.parent.children.indexOf(node)
val voidCall = PtFunctionCall(functionName, true, DataType.forDt(BaseDataType.UNDEFINED), value.position)
val voidCall = PtFunctionCall(functionName, true, DataType.UNDEFINED, value.position)
value.children.forEach { voidCall.add(it) }
node.parent.children[index] = voidCall
voidCall.parent = node.parent