prog8/compilerAst/src/prog8/ast/Extensions.kt

59 lines
2.4 KiB
Kotlin

package prog8.ast
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.InferredTypes
import prog8.ast.statements.VarDecl
import prog8.ast.statements.VarDeclOrigin
import prog8.ast.statements.VarDeclType
import prog8.ast.statements.ZeropageWish
import prog8.code.core.DataType
import prog8.code.core.Position
fun Program.getTempVar(dt: DataType, altNames: Boolean=false): Pair<List<String>, VarDecl> {
val tmpvarName = if(altNames) {
when (dt) {
DataType.UBYTE -> listOf("prog8_lib", "tempvar_ub2")
DataType.BYTE -> listOf("prog8_lib", "tempvar_b2")
DataType.UWORD -> listOf("prog8_lib", "tempvar_uw2")
DataType.WORD -> listOf("prog8_lib", "tempvar_w2")
DataType.FLOAT -> listOf("floats", "tempvar_swap_float2")
else -> throw FatalAstException("invalid dt")
}
} else {
when (dt) {
DataType.UBYTE -> listOf("prog8_lib", "tempvar_ub")
DataType.BYTE -> listOf("prog8_lib", "tempvar_b")
DataType.UWORD -> listOf("prog8_lib", "tempvar_uw")
DataType.WORD -> listOf("prog8_lib", "tempvar_w")
DataType.FLOAT -> listOf("floats", "tempvar_swap_float")
else -> throw FatalAstException("invalid dt")
}
}
val block = this.allBlocks.first { it.name==tmpvarName[0] }
val existingDecl = block.statements.firstOrNull { it is VarDecl && it.name == tmpvarName[1] }
if(existingDecl!=null)
return Pair(tmpvarName, existingDecl as VarDecl)
// add new temp variable to the ast directly (we can do this here because we're not iterating inside those container blocks)
val decl = VarDecl(
VarDeclType.VAR, VarDeclOrigin.AUTOGENERATED, dt, ZeropageWish.DONTCARE,
null, tmpvarName[1], null, false, false, null, Position.DUMMY)
block.statements.add(decl)
decl.linkParents(block)
return Pair(tmpvarName, decl)
}
fun getTempRegisterName(dt: InferredTypes.InferredType): List<String> {
return when {
// TODO assume (hope) cx16.r9 isn't used for anything else during the use of this temporary variable...
dt istype DataType.UBYTE -> listOf("cx16", "r9L")
dt istype DataType.BYTE -> listOf("cx16", "r9sL")
dt istype DataType.UWORD -> listOf("cx16", "r9")
dt istype DataType.WORD -> listOf("cx16", "r9s")
dt.isPassByReference -> listOf("cx16", "r9")
else -> throw FatalAstException("invalid dt $dt")
}
}