mirror of
https://github.com/irmen/prog8.git
synced 2026-04-26 05:17:54 +00:00
easier datatype notation by just using the type objects directly
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
+12
-12
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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>()
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user