mirror of
https://github.com/irmen/prog8.git
synced 2024-11-01 15:07:10 +00:00
cleaner return type
This commit is contained in:
parent
4f7465ba44
commit
367a2a4cee
@ -555,13 +555,14 @@ internal class AsmGen(private val program: Program,
|
|||||||
internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
||||||
|
|
||||||
|
|
||||||
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> {
|
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): String {
|
||||||
// returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary)
|
// returns the source name of the zero page pointervar if it's already in the ZP,
|
||||||
|
// otherwise returns "P8ZP_SCRATCH_W1" which is the intermediary
|
||||||
when (val target = pointervar.targetStatement(program)) {
|
when (val target = pointervar.targetStatement(program)) {
|
||||||
is Label -> {
|
is Label -> {
|
||||||
val sourceName = asmSymbolName(pointervar)
|
val sourceName = asmSymbolName(pointervar)
|
||||||
out(" lda $sourceName")
|
out(" lda $sourceName")
|
||||||
return Pair(true, sourceName)
|
return sourceName
|
||||||
}
|
}
|
||||||
is VarDecl -> {
|
is VarDecl -> {
|
||||||
val sourceName = asmVariableName(pointervar)
|
val sourceName = asmVariableName(pointervar)
|
||||||
@ -570,7 +571,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
return if (isZpVar(scopedName)) {
|
return if (isZpVar(scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" lda ($sourceName)")
|
out(" lda ($sourceName)")
|
||||||
Pair(true, sourceName)
|
sourceName
|
||||||
} else {
|
} else {
|
||||||
out("""
|
out("""
|
||||||
lda $sourceName
|
lda $sourceName
|
||||||
@ -578,13 +579,13 @@ internal class AsmGen(private val program: Program,
|
|||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda (P8ZP_SCRATCH_W1)""")
|
lda (P8ZP_SCRATCH_W1)""")
|
||||||
Pair(false, sourceName)
|
"P8ZP_SCRATCH_W1"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return if (isZpVar(scopedName)) {
|
return if (isZpVar(scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" ldy #0 | lda ($sourceName),y")
|
out(" ldy #0 | lda ($sourceName),y")
|
||||||
Pair(true, sourceName)
|
sourceName
|
||||||
} else {
|
} else {
|
||||||
out("""
|
out("""
|
||||||
lda $sourceName
|
lda $sourceName
|
||||||
@ -593,7 +594,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (P8ZP_SCRATCH_W1),y""")
|
lda (P8ZP_SCRATCH_W1),y""")
|
||||||
Pair(false, sourceName)
|
"P8ZP_SCRATCH_W1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun inplaceModification_byte_value_to_pointer(pointervar: IdentifierReference, operator: String, value: Expression) {
|
private fun inplaceModification_byte_value_to_pointer(pointervar: IdentifierReference, operator: String, value: Expression) {
|
||||||
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
"+" -> asmgen.out(" clc | adc P8ZP_SCRATCH_B1")
|
||||||
@ -324,15 +323,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
if(ptrOnZp)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_variable_to_pointer(pointervar: IdentifierReference, operator: String, value: IdentifierReference) {
|
private fun inplaceModification_byte_variable_to_pointer(pointervar: IdentifierReference, operator: String, value: IdentifierReference) {
|
||||||
val otherName = asmgen.asmVariableName(value)
|
val otherName = asmgen.asmVariableName(value)
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
|
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
@ -364,105 +361,72 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"^", "xor" -> asmgen.out(" eor $otherName")
|
"^", "xor" -> asmgen.out(" eor $otherName")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_byte_litval_to_pointer(pointervar: IdentifierReference, operator: String, value: Int) {
|
private fun inplaceModification_byte_litval_to_pointer(pointervar: IdentifierReference, operator: String, value: Int) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" clc | adc #$value")
|
asmgen.out(" clc | adc #$value")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" sec | sbc #$value")
|
asmgen.out(" sec | sbc #$value")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"*" -> {
|
"*" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
if(value in asmgen.optimizedByteMultiplications)
|
if(value in asmgen.optimizedByteMultiplications)
|
||||||
asmgen.out(" jsr math.mul_byte_${value}")
|
asmgen.out(" jsr math.mul_byte_${value}")
|
||||||
else
|
else
|
||||||
asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0")
|
asmgen.out(" ldy #$value | jsr math.multiply_bytes | ldy #0")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"/" -> {
|
"/" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
if(value==0)
|
if(value==0)
|
||||||
throw AssemblyError("division by zero")
|
throw AssemblyError("division by zero")
|
||||||
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0")
|
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | tya | ldy #0")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"%" -> {
|
"%" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
if(value==0)
|
if(value==0)
|
||||||
throw AssemblyError("division by zero")
|
throw AssemblyError("division by zero")
|
||||||
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0")
|
asmgen.out(" ldy #$value | jsr math.divmod_ub_asm | ldy #0")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
repeat(value) { asmgen.out(" asl a") }
|
repeat(value) { asmgen.out(" asl a") }
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
repeat(value) { asmgen.out(" lsr a") }
|
repeat(value) { asmgen.out(" lsr a") }
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&", "and" -> {
|
"&", "and" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" and #$value")
|
asmgen.out(" and #$value")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"|", "or" -> {
|
"|", "or" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" ora #$value")
|
asmgen.out(" ora #$value")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
"^", "xor" -> {
|
"^", "xor" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" eor #$value")
|
asmgen.out(" eor #$value")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -1766,15 +1730,12 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta $addr""")
|
sta $addr""")
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(mem.addressExpression as IdentifierReference)
|
val sourceName = asmgen.loadByteFromPointerIntoA(mem.addressExpression as IdentifierReference)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
beq +
|
beq +
|
||||||
lda #1
|
lda #1
|
||||||
+ eor #1""")
|
+ eor #1""")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
||||||
@ -1837,12 +1798,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta $addr""")
|
sta $addr""")
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(memory.addressExpression as IdentifierReference)
|
val sourceName = asmgen.loadByteFromPointerIntoA(memory.addressExpression as IdentifierReference)
|
||||||
asmgen.out(" eor #255")
|
asmgen.out(" eor #255")
|
||||||
if(ptrOnZp)
|
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.assignExpressionToVariable(memory.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
asmgen.assignExpressionToVariable(memory.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope)
|
||||||
|
Loading…
Reference in New Issue
Block a user