fix variable node casting

This commit is contained in:
Irmen de Jong 2023-02-12 17:04:58 +01:00
parent 4914609485
commit 75d486b124
7 changed files with 40 additions and 23 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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