diff --git a/codeCore/src/prog8/code/ast/AstPrinter.kt b/codeCore/src/prog8/code/ast/AstPrinter.kt index 1444aa416..d8b8717da 100644 --- a/codeCore/src/prog8/code/ast/AstPrinter.kt +++ b/codeCore/src/prog8/code/ast/AstPrinter.kt @@ -103,7 +103,7 @@ fun printAst(root: PtNode, output: (text: String) -> Unit) { else "${node.type.name.lowercase()} ${node.name}" if(node.value!=null) - str + " = " + txt(node.value!!) + str + " = " + txt(node.value) else str } diff --git a/codeCore/src/prog8/code/ast/AstStatements.kt b/codeCore/src/prog8/code/ast/AstStatements.kt index ae5e94af5..9e4b23a71 100644 --- a/codeCore/src/prog8/code/ast/AstStatements.kt +++ b/codeCore/src/prog8/code/ast/AstStatements.kt @@ -203,7 +203,7 @@ sealed interface IPtVariable { } -class PtVariable(name: String, override val type: DataType, val zeropage: ZeropageWish, var value: PtExpression?, var arraySize: UInt?, position: Position) : PtNamedNode(name, position), IPtVariable { +class PtVariable(name: String, override val type: DataType, val zeropage: ZeropageWish, val value: PtExpression?, val arraySize: UInt?, position: Position) : PtNamedNode(name, position), IPtVariable { override fun printProperties() { print("$type $name") } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index de6990b26..964d9c016 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -581,7 +581,7 @@ class AsmGen( } is PtIdentifier -> { val symbol = symbolTable.lookup((stmt.count as PtIdentifier).name) - val vardecl = symbol!!.astNode as PtVariable + val vardecl = symbol!!.astNode as IPtVariable val name = asmVariableName(stmt.count as PtIdentifier) when(vardecl.type) { DataType.UBYTE, DataType.BYTE -> { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 50586bc3f..7b2ce86fd 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -353,9 +353,13 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val variable = fcall.args.single() if (variable is PtIdentifier) { val symbol = asmgen.symbolTable.lookup(variable.name) - val decl = symbol!!.astNode as PtVariable + val decl = symbol!!.astNode as IPtVariable + val numElements = when(decl) { + is PtConstant -> throw AssemblyError("cannot reverse a constant") + is PtMemMapped -> decl.arraySize + is PtVariable -> decl.arraySize + } val varName = asmgen.asmVariableName(variable) - val numElements = decl.arraySize!! when (decl.type) { DataType.ARRAY_UB, DataType.ARRAY_B -> { asmgen.out(""" @@ -393,9 +397,13 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, val variable = fcall.args.single() if (variable is PtIdentifier) { val symbol = asmgen.symbolTable.lookup(variable.name) - val decl = symbol!!.astNode as PtVariable + val decl = symbol!!.astNode as IPtVariable val varName = asmgen.asmVariableName(variable) - val numElements = decl.arraySize!! + val numElements = when(decl) { + is PtConstant -> throw AssemblyError("cannot sort a constant") + is PtMemMapped -> decl.arraySize + is PtVariable -> decl.arraySize + } when (decl.type) { DataType.ARRAY_UB, DataType.ARRAY_B -> { asmgen.out(""" @@ -1014,17 +1022,19 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, // address in P8ZP_SCRATCH_W1, number of elements in A arg as PtIdentifier val symbol = asmgen.symbolTable.lookup(arg.name) - val arrayVar = symbol!!.astNode as PtVariable - if(arrayVar.arraySize==null) - throw AssemblyError("length of non-array requested") - val size = arrayVar.arraySize!! + val arrayVar = symbol!!.astNode as IPtVariable + val numElements = when(arrayVar) { + is PtConstant -> null + is PtMemMapped -> arrayVar.arraySize + is PtVariable -> arrayVar.arraySize + } ?: throw AssemblyError("length of non-array requested") val identifierName = asmgen.asmVariableName(arg) asmgen.out(""" lda #<$identifierName ldy #>$identifierName sta P8ZP_SCRATCH_W1 sty P8ZP_SCRATCH_W1+1 - lda #$size + lda #$numElements """) } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt index 59bf011b2..aacf1cf51 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ForLoopsAsmGen.kt @@ -240,7 +240,12 @@ $endLabel""") asmgen.loopEndLabels.push(endLabel) val iterableName = asmgen.asmVariableName(ident) val symbol = asmgen.symbolTable.lookup(ident.name) - val decl = symbol!!.astNode as PtVariable + val decl = symbol!!.astNode as IPtVariable + val numElements = when(decl) { + is PtConstant -> throw AssemblyError("length of non-array requested") + is PtMemMapped -> decl.arraySize + is PtVariable -> decl.arraySize + } when(iterableDt) { DataType.STR -> { asmgen.out(""" @@ -260,7 +265,6 @@ $loopLabel lda ${65535.toHex()} ; modified $endLabel""") } DataType.ARRAY_UB, DataType.ARRAY_B -> { - val length = decl.arraySize!! val indexVar = asmgen.makeLabel("for_index") asmgen.out(""" ldy #0 @@ -268,11 +272,11 @@ $loopLabel sty $indexVar lda $iterableName,y sta ${asmgen.asmVariableName(stmt.variable)}""") asmgen.translate(stmt.statements) - if(length<=255u) { + if(numElements!!<=255u) { asmgen.out(""" ldy $indexVar iny - cpy #$length + cpy #$numElements beq $endLabel bne $loopLabel""") } else { @@ -283,7 +287,7 @@ $loopLabel sty $indexVar bne $loopLabel beq $endLabel""") } - if(length>=16u) { + if(numElements>=16u) { // allocate index var on ZP if possible val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors) result.fold( @@ -296,7 +300,7 @@ $loopLabel sty $indexVar asmgen.out(endLabel) } DataType.ARRAY_W, DataType.ARRAY_UW -> { - val length = decl.arraySize!! * 2u + val length = numElements!! * 2u val indexVar = asmgen.makeLabel("for_index") val loopvarName = asmgen.asmVariableName(stmt.variable) asmgen.out(""" diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 14c328e97..0d4c210a1 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -808,8 +808,13 @@ internal class AssignmentAsmGen(private val program: PtProgram, private fun containmentCheckIntoA(containment: PtContainmentCheck) { val elementDt = containment.element.type val symbol = asmgen.symbolTable.lookup(containment.iterable.name) - val variable = symbol!!.astNode as PtVariable + val variable = symbol!!.astNode as IPtVariable val varname = asmgen.asmVariableName(containment.iterable) + val numElements = when(variable) { + is PtConstant -> null + is PtMemMapped -> variable.arraySize + is PtVariable -> variable.arraySize + } when(variable.type) { DataType.STR -> { // use subroutine @@ -817,7 +822,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!) assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W1"), varname) asmgen.restoreRegisterLocal(CpuRegister.A) - val stringVal = variable.value as PtString + val stringVal = (variable as PtVariable).value as PtString asmgen.out(" ldy #${stringVal.value.length}") asmgen.out(" jsr prog8_lib.containment_bytearray") return @@ -826,7 +831,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, throw AssemblyError("containment check of floats not supported") } DataType.ARRAY_B, DataType.ARRAY_UB -> { - val numElements = variable.arraySize!! assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt == DataType.BYTE) asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!) assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W1"), varname) @@ -836,7 +840,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, return } DataType.ARRAY_W, DataType.ARRAY_UW -> { - val numElements = variable.arraySize!! assignExpressionToVariable(containment.element, "P8ZP_SCRATCH_W1", elementDt, containment.definingISub()) assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W2"), varname) asmgen.out(" ldy #$numElements") diff --git a/compiler/test/ast/TestIntermediateAst.kt b/compiler/test/ast/TestIntermediateAst.kt index 729c5400a..26fa1a91c 100644 --- a/compiler/test/ast/TestIntermediateAst.kt +++ b/compiler/test/ast/TestIntermediateAst.kt @@ -57,7 +57,7 @@ class TestIntermediateAst: FunSpec({ ccdecl.name shouldBe "cc" ccdecl.scopedName shouldBe "main.start.cc" ccdecl.type shouldBe DataType.UBYTE - val arraydecl = entry.children[1] as PtVariable + val arraydecl = entry.children[1] as IPtVariable arraydecl.name shouldBe "array" arraydecl.type shouldBe DataType.ARRAY_UB