mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
code cleanups, pointer TODOs, docs dark mode
This commit is contained in:
@@ -9,7 +9,7 @@ import java.nio.file.Path
|
||||
|
||||
class C64Target: ICompilationTarget,
|
||||
IStringEncoding by Encoder(true),
|
||||
IMemSizer by NormalMemSizer(Mflpt5.Companion.FLOAT_MEM_SIZE) {
|
||||
IMemSizer by NormalMemSizer(Mflpt5.FLOAT_MEM_SIZE) {
|
||||
|
||||
override val name = NAME
|
||||
override val defaultEncoding = Encoding.PETSCII
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.nio.file.Path
|
||||
|
||||
class Cx16Target: ICompilationTarget,
|
||||
IStringEncoding by Encoder(true),
|
||||
IMemSizer by NormalMemSizer(Mflpt5.Companion.FLOAT_MEM_SIZE) {
|
||||
IMemSizer by NormalMemSizer(Mflpt5.FLOAT_MEM_SIZE) {
|
||||
|
||||
override val name = NAME
|
||||
override val defaultEncoding = Encoding.PETSCII
|
||||
|
||||
@@ -18,7 +18,7 @@ data class Mflpt5(val b0: UByte, val b1: UByte, val b2: UByte, val b3: UByte, va
|
||||
// and https://en.wikipedia.org/wiki/IEEE_754-1985
|
||||
|
||||
val flt = num.toDouble()
|
||||
if (flt < FLOAT_MAX_NEGATIVE || flt > FLOAT_MAX_POSITIVE)
|
||||
if (flt !in FLOAT_MAX_NEGATIVE..FLOAT_MAX_POSITIVE)
|
||||
throw InternalCompilerException("floating point number out of 5-byte mflpt range: $this")
|
||||
if (flt == 0.0)
|
||||
return zero
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.nio.file.Path
|
||||
|
||||
class PETTarget: ICompilationTarget,
|
||||
IStringEncoding by Encoder(true),
|
||||
IMemSizer by NormalMemSizer(Mflpt5.Companion.FLOAT_MEM_SIZE) {
|
||||
IMemSizer by NormalMemSizer(Mflpt5.FLOAT_MEM_SIZE) {
|
||||
|
||||
override val name = NAME
|
||||
override val defaultEncoding = Encoding.PETSCII
|
||||
|
||||
@@ -809,7 +809,7 @@ class AsmGen6502Internal (
|
||||
when {
|
||||
iterations == 0 -> {}
|
||||
iterations == 1 -> translate(stmt.statements)
|
||||
iterations<0 || iterations>65536 -> throw AssemblyError("invalid number of iterations")
|
||||
iterations !in 0..65536 -> throw AssemblyError("invalid number of iterations")
|
||||
iterations <= 256 -> repeatByteCount(iterations, stmt)
|
||||
else -> repeatWordCount(iterations, stmt)
|
||||
}
|
||||
@@ -1059,10 +1059,7 @@ $repeatLabel""")
|
||||
if(evaluateAddressExpression) {
|
||||
val arrayIdx = jump.target as? PtArrayIndexer
|
||||
if (arrayIdx!=null) {
|
||||
val arrayVariable = arrayIdx.variable
|
||||
if(arrayVariable==null)
|
||||
TODO("support for ptr indexing ${arrayIdx.position}")
|
||||
|
||||
val arrayVariable = arrayIdx.variable ?: TODO("support for ptr indexing ${arrayIdx.position}")
|
||||
if (isTargetCpu(CpuType.CPU65C02)) {
|
||||
if (!arrayIdx.splitWords) {
|
||||
// if the jump target is an address in a non-split array (like a jump table of only pointers),
|
||||
@@ -1272,9 +1269,7 @@ $repeatLabel""")
|
||||
}
|
||||
|
||||
if(addressExpr.operator=="+") {
|
||||
val ptrAndIndex = pointerViaIndexRegisterPossible(addressExpr)
|
||||
if (ptrAndIndex == null) return false
|
||||
|
||||
val ptrAndIndex = pointerViaIndexRegisterPossible(addressExpr) ?: return false
|
||||
if(write) {
|
||||
|
||||
// WRITING TO pointer + offset
|
||||
@@ -1366,9 +1361,7 @@ $repeatLabel""")
|
||||
}
|
||||
|
||||
else if(addressExpr.operator=="-") {
|
||||
val ptrAndIndex = pointerViaIndexRegisterPossible(addressExpr, true)
|
||||
if (ptrAndIndex == null) return false
|
||||
|
||||
val ptrAndIndex = pointerViaIndexRegisterPossible(addressExpr, true) ?: return false
|
||||
if(write) {
|
||||
|
||||
// WRITING TO pointer - offset
|
||||
|
||||
@@ -408,7 +408,7 @@ private fun optimizeStoreLoadSame(
|
||||
// a branch instruction follows, we can only remove the load instruction if
|
||||
// another load instruction of the same register precedes the store instruction
|
||||
// (otherwise wrong cpu flags are used)
|
||||
val loadinstruction = second.substring(0, 3)
|
||||
val loadinstruction = second.take(3)
|
||||
lines[0].value.trimStart().startsWith(loadinstruction)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -671,9 +671,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
val elementSize: Int
|
||||
val msbAdd: Int
|
||||
if(indexer.splitWords) {
|
||||
val arrayVariable = indexer.variable
|
||||
if(arrayVariable==null)
|
||||
TODO("support for ptr indexing ${indexer.position}")
|
||||
val arrayVariable = indexer.variable ?: TODO("support for ptr indexing ${indexer.position}")
|
||||
indexer.children[0] = PtIdentifier(arrayVariable.name + if(msb) "_msb" else "_lsb", DataType.arrayFor(BaseDataType.UBYTE, false), arrayVariable.position)
|
||||
indexer.children[0].parent = indexer
|
||||
elementSize = 1
|
||||
|
||||
@@ -412,7 +412,7 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("; struct types")
|
||||
symboltable.allStructInstances.distinctBy { it.structName }.forEach {
|
||||
val structtype: StStruct = symboltable.lookup(it.structName) as StStruct
|
||||
val structargs = structtype.fields.withIndex().joinToString(",") { "f${it.index}" }
|
||||
val structargs = structtype.fields.withIndex().joinToString(",") { field -> "f${field.index}" }
|
||||
asmgen.out("${it.structName} .struct $structargs\n")
|
||||
structtype.fields.withIndex().forEach { (index, field) ->
|
||||
val dt = field.first
|
||||
|
||||
@@ -148,7 +148,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
|
||||
left is PtIdentifier && left.name==scopedName
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
left is PtArrayIndexer && left isSameAs array!! && left.splitWords==array.splitWords
|
||||
left is PtArrayIndexer && left isSameAs array!! && left.splitWords==array.splitWords && (left.pointerderef==null && array.pointerderef==null || left.pointerderef!! isSameAs array.pointerderef!!)
|
||||
}
|
||||
TargetStorageKind.MEMORY -> {
|
||||
left isSameAs memory!!
|
||||
|
||||
@@ -934,20 +934,25 @@ internal class AssignmentAsmGen(
|
||||
assignTrue.add(PtNumber.fromBoolean(true, assign.position))
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val tgt = PtAssignTarget(false, assign.target.position)
|
||||
val targetarray = assign.target.array!!
|
||||
val array = PtArrayIndexer(assign.target.datatype, targetarray.position)
|
||||
|
||||
val targetArrayVar = targetarray.variable
|
||||
if(targetArrayVar==null) {
|
||||
TODO("optimized comparison on pointer ${targetarray.position}")
|
||||
val deref = assign.target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${assign.position}")
|
||||
} else {
|
||||
array.add(targetArrayVar)
|
||||
array.add(targetarray.index)
|
||||
tgt.add(array)
|
||||
assignTrue = PtAssignment(assign.position)
|
||||
assignTrue.add(tgt)
|
||||
assignTrue.add(PtNumber.fromBoolean(true, assign.position))
|
||||
val tgt = PtAssignTarget(false, assign.target.position)
|
||||
val targetarray = assign.target.array!!
|
||||
val array = PtArrayIndexer(assign.target.datatype, targetarray.position)
|
||||
|
||||
val targetArrayVar = targetarray.variable
|
||||
if (targetArrayVar == null) {
|
||||
TODO("optimized comparison on pointer ${targetarray.position}")
|
||||
} else {
|
||||
array.add(targetArrayVar)
|
||||
array.add(targetarray.index)
|
||||
tgt.add(array)
|
||||
assignTrue = PtAssignment(assign.position)
|
||||
assignTrue.add(tgt)
|
||||
assignTrue.add(PtNumber.fromBoolean(true, assign.position))
|
||||
}
|
||||
}
|
||||
}
|
||||
TargetStorageKind.POINTER -> TODO("optimized comparison for pointer-deref $expr.position")
|
||||
@@ -2308,6 +2313,11 @@ $endLabel""")
|
||||
// }
|
||||
TargetStorageKind.ARRAY -> {
|
||||
// byte to word, just assign to registers first, then assign into array
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
assignExpressionToRegister(value, RegisterOrPair.AY, targetDt.isSigned)
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
return
|
||||
@@ -2897,7 +2907,11 @@ $endLabel""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(sourceDt.isUnsignedByte) TODO("assign byte to word array")
|
||||
target.array!!
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
if(target.constArrayIndexValue!=null) {
|
||||
val scaledIdx = program.memsizer.memorySize(target.datatype, target.constArrayIndexValue!!.toInt())
|
||||
when {
|
||||
@@ -2998,7 +3012,12 @@ $endLabel""")
|
||||
jsr floats.MOVMF""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.A)
|
||||
asmgen.out("""
|
||||
ldy #<${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
@@ -3029,9 +3048,14 @@ $endLabel""")
|
||||
jsr floats.copy_float""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.out(" pha")
|
||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
||||
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A)
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.A)
|
||||
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
||||
asmgen.out(" pla")
|
||||
asmgen.out("""
|
||||
@@ -3069,6 +3093,11 @@ $endLabel""")
|
||||
jsr floats.copy_float""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A)
|
||||
asmgen.out("""
|
||||
ldy #<$sourceName
|
||||
@@ -3111,6 +3140,11 @@ $endLabel""")
|
||||
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
||||
}
|
||||
else {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
|
||||
}
|
||||
@@ -3152,6 +3186,11 @@ $endLabel""")
|
||||
+ sta ${wordtarget.asmVarname}+1""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val deref = wordtarget.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${wordtarget.position}")
|
||||
return
|
||||
}
|
||||
if(wordtarget.array!!.splitWords) {
|
||||
// signed byte, we must sign-extend
|
||||
if (wordtarget.constArrayIndexValue!=null) {
|
||||
@@ -3234,6 +3273,11 @@ $endLabel""")
|
||||
asmgen.out(" lda #0 | sta ${wordtarget.asmVarname}+1")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val deref = wordtarget.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${wordtarget.position}")
|
||||
return
|
||||
}
|
||||
if(wordtarget.array!!.splitWords) {
|
||||
if (wordtarget.constArrayIndexValue!=null) {
|
||||
val scaledIdx = wordtarget.constArrayIndexValue!!
|
||||
@@ -3521,6 +3565,11 @@ $endLabel""")
|
||||
}
|
||||
|
||||
private fun assignRegisterByteToByteArray(target: AsmAssignTarget, register: CpuRegister) {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
if(target.array!!.splitWords)
|
||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||
|
||||
@@ -3576,6 +3625,11 @@ $endLabel""")
|
||||
}
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
if(target.array!!.splitWords) {
|
||||
// assign to split lsb/msb word array
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
@@ -3756,7 +3810,12 @@ $endLabel""")
|
||||
throw AssemblyError("memory is bytes not words")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||
if(target.array.splitWords)
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
@@ -3810,7 +3869,12 @@ $endLabel""")
|
||||
throw AssemblyError("assign word to memory ${target.memory} should have gotten a typecast")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||
if(target.array.splitWords)
|
||||
asmgen.out("""
|
||||
lda #<${word.toHex()}
|
||||
@@ -3856,7 +3920,12 @@ $endLabel""")
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.array!!.splitWords)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
if(target.array.splitWords)
|
||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
val indexValue = target.constArrayIndexValue!!
|
||||
@@ -3899,12 +3968,16 @@ $endLabel""")
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
require(!target.array!!.splitWords)
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
require(!target.array.splitWords)
|
||||
if (target.constArrayIndexValue != null) {
|
||||
val indexValue = target.constArrayIndexValue!!
|
||||
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, CpuRegister.Y)
|
||||
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname},y")
|
||||
}
|
||||
@@ -3955,7 +4028,12 @@ $endLabel""")
|
||||
sta ${target.asmVarname}+4""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.A)
|
||||
asmgen.out("""
|
||||
ldy #<${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
@@ -3990,7 +4068,12 @@ $endLabel""")
|
||||
jsr floats.copy_float""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A)
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.A)
|
||||
asmgen.out("""
|
||||
ldy #<${constFloat}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
|
||||
@@ -226,11 +226,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val targetArrayVar = target.array!!.variable
|
||||
if(targetArrayVar==null) {
|
||||
TODO("array indexing on pointer ${target.position}")
|
||||
val deref = target.array!!.pointerderef
|
||||
if(deref!=null) {
|
||||
TODO("inplace modification array indexed pointer deref ${target.position}")
|
||||
return
|
||||
}
|
||||
val targetArrayVar = target.array.variable!!
|
||||
val indexNum = target.array.index as? PtNumber
|
||||
if (indexNum!=null) {
|
||||
val index = indexNum.number.toInt()
|
||||
|
||||
@@ -386,7 +386,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
require(value.datatype.isWord)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX)
|
||||
TODO("<< expression")
|
||||
}
|
||||
SourceStorageKind.REGISTER -> {
|
||||
@@ -396,7 +396,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
require(register.isWord())
|
||||
TODO("<< register")
|
||||
}
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
require(value.datatype.isWord)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX)
|
||||
TODO("<< expression")
|
||||
}
|
||||
SourceStorageKind.REGISTER -> {
|
||||
@@ -444,7 +444,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
require(register.isWord())
|
||||
TODO("<< register")
|
||||
}
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +480,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
require(value.datatype.isWord)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
clc
|
||||
@@ -507,7 +507,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
adc P8ZP_SCRATCH_W1+1
|
||||
sta ($ptrZpVar),y""")
|
||||
}
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
SourceStorageKind.VARIABLE -> TODO("variable + * float")
|
||||
SourceStorageKind.EXPRESSION -> TODO("expression + * float")
|
||||
SourceStorageKind.REGISTER -> TODO("register + * float")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
require(value.datatype.isWord)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
sec
|
||||
@@ -580,7 +580,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
sta ($ptrZpVar),y""")
|
||||
}
|
||||
SourceStorageKind.REGISTER -> TODO("register - word")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
multiply()
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> TODO("ptr * expr (word)")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,7 +677,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
TODO("inplace register word divide")
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> TODO("ptr / expr (word)")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,7 +701,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
SourceStorageKind.VARIABLE -> TODO("variable - / float")
|
||||
SourceStorageKind.EXPRESSION -> TODO("expression - / float")
|
||||
SourceStorageKind.REGISTER -> TODO("register - / float")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,14 +737,14 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
sta ($ptrZpVar),y""")
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.A, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.A)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
eor ($ptrZpVar),y
|
||||
sta ($ptrZpVar),y""")
|
||||
}
|
||||
SourceStorageKind.REGISTER -> TODO("register ^ byte")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,7 +777,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
}
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
require(value.datatype.isWord)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX, false)
|
||||
asmgen.assignExpressionToRegister(value.expression!!, RegisterOrPair.AX)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
eor ($ptrZpVar),y
|
||||
@@ -788,7 +788,7 @@ internal class PointerAssignmentsGen(private val asmgen: AsmGen6502Internal, pri
|
||||
sta ($ptrZpVar),y""")
|
||||
}
|
||||
SourceStorageKind.REGISTER -> TODO("register ^ word")
|
||||
else -> throw AssemblyError("weird source value ${value}")
|
||||
else -> throw AssemblyError("weird source value $value")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,10 +310,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
when(operator) {
|
||||
"+" -> { }
|
||||
"-" -> {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val skipCarryLabel = codeGen.createLabelName()
|
||||
if(constIndex!=null) {
|
||||
addInstr(result, IRInstruction(Opcode.NEGM, IRDataType.BYTE, labelSymbol = arrayVariableName+"_lsb", symbolOffset = constIndex), null)
|
||||
@@ -340,10 +337,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
}
|
||||
"~" -> {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
if(constIndex!=null) {
|
||||
addInstr(result, IRInstruction(Opcode.INVM, IRDataType.BYTE, labelSymbol = arrayVariableName+"_lsb", symbolOffset = constIndex), null)
|
||||
addInstr(result, IRInstruction(Opcode.INVM, IRDataType.BYTE, labelSymbol = arrayVariableName+"_msb", symbolOffset = constIndex), null)
|
||||
@@ -370,9 +364,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
when(operator) {
|
||||
"+" -> { }
|
||||
"-" -> {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
if(constIndex!=null) {
|
||||
addInstr(result, IRInstruction(Opcode.NEGM, vmDt, labelSymbol = arrayVariableName, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
@@ -386,10 +378,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
}
|
||||
"~" -> {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
if(constIndex!=null) {
|
||||
addInstr(result, IRInstruction(Opcode.INVM, vmDt, labelSymbol = arrayVariableName, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
@@ -403,10 +392,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
}
|
||||
}
|
||||
"not" -> {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val register = codeGen.registers.next(vmDt)
|
||||
if(constIndex!=null) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@@ -738,10 +724,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun operatorAndInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? {
|
||||
if(array!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
@@ -782,10 +765,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun operatorLogicalAndInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? {
|
||||
if(array!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
@@ -844,10 +824,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constValue = operand.asConstInteger()
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type, null)
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
if(array.splitWords) {
|
||||
val valueRegLsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
val valueRegMsb = codeGen.registers.next(IRDataType.BYTE)
|
||||
@@ -891,10 +868,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(array.splitWords) {
|
||||
throw AssemblyError("logical or on (split) word array should not happen")
|
||||
} else {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val valueReg = codeGen.registers.next(vmDt)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate=constValue)
|
||||
@@ -1004,10 +978,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constValue = operand.asConstInteger()
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(constValue!=1) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
val valueReg=codeGen.registers.next(eltDt)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue)
|
||||
@@ -1065,9 +1036,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
if(constValue==1) {
|
||||
addInstr(result, IRInstruction(Opcode.DECM, eltDt, labelSymbol = arrayVariableName, symbolOffset = constIndex*eltSize), null)
|
||||
@@ -1135,9 +1104,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(constIndex!=null) {
|
||||
val skip = codeGen.createLabelName()
|
||||
if(constValue==1) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val lsbReg = codeGen.registers.next(IRDataType.BYTE)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
@@ -1167,9 +1134,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
if(constValue==1) {
|
||||
addInstr(result, IRInstruction(Opcode.INCM, elementDt, labelSymbol = arrayVariableName, symbolOffset = constIndex*eltSize), null)
|
||||
@@ -1230,9 +1195,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
if(constIndex!=null) {
|
||||
val skip = codeGen.createLabelName()
|
||||
if(constValue==1) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.INCM, IRDataType.BYTE, labelSymbol = arrayVariableName+"_lsb", symbolOffset = constIndex)
|
||||
@@ -1255,9 +1218,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constValue = operand.asConstInteger()
|
||||
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
if(array.splitWords) {
|
||||
repeat(constValue) {
|
||||
@@ -1320,9 +1281,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val constValue = operand.asConstInteger()
|
||||
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
if(array.splitWords) {
|
||||
repeat(constValue) {
|
||||
@@ -1378,9 +1337,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
|
||||
private fun operatorXorInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? {
|
||||
if(array!=null) {
|
||||
val arrayVariableName = array.variable?.name
|
||||
if(arrayVariableName==null)
|
||||
TODO("support for ptr indexing ${array.position}")
|
||||
val arrayVariableName = array.variable?.name ?: TODO("support for ptr indexing ${array.position}")
|
||||
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val constIndex = array.index.asConstInteger()
|
||||
|
||||
@@ -666,9 +666,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
else {
|
||||
val targetVariable = target.variable
|
||||
if(targetVariable==null)
|
||||
TODO("support for ptr indexing ${target.position}")
|
||||
val targetVariable = target.variable ?: TODO("support for ptr indexing ${target.position}")
|
||||
|
||||
val eltSize = codeGen.program.memsizer.memorySize(target.type, null)
|
||||
val constIndex = target.index.asConstInteger()
|
||||
|
||||
@@ -69,8 +69,7 @@ class IRCodeGen(
|
||||
val initialization = (block.children.firstOrNull {
|
||||
it is PtAssignment && it.isVarInitializer && it.target.identifier?.name==variable.scopedNameString
|
||||
} as PtAssignment?)
|
||||
val initValue = initialization?.value
|
||||
when(initValue){
|
||||
when(val initValue = initialization?.value){
|
||||
is PtBool -> {
|
||||
require(initValue.asInt()!=0 || variable.zpwish!=ZeropageWish.NOT_IN_ZEROPAGE) { "non-zp variable should not be initialized with 0, it will already be zeroed as part of BSS clear, initializer=$initialization" }
|
||||
variable.setOnetimeInitNumeric(initValue.asInt().toDouble())
|
||||
@@ -1771,9 +1770,7 @@ class IRCodeGen(
|
||||
private fun isIndirectJump(jump: PtJump): Boolean {
|
||||
if(jump.target.asConstInteger()!=null)
|
||||
return false
|
||||
val identifier = jump.target as? PtIdentifier
|
||||
if(identifier==null)
|
||||
return true
|
||||
val identifier = jump.target as? PtIdentifier ?: return true
|
||||
val symbol = symbolTable.lookup(identifier.name)
|
||||
return symbol?.type==StNodeType.MEMVAR || symbol?.type==StNodeType.STATICVAR
|
||||
}
|
||||
@@ -1927,8 +1924,7 @@ class IRCodeGen(
|
||||
if(it.register==null) {
|
||||
require('.' in it.name) { "even parameter names should have been made fully scoped by now" }
|
||||
val orig = symbolTable.lookup(it.name) as? StStaticVariable
|
||||
if (orig == null)
|
||||
TODO("fix missing lookup for: ${it.name} parameter")
|
||||
?: TODO("fix missing lookup for: ${it.name} parameter")
|
||||
result += IRSubroutine.IRParam(it.name, orig.dt)
|
||||
} else {
|
||||
val reg = it.register
|
||||
|
||||
@@ -395,8 +395,7 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
||||
|
||||
val stepLiteral = iterableRange.step as? NumericLiteral
|
||||
require(loopvar.datatype.isBasic)
|
||||
val loopvarSimpleDt = loopvar.datatype.base
|
||||
when(loopvarSimpleDt) {
|
||||
when(val loopvarSimpleDt = loopvar.datatype.base) {
|
||||
BaseDataType.UBYTE -> {
|
||||
if(rangeFrom.type != BaseDataType.UBYTE) {
|
||||
// attempt to translate the iterable into ubyte values
|
||||
|
||||
@@ -139,7 +139,6 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private fun builtinLen(args: List<Expression>, position: Position, program: Program): NumericLiteral {
|
||||
// note: in some cases the length is > 255, and then we have to return a UWORD type instead of a UBYTE.
|
||||
if(args.size!=1)
|
||||
|
||||
@@ -116,7 +116,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(iterations==null) {
|
||||
errors.err("unroll needs constant number of iterations", unrollLoop.position)
|
||||
} else {
|
||||
if (iterations < 0 || iterations > 65535)
|
||||
if (iterations !in 0..65535)
|
||||
errors.err("invalid number of unrolls", unrollLoop.position)
|
||||
unrollLoop.body.statements.forEach {
|
||||
if (it !is InlineAssembly && it !is Assignment && it !is FunctionCallStatement)
|
||||
@@ -299,7 +299,7 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
} else {
|
||||
val addr = jump.target.constValue(program)?.number
|
||||
if (addr!=null && (addr<0 || addr > 65535))
|
||||
if (addr != null && addr !in 0.0..65535.0)
|
||||
errors.err("goto address must be uword", jump.position)
|
||||
|
||||
val addressDt = jump.target.inferType(program).getOrUndef()
|
||||
@@ -741,7 +741,7 @@ internal class AstChecker(private val program: Program,
|
||||
|
||||
val memAddr = assignTarget.memoryAddress?.addressExpression?.constValue(program)?.number?.toInt()
|
||||
if (memAddr != null) {
|
||||
if (memAddr < 0 || memAddr >= 65536)
|
||||
if (memAddr !in 0..<65536)
|
||||
errors.err("address out of range", assignTarget.position)
|
||||
}
|
||||
|
||||
@@ -1855,12 +1855,10 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) {
|
||||
var regname = ident.nameInSource[1].uppercase()
|
||||
val lastLetter = regname.last().lowercaseChar()
|
||||
if(lastLetter in arrayOf('l', 'h', 's')) {
|
||||
regname = regname.substring(0, regname.length - 1)
|
||||
val lastLetter2 = regname.last().lowercaseChar()
|
||||
if(lastLetter2 in arrayOf('l', 'h', 's')) {
|
||||
regname = regname.substring(0, regname.length - 1)
|
||||
if(regname.last().lowercaseChar() in arrayOf('l', 'h', 's')) {
|
||||
regname = regname.dropLast(1)
|
||||
if(regname.last().lowercaseChar() in arrayOf('l', 'h', 's')) {
|
||||
regname = regname.dropLast(1)
|
||||
}
|
||||
}
|
||||
val reg = RegisterOrPair.valueOf(regname)
|
||||
@@ -1950,13 +1948,13 @@ internal class AstChecker(private val program: Program,
|
||||
val arraysize = target.arraysize?.constIndex()
|
||||
val index = arrayIndexedExpression.indexer.constIndex()
|
||||
if (arraysize != null) {
|
||||
if (index != null && (index < 0 || index >= arraysize))
|
||||
if (index != null && index !in 0..<arraysize)
|
||||
errors.err("index out of bounds", arrayIndexedExpression.indexer.position)
|
||||
} else if (target.datatype.isString) {
|
||||
if (target.value is StringLiteral) {
|
||||
// check string lengths for non-memory mapped strings
|
||||
val stringLen = (target.value as StringLiteral).value.length
|
||||
if (index != null && (index < 0 || index >= stringLen))
|
||||
if (index != null && index !in 0..<stringLen)
|
||||
errors.err("index out of bounds", arrayIndexedExpression.indexer.position)
|
||||
}
|
||||
} else if (index != null && index < 0) {
|
||||
@@ -2315,7 +2313,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(value.type==BaseDataType.FLOAT)
|
||||
err("unsigned byte value expected instead of float; possible loss of precision")
|
||||
val number=value.number
|
||||
if (number < 0 || number > 255)
|
||||
if (number !in 0.0..255.0)
|
||||
return err("value '$number' out of range for unsigned byte")
|
||||
}
|
||||
targetDt.isSignedByte -> {
|
||||
@@ -2329,7 +2327,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(value.type==BaseDataType.FLOAT)
|
||||
err("unsigned word value expected instead of float; possible loss of precision")
|
||||
val number=value.number
|
||||
if (number < 0 || number > 65535)
|
||||
if (number !in 0.0..65535.0)
|
||||
return err("value '$number' out of range for unsigned word")
|
||||
}
|
||||
targetDt.isSignedWord -> {
|
||||
|
||||
@@ -329,7 +329,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
"%breakpoint" -> PtBreakpoint(directive.position)
|
||||
"%align" -> {
|
||||
val align = directive.args[0].int!!
|
||||
if(align<2u || align>65536u)
|
||||
if(align !in 2u..65536u)
|
||||
errors.err("invalid alignment size", directive.position)
|
||||
PtAlign(align, directive.position)
|
||||
}
|
||||
@@ -585,7 +585,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
throw FatalAstException("varbank must be a regular variable")
|
||||
val asmAddr = if(srcSub.asmAddress==null) null else {
|
||||
val constAddr = srcSub.asmAddress!!.address.constValue(program)
|
||||
if(constAddr==null) throw FatalAstException("extsub address should be a constant")
|
||||
?: throw FatalAstException("extsub address should be a constant")
|
||||
PtAsmSub.Address(srcSub.asmAddress!!.constbank, varbank, constAddr.number.toUInt())
|
||||
}
|
||||
val sub = PtAsmSub(srcSub.name,
|
||||
@@ -813,7 +813,6 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
val rightDt = expr.right.inferType(program).getOrUndef()
|
||||
|
||||
if(leftDt.isPointer && !rightDt.isPointer) {
|
||||
val resultDt = leftDt
|
||||
val structSize = leftDt.size(program.memsizer)
|
||||
val constValue = expr.right.constValue(program)
|
||||
if(constValue!=null) {
|
||||
@@ -822,7 +821,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
if (total == 0.0)
|
||||
return transformExpression(expr.left)
|
||||
else {
|
||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||
val plusorminus = PtBinaryExpression(operator, leftDt, expr.position)
|
||||
plusorminus.add(transformExpression(expr.left))
|
||||
plusorminus.add(PtNumber(BaseDataType.UWORD, total, expr.position))
|
||||
return plusorminus
|
||||
@@ -848,14 +847,13 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
offset.add(transformExpression(expr.right))
|
||||
offset.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
||||
}
|
||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||
val plusorminus = PtBinaryExpression(operator, leftDt, expr.position)
|
||||
plusorminus.add(transformExpression(expr.left))
|
||||
plusorminus.add(offset)
|
||||
return plusorminus
|
||||
}
|
||||
}
|
||||
} else if(!leftDt.isPointer && rightDt.isPointer) {
|
||||
val resultDt = rightDt
|
||||
val structSize = rightDt.size(program.memsizer)
|
||||
val constValue = expr.left.constValue(program)
|
||||
if(constValue!=null) {
|
||||
@@ -864,7 +862,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
if (total == 0.0)
|
||||
return transformExpression(expr.right)
|
||||
else {
|
||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||
val plusorminus = PtBinaryExpression(operator, rightDt, expr.position)
|
||||
plusorminus.add(transformExpression(expr.right))
|
||||
plusorminus.add(PtNumber(BaseDataType.UWORD, total, expr.position))
|
||||
return plusorminus
|
||||
@@ -890,7 +888,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
offset.add(transformExpression(expr.left))
|
||||
offset.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
||||
}
|
||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||
val plusorminus = PtBinaryExpression(operator, rightDt, expr.position)
|
||||
plusorminus.add(offset)
|
||||
plusorminus.add(transformExpression(expr.right))
|
||||
return plusorminus
|
||||
|
||||
@@ -449,8 +449,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
||||
}
|
||||
|
||||
override fun visitInlineasm(ctx: InlineasmContext): InlineAssembly {
|
||||
val type = ctx.directivename().UNICODEDNAME().text
|
||||
val isIR = when(type) {
|
||||
val isIR = when(val type = ctx.directivename().UNICODEDNAME().text) {
|
||||
"asm" -> false
|
||||
"ir" -> true
|
||||
else -> throw SyntaxError("unknown inline asm type $type", ctx.toPosition())
|
||||
@@ -611,8 +610,7 @@ class Antlr2KotlinVisitor(val source: SourceCode): AbstractParseTreeVisitor<Node
|
||||
}
|
||||
|
||||
override fun visitPointerDereferenceTarget(ctx: PointerDereferenceTargetContext): AssignTarget {
|
||||
val deref = ctx.pointerdereference().accept(this)
|
||||
return when (deref) {
|
||||
return when (val deref = ctx.pointerdereference().accept(this)) {
|
||||
is PtrDereference -> AssignTarget(null, null, null, null, false, pointerDereference = deref, position = deref.position)
|
||||
is ArrayIndexedPtrDereference -> AssignTarget(null, null, null, null, false, arrayIndexedDereference = deref, position = deref.position)
|
||||
else -> throw FatalAstException("weird dereference ${ctx.toPosition()}")
|
||||
|
||||
@@ -564,9 +564,7 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
|
||||
|
||||
val targetAsmAddress = (target as? Subroutine)?.asmAddress
|
||||
if (targetAsmAddress != null) {
|
||||
val constAddress = targetAsmAddress.address.constValue(program)
|
||||
if (constAddress == null)
|
||||
return null
|
||||
val constAddress = targetAsmAddress.address.constValue(program) ?: return null
|
||||
return NumericLiteral(BaseDataType.UWORD, constAddress.number, position)
|
||||
}
|
||||
return null
|
||||
@@ -860,35 +858,35 @@ class NumericLiteral(val type: BaseDataType, // only numerical types allowed
|
||||
BaseDataType.FLOAT -> {
|
||||
try {
|
||||
when (targettype) {
|
||||
BaseDataType.BYTE if number >= -128 && number <= 127 -> {
|
||||
BaseDataType.BYTE if number in -128.0..127.0 -> {
|
||||
val converted = number.toInt().toByte().toDouble()
|
||||
return if(implicit && converted!=number)
|
||||
ValueAfterCast(false, "refused truncating of float to avoid loss of precision", this)
|
||||
else
|
||||
ValueAfterCast(true, null, NumericLiteral(targettype, converted, position))
|
||||
}
|
||||
BaseDataType.UBYTE if number >= 0 && number <= 255 -> {
|
||||
BaseDataType.UBYTE if number in 0.0..255.0 -> {
|
||||
val converted = number.toInt().toUByte().toDouble()
|
||||
return if(implicit && converted!=number)
|
||||
ValueAfterCast(false, "refused truncating of float to avoid loss of precision", this)
|
||||
else
|
||||
ValueAfterCast(true, null, NumericLiteral(targettype, converted, position))
|
||||
}
|
||||
BaseDataType.WORD if number >= -32768 && number <= 32767 -> {
|
||||
BaseDataType.WORD if number >= -32768.0 && number <= 32767.0 -> {
|
||||
val converted = number.toInt().toShort().toDouble()
|
||||
return if(implicit && converted!=number)
|
||||
ValueAfterCast(false, "refused truncating of float to avoid loss of precision", this)
|
||||
else
|
||||
ValueAfterCast(true, null, NumericLiteral(targettype, converted, position))
|
||||
}
|
||||
BaseDataType.UWORD if number >= 0 && number <= 65535 -> {
|
||||
BaseDataType.UWORD if number in 0.0..65535.0 -> {
|
||||
val converted = number.toInt().toUShort().toDouble()
|
||||
return if(implicit && converted!=number)
|
||||
ValueAfterCast(false, "refused truncating of float to avoid loss of precision", this)
|
||||
else
|
||||
ValueAfterCast(true, null, NumericLiteral(targettype, converted, position))
|
||||
}
|
||||
BaseDataType.LONG if number >=0 && number <= 2147483647 -> {
|
||||
BaseDataType.LONG if number in 0.0..2.147483647E9 -> {
|
||||
val converted = number.toInt().toDouble()
|
||||
return if(implicit && converted!=number)
|
||||
ValueAfterCast(false, "refused truncating of float to avoid loss of precision", this)
|
||||
@@ -1684,10 +1682,7 @@ class PtrDereference(
|
||||
|
||||
fun resultType(dt: DataType?) = if(dt==null) InferredTypes.unknown() else InferredTypes.knownFor(if(derefLast) dt.dereference() else dt)
|
||||
|
||||
val target = definingScope.lookup(chain)
|
||||
if(target==null)
|
||||
return InferredTypes.unknown()
|
||||
|
||||
val target = definingScope.lookup(chain) ?: return InferredTypes.unknown()
|
||||
if(target is VarDecl)
|
||||
return resultType(target.datatype)
|
||||
if(target is StructFieldRef)
|
||||
|
||||
@@ -432,7 +432,7 @@ abstract class AstWalker {
|
||||
|
||||
fun visit(returnStmt: Return, parent: Node) {
|
||||
track(before(returnStmt, parent), returnStmt, parent)
|
||||
returnStmt.values.forEach { it -> it.accept(this, returnStmt) }
|
||||
returnStmt.values.forEach { it.accept(this, returnStmt) }
|
||||
track(after(returnStmt, parent), returnStmt, parent)
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ interface IAstVisitor {
|
||||
}
|
||||
|
||||
fun visit(returnStmt: Return) {
|
||||
returnStmt.values.forEach { it->it.accept(this) }
|
||||
returnStmt.values.forEach { it.accept(this) }
|
||||
}
|
||||
|
||||
fun visit(arrayIndexedExpression: ArrayIndexedExpression) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
sphinx>7.0.0
|
||||
sphinx_rtd_theme>=1.2
|
||||
sphinx_rtd_dark_mode
|
||||
sphinxcontrib-jquery
|
||||
|
||||
@@ -52,7 +52,10 @@ needs_sphinx = '5.3'
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [ 'sphinxcontrib.jquery']
|
||||
extensions = [ 'sphinxcontrib.jquery', 'sphinx_rtd_dark_mode']
|
||||
|
||||
# user starts in light mode
|
||||
default_dark_mode = False
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -5,10 +5,10 @@ TODO
|
||||
STRUCTS and TYPED POINTERS (6502 codegen specific)
|
||||
--------------------------------------------------
|
||||
|
||||
- fix struct and field name prefixing errors
|
||||
- 6502 codegen should warn about writing to initialized struct instances when using romable code, like with arrays "can only be used as read-only in ROMable code"
|
||||
- 6502 asm symbol name prefixing should work for dereferences and structs too.
|
||||
- update structpointers.rst docs with 6502 specific things?
|
||||
- scan through 6502 library modules to change untyped uword pointers to typed pointers
|
||||
- scan through 6502 examples to change untyped uword pointers to typed pointers
|
||||
- fix code size regressions (if any)
|
||||
- fix all the "array indexed pointer deref" todo's
|
||||
- fix code size regressions (if any left)
|
||||
- update structpointers.rst docs with 6502 specific things?
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
%option enable_floats
|
||||
%zeropage dontuse
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
struct List {
|
||||
uword s
|
||||
bool b
|
||||
float f
|
||||
^^ubyte p
|
||||
uword n
|
||||
}
|
||||
struct Node {
|
||||
uword value
|
||||
^^Node next
|
||||
}
|
||||
^^List l1 = List()
|
||||
^^List l2 = List(1234,true,9.876,50000)
|
||||
^^Node n1 = Node()
|
||||
^^Node n2 = Node(1234, 50000)
|
||||
cx16.r0 = l1
|
||||
cx16.r1 = l2
|
||||
cx16.r0 = n1
|
||||
cx16.r1 = n2
|
||||
;l.s[2] = 42
|
||||
|
||||
^^List l = List()
|
||||
l.s[2] = 42
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,14 +243,14 @@ class IRFileReader {
|
||||
val name = match.groups["name"]!!.value
|
||||
val value = match.groups["value"]!!.value
|
||||
val zpwish = match.groups["zp"]!!.value
|
||||
val split = match.groups["split"]?.value ?: ""
|
||||
val splitStr = match.groups["split"]?.value ?: ""
|
||||
val alignment = match.groups["align"]?.value ?: ""
|
||||
if('.' !in name)
|
||||
throw IRParseException("unscoped varname: $name")
|
||||
val arraysize = if(arrayspec.isNotBlank()) arrayspec.substring(1, arrayspec.length-1).toUInt() else null
|
||||
val dt = parseDatatype(type, arraysize!=null)
|
||||
val zp = if(zpwish.isBlank()) ZeropageWish.DONTCARE else ZeropageWish.valueOf(zpwish)
|
||||
if(split.isBlank()) false else split.toBoolean()
|
||||
val split = if(splitStr.isBlank()) false else splitStr.toBoolean()
|
||||
val align = if(alignment.isBlank()) 0u else alignment.toUInt()
|
||||
val dirty = false // these variables have initialization values.
|
||||
var initNumeric: Double? = null
|
||||
|
||||
@@ -298,7 +298,7 @@ class StStruct(
|
||||
throw NoSuchElementException("field $name not found in struct ${this.name}")
|
||||
}
|
||||
|
||||
override fun getFieldType(name: String): DataType? = fields.first { it.second == name }.first
|
||||
override fun getFieldType(name: String): DataType? = fields.firstOrNull { it.second == name }?.first
|
||||
|
||||
override fun memsize(sizer: IMemSizer): Int = size.toInt()
|
||||
override fun sameas(other: ISubType): Boolean = other is StStruct &&
|
||||
|
||||
@@ -20,6 +20,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||
}
|
||||
|
||||
infix fun isSameAs(other: PtExpression): Boolean {
|
||||
// TOOD replace this by == operator?
|
||||
return when(this) {
|
||||
is PtAddressOf -> {
|
||||
if(other !is PtAddressOf)
|
||||
@@ -81,6 +82,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
|
||||
is PtPrefix -> other is PtPrefix && other.type==type && other.operator==operator && other.value isSameAs value
|
||||
is PtRange -> other is PtRange && other.type==type && other.from==from && other.to==to && other.step==step
|
||||
is PtTypeCast -> other is PtTypeCast && other.type==type && other.value isSameAs value
|
||||
is PtPointerDeref -> other is PtPointerDeref && other.type==type && other.derefLast==derefLast && startpointer isSameAs other.startpointer
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,17 +59,17 @@ class GraphicsWindow(val pixelWidth: Int, val pixelHeight: Int, val pixelScaling
|
||||
}
|
||||
|
||||
fun plot(x: Int, y: Int, color: Int) {
|
||||
if(x<0 || x>=pixelWidth)
|
||||
if(x !in 0..<pixelWidth)
|
||||
throw IllegalArgumentException("plot x outside of screen: $x")
|
||||
if(y<0 || y>=pixelHeight)
|
||||
if(y !in 0..<pixelHeight)
|
||||
throw IllegalArgumentException("plot y outside of screen: $y")
|
||||
image.setRGB(x, y, Color(color, color, color, 255).rgb)
|
||||
}
|
||||
|
||||
fun getpixel(x: Int, y: Int): Int {
|
||||
if(x<0 || x>=pixelWidth)
|
||||
if(x !in 0..<pixelWidth)
|
||||
throw IllegalArgumentException("getpixel x outside of screen: $x")
|
||||
if(y<0 || y>=pixelHeight)
|
||||
if(y !in 0..<pixelHeight)
|
||||
throw IllegalArgumentException("getpixel y outside of screen: $y")
|
||||
return image.getRGB(x, y)
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ object SysCalls {
|
||||
var input = readln()
|
||||
val maxlenvalue = (maxlen as UByte).toInt()
|
||||
if(maxlenvalue>0)
|
||||
input = input.substring(0, min(input.length, maxlenvalue))
|
||||
input = input.take(min(input.length, maxlenvalue))
|
||||
vm.memory.setString((address as UShort).toInt(), input, true)
|
||||
returnValue(callspec.returns.single(), input.length, vm)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user