move some utility methods into Pt Ast nodes itself

This commit is contained in:
Irmen de Jong 2023-02-16 22:45:35 +01:00
parent 3cce985f03
commit aaf375a57b
9 changed files with 91 additions and 91 deletions

View File

@ -66,12 +66,6 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
StSub(node.name, params, node.returntype, node)
}
is PtVariable -> {
val bss = when (node.type) {
// TODO should bss be a computed property on PtVariable?
DataType.STR -> false
in ArrayDatatypes -> node.value==null || node.arraySize==0u
else -> node.value==null
}
val initialNumeric: Double?
val initialString: StString?
val initialArray: StArray?
@ -103,7 +97,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
initialString = null
numElements = node.arraySize?.toInt()
}
StStaticVariable(node.name, node.type, bss, initialNumeric, initialString, initialArray, numElements, node.zeropage, node)
StStaticVariable(node.name, node.type, node.bss, initialNumeric, initialString, initialArray, numElements, node.zeropage, node)
}
is PtBuiltinFunctionCall -> {
if(node.name=="memory") {

View File

@ -2,6 +2,7 @@ package prog8.code.ast
import prog8.code.core.*
import java.util.*
import kotlin.math.abs
import kotlin.math.round
@ -52,6 +53,54 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
else -> false
}
}
fun asConstInteger(): Int? = (this as? PtNumber)?.number?.toInt()
fun isSimple(): Boolean {
return when(this) {
is PtAddressOf -> true
is PtArray -> true
is PtArrayIndexer -> index is PtNumber || index is PtIdentifier
is PtBinaryExpression -> false
is PtBuiltinFunctionCall -> name in arrayOf("msb", "lsb", "peek", "peekw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd")
is PtContainmentCheck -> false
is PtFunctionCall -> false
is PtIdentifier -> true
is PtMachineRegister -> true
is PtMemoryByte -> address is PtNumber || address is PtIdentifier
is PtNumber -> true
is PtPrefix -> value.isSimple()
is PtRange -> true
is PtString -> true
is PtTypeCast -> value.isSimple()
}
}
/*
fun clone(): PtExpression {
fun withClonedChildrenFrom(orig: PtExpression, clone: PtExpression): PtExpression {
orig.children.forEach { clone.add((it as PtExpression).clone()) }
return clone
}
when(this) {
is PtAddressOf -> return withClonedChildrenFrom(this, PtAddressOf(position))
is PtArray -> return withClonedChildrenFrom(this, PtArray(type, position))
is PtArrayIndexer -> return withClonedChildrenFrom(this, PtArrayIndexer(type, position))
is PtBinaryExpression -> return withClonedChildrenFrom(this, PtBinaryExpression(operator, type, position))
is PtBuiltinFunctionCall -> return withClonedChildrenFrom(this, PtBuiltinFunctionCall(name, void, hasNoSideEffects, type, position))
is PtContainmentCheck -> return withClonedChildrenFrom(this, PtContainmentCheck(position))
is PtFunctionCall -> return withClonedChildrenFrom(this, PtFunctionCall(name, void, type, position))
is PtIdentifier -> return withClonedChildrenFrom(this, PtIdentifier(name, type, position))
is PtMachineRegister -> return withClonedChildrenFrom(this, PtMachineRegister(register, type, position))
is PtMemoryByte -> return withClonedChildrenFrom(this, PtMemoryByte(position))
is PtNumber -> return withClonedChildrenFrom(this, PtNumber(type, number, position))
is PtPrefix -> return withClonedChildrenFrom(this, PtPrefix(operator, type, position))
is PtRange -> return withClonedChildrenFrom(this, PtRange(type, position))
is PtString -> return withClonedChildrenFrom(this, PtString(value, encoding, position))
is PtTypeCast -> return withClonedChildrenFrom(this, PtTypeCast(type, position))
}
}
*/
}
class PtAddressOf(position: Position) : PtExpression(DataType.UWORD, position) {
@ -187,6 +236,33 @@ class PtRange(type: DataType, position: Position) : PtExpression(type, position)
get() = children[1] as PtExpression
val step: PtNumber
get() = children[2] as PtNumber
fun toConstantIntegerRange(): IntProgression? {
fun makeRange(fromVal: Int, toVal: Int, stepVal: Int): IntProgression {
return when {
fromVal <= toVal -> when {
stepVal <= 0 -> IntRange.EMPTY
stepVal == 1 -> fromVal..toVal
else -> fromVal..toVal step stepVal
}
else -> when {
stepVal >= 0 -> IntRange.EMPTY
stepVal == -1 -> fromVal downTo toVal
else -> fromVal downTo toVal step abs(stepVal)
}
}
}
val fromLv = from as? PtNumber
val toLv = to as? PtNumber
val stepLv = step as? PtNumber
if(fromLv==null || toLv==null || stepLv==null)
return null
val fromVal = fromLv.number.toInt()
val toVal = toLv.number.toInt()
val stepVal = stepLv.number.toInt()
return makeRange(fromVal, toVal, stepVal)
}
}

