diff --git a/codeCore/src/prog8/code/SymbolTableMaker.kt b/codeCore/src/prog8/code/SymbolTableMaker.kt index ad57077e1..5f41c23ce 100644 --- a/codeCore/src/prog8/code/SymbolTableMaker.kt +++ b/codeCore/src/prog8/code/SymbolTableMaker.kt @@ -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") { diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index 93fcf43af..531079193 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -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) + } } diff --git a/codeCore/src/prog8/code/ast/AstStatements.kt b/codeCore/src/prog8/code/ast/AstStatements.kt index 831364e54..9706388f4 100644 --- a/codeCore/src/prog8/code/ast/AstStatements.kt +++ b/codeCore/src/prog8/code/ast/AstStatements.kt @@ -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 + } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index e67245a9a..701b03f62 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -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") } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt index cda0c0942..b1e7628ba 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt @@ -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 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) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt index dda428e83..5d9702ce9 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt @@ -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 diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index 82f86c32e..16f89cefb 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -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}") } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 06bfe373b..c32d0003a 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -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}") } } diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 8cac9ec92..cdfa0fbd4 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -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() enum class BlockAlignment {