fix for certain invalid expression evaluation code.

it no longer reuses the same temporary variable all the time.

todo
This commit is contained in:
Irmen de Jong 2024-01-30 23:47:40 +01:00
parent 48ef856c0b
commit ef198f1493
5 changed files with 65 additions and 34 deletions

View File

@ -356,15 +356,20 @@ class AsmGen6502Internal (
name
}
internal val tempVarsCounters = mutableMapOf(
DataType.BYTE to 0,
DataType.UBYTE to 0,
DataType.WORD to 0,
DataType.UWORD to 0,
DataType.FLOAT to 0
)
internal fun buildTempVarName(dt: DataType, counter: Int): String = "prog8_tmpvar_${dt.toString().lowercase()}_$counter"
internal fun getTempVarName(dt: DataType): String {
return when(dt) {
DataType.UBYTE -> "cx16.r9L"
DataType.BYTE -> "cx16.r9sL"
DataType.UWORD -> "cx16.r9"
DataType.WORD -> "cx16.r9s"
DataType.FLOAT -> "floats.floats_temp_var"
else -> throw AssemblyError("invalid dt")
}
tempVarsCounters[dt] = tempVarsCounters.getValue(dt)+1
return buildTempVarName(dt, tempVarsCounters.getValue(dt))
}
internal fun loadByteFromPointerIntoA(pointervar: PtIdentifier): String {

View File

@ -49,6 +49,7 @@ internal class ProgramAndVarsGen(
}
memorySlabs()
tempVars()
footer()
}
}
@ -165,6 +166,26 @@ internal class ProgramAndVarsGen(
}
}
private fun tempVars() {
asmgen.out("; expression temp vars\n .section BSS")
for((dt, count) in asmgen.tempVarsCounters) {
if(count>0) {
for(num in 1..count) {
val name = asmgen.buildTempVarName(dt, num)
when (dt) {
DataType.BYTE -> asmgen.out("$name .char ?")
DataType.UBYTE -> asmgen.out("$name .byte ?")
DataType.WORD -> asmgen.out("$name .sint ?")
DataType.UWORD -> asmgen.out("$name .word ?")
DataType.FLOAT -> asmgen.out("$name .fill ${options.compTarget.machine.FLOAT_MEM_SIZE}")
else -> throw AssemblyError("weird dt for extravar $dt")
}
}
}
}
asmgen.out(" .send BSS")
}
private fun footer() {
var relocateBssVars = false
var relocateBssSlabs = false

View File

@ -191,13 +191,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.out(" ldx P8ZP_SCRATCH_B1")
}
SourceStorageKind.EXPRESSION -> {
TODO("safe evaluation of sub-expression at ${value.expression!!.position} - in the meantime, split up the expression in multiple statements")
// asmgen.out(" sta P8ZP_SCRATCH_B1")
// if(value.expression is PtTypeCast)
// inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression)
// else
// inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", DataType.UBYTE, operator, value.expression!!)
// asmgen.out(" ldx P8ZP_SCRATCH_B1")
val tempVar = asmgen.getTempVarName(DataType.UBYTE)
asmgen.out(" sta $tempVar")
if(value.expression is PtTypeCast)
inplacemodificationByteVariableWithValue(tempVar, DataType.UBYTE, operator, value.expression)
else
inplacemodificationByteVariableWithValue(tempVar, DataType.UBYTE, operator, value.expression!!)
asmgen.out(" ldx $tempVar")
}
}
asmgen.restoreRegisterStack(CpuRegister.Y, false)
@ -326,14 +326,14 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
SourceStorageKind.EXPRESSION -> {
TODO("safe evaluation of sub-expression at ${value.expression!!.position} - in the meantime, split up the expression in multiple statements")
// asmgen.out(" sta P8ZP_SCRATCH_B1")
// if(value.expression is PtTypeCast)
// inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression)
// else
// inplacemodificationByteVariableWithValue("P8ZP_SCRATCH_B1", target.datatype, operator, value.expression!!)
// asmgen.restoreRegisterStack(CpuRegister.Y, false)
// asmgen.out(" lda P8ZP_SCRATCH_B1")
val tempVar = asmgen.getTempVarName(DataType.UBYTE)
asmgen.out(" sta $tempVar")
if(value.expression is PtTypeCast)
inplacemodificationByteVariableWithValue(tempVar, target.datatype, operator, value.expression)
else
inplacemodificationByteVariableWithValue(tempVar, target.datatype, operator, value.expression!!)
asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.out(" lda $tempVar")
}
}
asmgen.out(" sta ${target.array.variable.name},y")
@ -401,13 +401,13 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
SourceStorageKind.EXPRESSION -> {
TODO("safe evaluation of sub-expression at ${value.expression!!.position} - in the meantime, split up the expression in multiple statements")
// asmgen.out(" sta P8ZP_SCRATCH_W1 | stx P8ZP_SCRATCH_W1+1")
// if(value.expression is PtTypeCast)
// inplacemodificationWordWithValue("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression, block)
// else
// inplacemodificationWordWithValue("P8ZP_SCRATCH_W1", target.datatype, operator, value.expression!!, block)
// asmgen.out(" lda P8ZP_SCRATCH_W1 | ldx P8ZP_SCRATCH_W1+1")
val tempVar = asmgen.getTempVarName(DataType.UWORD)
asmgen.out(" sta $tempVar | stx $tempVar+1")
if(value.expression is PtTypeCast)
inplacemodificationWordWithValue(tempVar, target.datatype, operator, value.expression, block)
else
inplacemodificationWordWithValue(tempVar, target.datatype, operator, value.expression!!, block)
asmgen.out(" lda $tempVar | ldx $tempVar+1")
}
}
asmgen.restoreRegisterStack(CpuRegister.Y, true)

View File

@ -1,7 +1,7 @@
TODO
====
fix "safe evaluation of sub-expression" (byte and word, in AugmentableAssignmentAsmGen).
fix "return <stmt>" not being an error.
maze: if cell & UP!=0 and @(celladdr(cx,cy-1)) & (WALKED|BACKTRACKED) ==0

View File

@ -1,5 +1,5 @@
%import textio
%import test_stack
;; %import test_stack
%zeropage basicsafe
%option no_sysinit
@ -9,8 +9,13 @@ main {
ubyte @shared j
uword @shared aa = 1
sub derp() {
return aa=5
}
sub start() {
test_stack.test()
derp()
;; test_stack.test()
j = 1
a[j] = 1
b[j] = 0
@ -32,7 +37,7 @@ main {
b[j] += 5 * a[j]
txt.print_uw(b[j]) ; 60
txt.nl()
test_stack.test()
;; test_stack.test()
}
}