View File

@ -155,6 +155,13 @@ class PtVariable(name: String, override val type: DataType, val zeropage: Zeropa
init {
value?.let {it.parent=this}
}
val bss: Boolean =
when (type) {
DataType.STR -> false
in ArrayDatatypes -> value==null || arraySize==0u
else -> value==null
}
}

View File

@ -130,7 +130,7 @@ class AsmGen6502Internal (
DataType.BYTE -> "cx16.r9sL"
DataType.UWORD -> "cx16.r9"
DataType.WORD -> "cx16.r9s"
DataType.FLOAT -> TODO("no temporary float var available")
DataType.FLOAT -> throw AssemblyError("a float tempvar should never be requested and it also doesn't exist")
else -> throw AssemblyError("invalid dt $dt")
}
}

View File

@ -1,62 +1,10 @@
package prog8.codegen.cpu6502
import prog8.code.ast.*
import prog8.code.ast.IPtSubroutine
import prog8.code.ast.PtAsmSub
import prog8.code.ast.PtSub
import prog8.code.core.*
import kotlin.math.abs
// TODO include this in the node class directly?
internal fun PtExpression.asConstInteger(): Int? =
(this as? PtNumber)?.number?.toInt()
internal fun PtRange.toConstantIntegerRange(): IntProgression? {
fun makeRange(fromVal: Int, toVal: Int, stepVal: Int): IntProgression {
return when {
fromVal <= toVal -> when {
stepVal <= 0 -> IntRange.EMPTY
stepVal == 1 -> fromVal..toVal
else -> fromVal..toVal step stepVal
}
else -> when {
stepVal >= 0 -> IntRange.EMPTY
stepVal == -1 -> fromVal downTo toVal
else -> fromVal downTo toVal step abs(stepVal)
}
}
}
val fromLv = from as? PtNumber
val toLv = to as? PtNumber
val stepLv = step as? PtNumber
if(fromLv==null || toLv==null || stepLv==null)
return null
val fromVal = fromLv.number.toInt()
val toVal = toLv.number.toInt()
val stepVal = stepLv.number.toInt()
return makeRange(fromVal, toVal, stepVal)
}
fun PtExpression.isSimple(): Boolean {
return when(this) {
is PtAddressOf -> true
is PtArray -> true
is PtArrayIndexer -> index is PtNumber || index is PtIdentifier
is PtBinaryExpression -> false
is PtBuiltinFunctionCall -> name in arrayOf("msb", "lsb", "peek", "peekw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd")
is PtContainmentCheck -> false
is PtFunctionCall -> false
is PtIdentifier -> true
is PtMachineRegister -> true
is PtMemoryByte -> address is PtNumber || address is PtIdentifier
is PtNumber -> true
is PtPrefix -> value.isSimple()
is PtRange -> true
is PtString -> true
is PtTypeCast -> value.isSimple()
}
}
internal fun IPtSubroutine.regXasResult(): Boolean =
(this is PtAsmSub) && this.returns.any { it.first.registerOrPair in arrayOf(RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY) }
@ -100,29 +48,6 @@ internal fun IPtSubroutine.returnsWhatWhere(): List<Pair<RegisterOrStatusflag, D
}
}
internal fun PtExpression.clone(): PtExpression {
fun withClonedChildrenFrom(orig: PtExpression, clone: PtExpression): PtExpression {
orig.children.forEach { clone.add((it as PtExpression).clone()) }
return clone
}
when(this) {
is PtAddressOf -> return withClonedChildrenFrom(this, PtAddressOf(position))
is PtArray -> return withClonedChildrenFrom(this, PtArray(type, position))
is PtArrayIndexer -> return withClonedChildrenFrom(this, PtArrayIndexer(type, position))
is PtBinaryExpression -> return withClonedChildrenFrom(this, PtBinaryExpression(operator, type, position))
is PtBuiltinFunctionCall -> return withClonedChildrenFrom(this, PtBuiltinFunctionCall(name, void, hasNoSideEffects, type, position))
is PtContainmentCheck -> return withClonedChildrenFrom(this, PtContainmentCheck(position))
is PtFunctionCall -> return withClonedChildrenFrom(this, PtFunctionCall(name, void, type, position))
is PtIdentifier -> return withClonedChildrenFrom(this, PtIdentifier(name, type, position))
is PtMachineRegister -> return withClonedChildrenFrom(this, PtMachineRegister(register, type, position))
is PtMemoryByte -> return withClonedChildrenFrom(this, PtMemoryByte(position))
is PtNumber -> return withClonedChildrenFrom(this, PtNumber(type, number, position))
is PtPrefix -> return withClonedChildrenFrom(this, PtPrefix(operator, type, position))
is PtRange -> return withClonedChildrenFrom(this, PtRange(type, position))
is PtString -> return withClonedChildrenFrom(this, PtString(value, encoding, position))
is PtTypeCast -> return withClonedChildrenFrom(this, PtTypeCast(type, position))
}
}
internal fun PtSub.returnRegister(): RegisterOrStatusflag? {
return when(returntype) {

View File

@ -3,7 +3,6 @@ package prog8.codegen.cpu6502.assignment
import prog8.code.ast.*
import prog8.code.core.*
import prog8.codegen.cpu6502.AsmGen6502Internal
import prog8.codegen.cpu6502.asConstInteger
import prog8.codegen.cpu6502.returnsWhatWhere

View File

@ -44,7 +44,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"^=" -> inplaceModification(assign.target, "^", srcValue)
"<<=" -> inplaceModification(assign.target, "<<", srcValue)
">>=" -> inplaceModification(assign.target, ">>", srcValue)
else -> throw AssemblyError("invalid augmented assign operator ${assign.operator}") // TODO fallback to non-augmented Assign?
else -> throw AssemblyError("invalid augmented assign operator ${assign.operator}")
}
}

View File

@ -62,7 +62,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
"<<" -> expressionEval.operatorShiftLeftInplace(address, null, vmDt, value)
">>" -> expressionEval.operatorShiftRightInplace(address, null, vmDt, value.type in SignedDatatypes, value)
in PrefixOperators -> inplacePrefix(assignment.operator, vmDt, address, null)
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}") // TODO fallbackAssign?
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}")
}
}
@ -80,7 +80,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
"<<=" -> expressionEval.operatorShiftLeftInplace(null, symbol, valueVmDt, value)
">>=" -> expressionEval.operatorShiftRightInplace(null, symbol, valueVmDt, value.type in SignedDatatypes, value)
in PrefixOperators -> inplacePrefix(assignment.operator, valueVmDt, null, symbol)
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}") // TODO fallbackAssign?
else -> throw AssemblyError("invalid augmented assign operator ${assignment.operator}")
}
}

View File

@ -234,7 +234,6 @@ class IRBlock(
val alignment: BlockAlignment,
val position: Position
) {
// TODO not separate lists but just a single list of chunks, like IRSubroutine? (but these are not all chunks...)
val children = mutableListOf<IIRBlockElement>()
enum class BlockAlignment {