code cleanups, pointer TODOs, docs dark mode

This commit is contained in:
Irmen de Jong
2025-08-16 11:25:18 +02:00
parent 2f60716082
commit 4a8d5def84
32 changed files with 212 additions and 208 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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!!

View File

@@ -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

View File

@@ -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()

View File

@@ -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")
}
}
}

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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 -> {

View File

@@ -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

View File

@@ -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()}")

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -1,3 +1,4 @@
sphinx>7.0.0
sphinx_rtd_theme>=1.2
sphinx_rtd_dark_mode
sphinxcontrib-jquery

View File

@@ -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']

View File

@@ -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?

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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 &&

View File

@@ -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
}
}

View File

@@ -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)
}

View File

@@ -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)
}