mirror of
https://github.com/irmen/prog8.git
synced 2024-09-29 08:57:51 +00:00
fix variable node casting
This commit is contained in:
parent
4914609485
commit
75d486b124
@ -103,7 +103,7 @@ fun printAst(root: PtNode, output: (text: String) -> Unit) {
|
|||||||
else
|
else
|
||||||
"${node.type.name.lowercase()} ${node.name}"
|
"${node.type.name.lowercase()} ${node.name}"
|
||||||
if(node.value!=null)
|
if(node.value!=null)
|
||||||
str + " = " + txt(node.value!!)
|
str + " = " + txt(node.value)
|
||||||
else
|
else
|
||||||
str
|
str
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
override fun printProperties() {
|
||||||
print("$type $name")
|
print("$type $name")
|
||||||
}
|
}
|
||||||
|
@ -581,7 +581,7 @@ class AsmGen(
|
|||||||
}
|
}
|
||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val symbol = symbolTable.lookup((stmt.count as PtIdentifier).name)
|
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)
|
val name = asmVariableName(stmt.count as PtIdentifier)
|
||||||
when(vardecl.type) {
|
when(vardecl.type) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
|
@ -353,9 +353,13 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
val variable = fcall.args.single()
|
val variable = fcall.args.single()
|
||||||
if (variable is PtIdentifier) {
|
if (variable is PtIdentifier) {
|
||||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
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 varName = asmgen.asmVariableName(variable)
|
||||||
val numElements = decl.arraySize!!
|
|
||||||
when (decl.type) {
|
when (decl.type) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -393,9 +397,13 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
val variable = fcall.args.single()
|
val variable = fcall.args.single()
|
||||||
if (variable is PtIdentifier) {
|
if (variable is PtIdentifier) {
|
||||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
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 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) {
|
when (decl.type) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -1014,17 +1022,19 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
// address in P8ZP_SCRATCH_W1, number of elements in A
|
// address in P8ZP_SCRATCH_W1, number of elements in A
|
||||||
arg as PtIdentifier
|
arg as PtIdentifier
|
||||||
val symbol = asmgen.symbolTable.lookup(arg.name)
|
val symbol = asmgen.symbolTable.lookup(arg.name)
|
||||||
val arrayVar = symbol!!.astNode as PtVariable
|
val arrayVar = symbol!!.astNode as IPtVariable
|
||||||
if(arrayVar.arraySize==null)
|
val numElements = when(arrayVar) {
|
||||||
throw AssemblyError("length of non-array requested")
|
is PtConstant -> null
|
||||||
val size = arrayVar.arraySize!!
|
is PtMemMapped -> arrayVar.arraySize
|
||||||
|
is PtVariable -> arrayVar.arraySize
|
||||||
|
} ?: throw AssemblyError("length of non-array requested")
|
||||||
val identifierName = asmgen.asmVariableName(arg)
|
val identifierName = asmgen.asmVariableName(arg)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$identifierName
|
lda #<$identifierName
|
||||||
ldy #>$identifierName
|
ldy #>$identifierName
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$size
|
lda #$numElements
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,12 @@ $endLabel""")
|
|||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
val iterableName = asmgen.asmVariableName(ident)
|
val iterableName = asmgen.asmVariableName(ident)
|
||||||
val symbol = asmgen.symbolTable.lookup(ident.name)
|
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) {
|
when(iterableDt) {
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -260,7 +265,6 @@ $loopLabel lda ${65535.toHex()} ; modified
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
val length = decl.arraySize!!
|
|
||||||
val indexVar = asmgen.makeLabel("for_index")
|
val indexVar = asmgen.makeLabel("for_index")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
@ -268,11 +272,11 @@ $loopLabel sty $indexVar
|
|||||||
lda $iterableName,y
|
lda $iterableName,y
|
||||||
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
||||||
asmgen.translate(stmt.statements)
|
asmgen.translate(stmt.statements)
|
||||||
if(length<=255u) {
|
if(numElements!!<=255u) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy $indexVar
|
ldy $indexVar
|
||||||
iny
|
iny
|
||||||
cpy #$length
|
cpy #$numElements
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
bne $loopLabel""")
|
bne $loopLabel""")
|
||||||
} else {
|
} else {
|
||||||
@ -283,7 +287,7 @@ $loopLabel sty $indexVar
|
|||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
}
|
}
|
||||||
if(length>=16u) {
|
if(numElements>=16u) {
|
||||||
// allocate index var on ZP if possible
|
// allocate index var on ZP if possible
|
||||||
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
|
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
result.fold(
|
result.fold(
|
||||||
@ -296,7 +300,7 @@ $loopLabel sty $indexVar
|
|||||||
asmgen.out(endLabel)
|
asmgen.out(endLabel)
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
val length = decl.arraySize!! * 2u
|
val length = numElements!! * 2u
|
||||||
val indexVar = asmgen.makeLabel("for_index")
|
val indexVar = asmgen.makeLabel("for_index")
|
||||||
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
@ -808,8 +808,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
private fun containmentCheckIntoA(containment: PtContainmentCheck) {
|
private fun containmentCheckIntoA(containment: PtContainmentCheck) {
|
||||||
val elementDt = containment.element.type
|
val elementDt = containment.element.type
|
||||||
val symbol = asmgen.symbolTable.lookup(containment.iterable.name)
|
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 varname = asmgen.asmVariableName(containment.iterable)
|
||||||
|
val numElements = when(variable) {
|
||||||
|
is PtConstant -> null
|
||||||
|
is PtMemMapped -> variable.arraySize
|
||||||
|
is PtVariable -> variable.arraySize
|
||||||
|
}
|
||||||
when(variable.type) {
|
when(variable.type) {
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
// use subroutine
|
// use subroutine
|
||||||
@ -817,7 +822,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!)
|
asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!)
|
||||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W1"), varname)
|
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W1"), varname)
|
||||||
asmgen.restoreRegisterLocal(CpuRegister.A)
|
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(" ldy #${stringVal.value.length}")
|
||||||
asmgen.out(" jsr prog8_lib.containment_bytearray")
|
asmgen.out(" jsr prog8_lib.containment_bytearray")
|
||||||
return
|
return
|
||||||
@ -826,7 +831,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
throw AssemblyError("containment check of floats not supported")
|
throw AssemblyError("containment check of floats not supported")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||||
val numElements = variable.arraySize!!
|
|
||||||
assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt == DataType.BYTE)
|
assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt == DataType.BYTE)
|
||||||
asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!)
|
asmgen.saveRegisterLocal(CpuRegister.A, containment.definingISub()!!)
|
||||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W1"), varname)
|
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
|
return
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
val numElements = variable.arraySize!!
|
|
||||||
assignExpressionToVariable(containment.element, "P8ZP_SCRATCH_W1", elementDt, containment.definingISub())
|
assignExpressionToVariable(containment.element, "P8ZP_SCRATCH_W1", elementDt, containment.definingISub())
|
||||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W2"), varname)
|
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), "P8ZP_SCRATCH_W2"), varname)
|
||||||
asmgen.out(" ldy #$numElements")
|
asmgen.out(" ldy #$numElements")
|
||||||
|
@ -57,7 +57,7 @@ class TestIntermediateAst: FunSpec({
|
|||||||
ccdecl.name shouldBe "cc"
|
ccdecl.name shouldBe "cc"
|
||||||
ccdecl.scopedName shouldBe "main.start.cc"
|
ccdecl.scopedName shouldBe "main.start.cc"
|
||||||
ccdecl.type shouldBe DataType.UBYTE
|
ccdecl.type shouldBe DataType.UBYTE
|
||||||
val arraydecl = entry.children[1] as PtVariable
|
val arraydecl = entry.children[1] as IPtVariable
|
||||||
arraydecl.name shouldBe "array"
|
arraydecl.name shouldBe "array"
|
||||||
arraydecl.type shouldBe DataType.ARRAY_UB
|
arraydecl.type shouldBe DataType.ARRAY_UB
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user