diff --git a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt index 98ded5a3c..ad5ee50bf 100644 --- a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt +++ b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt @@ -4,11 +4,11 @@ import prog8.ast.IStatementContainer import prog8.ast.Node import prog8.ast.Program import prog8.ast.base.DataType -import prog8.ast.base.FatalAstException import prog8.ast.expressions.AugmentAssignmentOperators import prog8.ast.expressions.BinaryExpression import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.TypecastExpression +import prog8.ast.getTempVar import prog8.ast.statements.AssignTarget import prog8.ast.statements.Assignment import prog8.ast.statements.AssignmentOrigin @@ -98,14 +98,7 @@ X = BinExpr X = LeftExpr // we can see if we can unwrap the binary expression by working on a new temporary variable // (that has the type of the expression), and then finally doing the typecast. // Once it's outside the typecast, the regular splitting can commence. - val tempVar = when(val tempDt = origExpr.inferType(program).getOr(DataType.UNDEFINED)) { - DataType.UBYTE -> listOf("prog8_lib", "retval_interm_ub") - DataType.BYTE -> listOf("prog8_lib", "retval_interm_b") - DataType.UWORD -> listOf("prog8_lib", "retval_interm_uw") - DataType.WORD -> listOf("prog8_lib", "retval_interm_w") - DataType.FLOAT -> listOf("floats", "tempvar_swap_float") - else -> throw FatalAstException("invalid dt $tempDt") - } + val tempVar = program.getTempVar(origExpr.inferType(program).getOr(DataType.UNDEFINED)) val assignTempVar = Assignment( AssignTarget(IdentifierReference(tempVar, typecast.position), null, null, typecast.position), typecast.expression, AssignmentOrigin.OPTIMIZER, typecast.position diff --git a/codeOptimizers/src/prog8/optimizer/Extensions.kt b/codeOptimizers/src/prog8/optimizer/Extensions.kt index f01d53598..92453d4a2 100644 --- a/codeOptimizers/src/prog8/optimizer/Extensions.kt +++ b/codeOptimizers/src/prog8/optimizer/Extensions.kt @@ -4,7 +4,12 @@ import prog8.ast.IBuiltinFunctions import prog8.ast.Program import prog8.ast.base.DataType import prog8.ast.base.FatalAstException +import prog8.ast.base.Position +import prog8.ast.base.VarDeclType import prog8.ast.expressions.InferredTypes +import prog8.ast.statements.VarDecl +import prog8.ast.statements.VarDeclOrigin +import prog8.ast.statements.ZeropageWish import prog8.compilerinterface.CompilationOptions import prog8.compilerinterface.ICompilationTarget import prog8.compilerinterface.IErrorReporter @@ -69,7 +74,7 @@ fun Program.splitBinaryExpressions(options: CompilationOptions, compTarget: ICom return opti.applyModifications() } -fun getTempVarName(dt: InferredTypes.InferredType): List { +fun getTempRegisterName(dt: InferredTypes.InferredType): List { 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") diff --git a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt index 969a4ef9f..802984b95 100644 --- a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt @@ -130,7 +130,7 @@ class StatementOptimizer(private val program: Program, if(functionCallStatement.target.nameInSource !in listOf(listOf("pop"), listOf("popw")) && functionCallStatement.args.size==1) { val arg = functionCallStatement.args[0] if(!arg.isSimple && arg !is TypecastExpression && arg !is IFunctionCall) { - val name = getTempVarName(arg.inferType(program)) + val name = getTempRegisterName(arg.inferType(program)) val tempvar = IdentifierReference(name, functionCallStatement.position) val assignTempvar = Assignment(AssignTarget(tempvar.copy(), null, null, functionCallStatement.position), arg, AssignmentOrigin.OPTIMIZER, functionCallStatement.position) return listOf( @@ -474,14 +474,8 @@ class StatementOptimizer(private val program: Program, val returnDt = subr.returntypes.single() if (returnDt in IntegerDatatypes) { // first assign to intermediary variable, then return that - val returnVarName = "retval_interm_" + when(returnDt) { - DataType.UBYTE -> "ub" - DataType.BYTE -> "b" - DataType.UWORD -> "uw" - DataType.WORD -> "w" - else -> "" - } - val returnValueIntermediary = IdentifierReference(listOf("prog8_lib", returnVarName), returnStmt.position) + val returnVarName = program.getTempVar(returnDt) + val returnValueIntermediary = IdentifierReference(returnVarName, returnStmt.position) val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position) val assign = Assignment(tgt, value, AssignmentOrigin.OPTIMIZER, returnStmt.position) val returnReplacement = Return(returnValueIntermediary.copy(), returnStmt.position) diff --git a/compiler/res/prog8lib/c128/floats.p8 b/compiler/res/prog8lib/c128/floats.p8 index f8be8b35a..472318d46 100644 --- a/compiler/res/prog8lib/c128/floats.p8 +++ b/compiler/res/prog8lib/c128/floats.p8 @@ -10,8 +10,6 @@ floats { const float PI = 3.141592653589793 const float TWOPI = 6.283185307179586 - float tempvar_swap_float ; used for some swap() operations - ; ---- ROM float functions ---- diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index 91aa35a27..b6ed18d94 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -13,8 +13,6 @@ floats { const float PI = 3.141592653589793 const float TWOPI = 6.283185307179586 - float tempvar_swap_float ; used for some swap() operations - ; ---- ROM float functions ---- diff --git a/compiler/res/prog8lib/prog8_lib.p8 b/compiler/res/prog8lib/prog8_lib.p8 index 14cc24bd4..49c6a4687 100644 --- a/compiler/res/prog8lib/prog8_lib.p8 +++ b/compiler/res/prog8lib/prog8_lib.p8 @@ -6,24 +6,6 @@ prog8_lib { %asminclude "library:prog8_lib.asm" %asminclude "library:prog8_funcs.asm" - ; to store intermediary expression results for return values: - ; NOTE: these variables can be used in the StatementReorderer and StatementOptimizer - uword @zp retval_interm_uw - word @zp retval_interm_w - ubyte @zp retval_interm_ub - byte @zp retval_interm_b - word retval_interm_w2 - byte retval_interm_b2 - - ; prog8 "hooks" to be able to access the temporary scratch variables - ; YOU SHOULD NOT USE THESE IN USER CODE - THESE ARE MEANT FOR INTERNAL COMPILER USE - ; NOTE: the assembly code generator will match these names and not generate - ; new variables/memdefs for them, rather, they'll point to the scratch variables directly. - &ubyte P8ZP_SCRATCH_REG = $ff - &byte P8ZP_SCRATCH_B1 = $ff - &uword P8ZP_SCRATCH_W1 = $ff - &word P8ZP_SCRATCH_W2 = $ff - asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A { %asm {{ diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index ee6085ea1..81c8aeae2 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -345,7 +345,7 @@ private fun writeAssembly(program: Program, // asm generation directly from the Ast compilerOptions.compTarget.machine.initializeZeropage(compilerOptions) val variables = VariableExtractor().extractVars(program) - program.processAstBeforeAsmGeneration(compilerOptions, errors) + program.processAstBeforeAsmGeneration(compilerOptions, variables, errors) errors.report() // println("*********** AST RIGHT BEFORE ASM GENERATION *************") diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index 46187a925..d3e4d5595 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -13,6 +13,7 @@ import prog8.ast.walk.IAstModification import prog8.compilerinterface.CompilationOptions import prog8.compilerinterface.IErrorReporter import prog8.compilerinterface.IStringEncoding +import prog8.compilerinterface.IVariablesAndConsts internal fun Program.checkValid(errors: IErrorReporter, compilerOptions: CompilationOptions) { @@ -23,8 +24,8 @@ internal fun Program.checkValid(errors: IErrorReporter, compilerOptions: Compila checker.visit(this) } -internal fun Program.processAstBeforeAsmGeneration(compilerOptions: CompilationOptions, errors: IErrorReporter) { - val fixer = BeforeAsmAstChanger(this, compilerOptions, errors) +internal fun Program.processAstBeforeAsmGeneration(compilerOptions: CompilationOptions, variables: IVariablesAndConsts, errors: IErrorReporter) { + val fixer = BeforeAsmAstChanger(this, compilerOptions, variables, errors) fixer.visit(this) while(errors.noErrors() && fixer.applyModifications()>0) { fixer.visit(this) diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt index 642a074aa..43e4f0959 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt @@ -8,10 +8,11 @@ import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstVisitor import prog8.compilerinterface.* -import prog8.optimizer.getTempVarName +import prog8.optimizer.getTempRegisterName internal class BeforeAsmAstChanger(val program: Program, private val options: CompilationOptions, + private val variables: IVariablesAndConsts, private val errors: IErrorReporter ) : AstWalker() { @@ -243,7 +244,7 @@ internal class BeforeAsmAstChanger(val program: Program, } if(separateLeftExpr) { - val name = getTempVarName(leftDt) + val name = getTempRegisterName(leftDt) leftOperandReplacement = IdentifierReference(name, expr.position) leftAssignment = Assignment( AssignTarget(IdentifierReference(name, expr.position), null, null, expr.position), @@ -252,13 +253,9 @@ internal class BeforeAsmAstChanger(val program: Program, ) } if(separateRightExpr) { - val name = when { - rightDt istype DataType.UBYTE -> listOf("prog8_lib","retval_interm_ub") - rightDt istype DataType.UWORD -> listOf("prog8_lib","retval_interm_uw") - rightDt istype DataType.BYTE -> listOf("prog8_lib","retval_interm_b2") - rightDt istype DataType.WORD -> listOf("prog8_lib","retval_interm_w2") - else -> throw AssemblyError("invalid dt") - } + val name = program.getTempVar(rightDt.getOrElse { throw FatalAstException("invalid dt") }, true) + val tempvardecl = program.toplevelModule.lookup(name) as VarDecl + variables.addIfUnknown(tempvardecl.definingBlock, tempvardecl) rightOperandReplacement = IdentifierReference(name, expr.position) rightAssignment = Assignment( AssignTarget(IdentifierReference(name, expr.position), null, null, expr.position), @@ -354,7 +351,9 @@ internal class BeforeAsmAstChanger(val program: Program, val modifications = mutableListOf() val statement = expr.containingStatement val dt = expr.indexer.indexExpr.inferType(program) - val tempvar = if(dt.isBytes) listOf("prog8_lib","retval_interm_ub") else listOf("prog8_lib","retval_interm_b") + val tempvar = program.getTempVar(dt.getOrElse { throw FatalAstException("invalid dt") }) + val tempvardecl = program.toplevelModule.lookup(tempvar) as VarDecl + variables.addIfUnknown(tempvardecl.definingBlock, tempvardecl) val target = AssignTarget(IdentifierReference(tempvar, expr.indexer.position), null, null, expr.indexer.position) val assign = Assignment(target, expr.indexer.indexExpr, AssignmentOrigin.BEFOREASMGEN, expr.indexer.position) modifications.add(IAstModification.InsertBefore(statement, assign, statement.parent as IStatementContainer)) diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index ee5afa559..f001374aa 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -55,8 +55,8 @@ internal class StatementReorderer(val program: Program, // This allows you to restart the program and have the same starting values of the variables // So basically consider 'ubyte xx' as a short form for 'ubyte xx; xx=0' decl.value = null - if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") { - // no need to zero out the special internal returnvalue intermediates. + if(decl.name.startsWith("tempvar_") && decl.definingScope.name=="prog8_lib") { + // no need to zero out the special internal temporary variables. return noModifications } if(decl.findInitializer(program)!=null) diff --git a/compiler/src/prog8/compiler/astprocessing/VariablesAndConsts.kt b/compiler/src/prog8/compiler/astprocessing/VariablesAndConsts.kt index 14fea44f3..46fb2f3a1 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariablesAndConsts.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariablesAndConsts.kt @@ -104,18 +104,17 @@ internal class VariablesAndConsts ( override val subroutineConsts: Map> override val subroutineMemvars: Map> + private val bv = astBlockVars.keys.associateWith { mutableSetOf() }.toMutableMap() + private val bc = astBlockConsts.keys.associateWith { mutableSetOf() } + private val bmv = astBlockMemvars.keys.associateWith { mutableSetOf() } + private val sv = astSubroutineVars.keys.associateWith { mutableSetOf() } + private val sc = astSubroutineConsts.keys.associateWith { mutableSetOf() } + private val smv = astSubroutineMemvars.keys.associateWith { mutableSetOf() } + init { - val bv = astBlockVars.keys.associateWith { mutableSetOf() } - val bc = astBlockConsts.keys.associateWith { mutableSetOf() } - val bmv = astBlockMemvars.keys.associateWith { mutableSetOf() } - val sv = astSubroutineVars.keys.associateWith { mutableSetOf() } - val sc = astSubroutineConsts.keys.associateWith { mutableSetOf() } - val smv = astSubroutineMemvars.keys.associateWith { mutableSetOf() } astBlockVars.forEach { (block, decls) -> val vars = bv.getValue(block) - vars.addAll(decls.map { - IVariablesAndConsts.StaticVariable(it.datatype, it.scopedName, it.definingScope, it.value, it.arraysize?.constIndex(), it.zeropage, it.position) - }) + vars.addAll(decls.map { toStatic(it) }) } astBlockConsts.forEach { (block, decls) -> bc.getValue(block).addAll( @@ -146,9 +145,7 @@ internal class VariablesAndConsts ( } astSubroutineVars.forEach { (sub, decls) -> val vars = sv.getValue(sub) - vars.addAll(decls.map { - IVariablesAndConsts.StaticVariable(it.datatype, it.scopedName, it.definingScope, it.value, it.arraysize?.constIndex(), it.zeropage, it.position) - }) + vars.addAll(decls.map { toStatic(it) }) } astSubroutineConsts.forEach { (sub, decls) -> sc.getValue(sub).addAll( @@ -179,4 +176,16 @@ internal class VariablesAndConsts ( subroutineConsts = sc subroutineMemvars = smv } + + private fun toStatic(decl: VarDecl) = + IVariablesAndConsts.StaticVariable(decl.datatype, decl.scopedName, decl.definingScope, decl.value, decl.arraysize?.constIndex(), decl.zeropage, decl.position) + + override fun addIfUnknown(definingBlock: Block, variable: VarDecl) { + var blockvars = bv[definingBlock] + if(blockvars==null) { + blockvars = mutableSetOf() + bv[definingBlock] = blockvars + } + blockvars.add(toStatic(variable)) + } } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index e4af72316..70c80a117 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -303,7 +303,7 @@ class TestOptimization: FunSpec({ expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, true, C64Target(), outputDir= outputDir) - result.program.processAstBeforeAsmGeneration(options, ErrorReporterForTests()) + result.program.processAstBeforeAsmGeneration(options, DummyVarsAndConsts, ErrorReporterForTests()) // assignment is now split into: // bb = not bb @@ -357,11 +357,11 @@ class TestOptimization: FunSpec({ st.size shouldBe 8 st.last() shouldBe instanceOf() var assign = st[3] as Assignment - assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","retval_interm_b") + assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","tempvar_b") assign = st[4] as Assignment - assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","retval_interm_b") + assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","tempvar_b") assign = st[5] as Assignment - assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","retval_interm_b") + assign.target.identifier!!.nameInSource shouldBe listOf("prog8_lib","tempvar_b") assign = st[6] as Assignment assign.target.identifier!!.nameInSource shouldBe listOf("bb") } diff --git a/compiler/test/codegeneration/TestAsmGenSymbols.kt b/compiler/test/codegeneration/TestAsmGenSymbols.kt index cf192aa84..75f41d68b 100644 --- a/compiler/test/codegeneration/TestAsmGenSymbols.kt +++ b/compiler/test/codegeneration/TestAsmGenSymbols.kt @@ -76,6 +76,11 @@ class TestAsmGenSymbols: StringSpec({ override val subroutineVars: Map> override val subroutineConsts: Map> override val subroutineMemvars: Map> + + override fun addIfUnknown(definingBlock: Block, variable: VarDecl) { + throw NotImplementedError("dummy") + } + init { blockVars = mutableMapOf() blockVars[block] = mutableSetOf(IVariablesAndConsts.StaticVariable(varInBlock.datatype, varInBlock.scopedName, varInBlock.definingScope, varInBlock.value, varInBlock.arraysize?.constIndex(), varInBlock.zeropage, varInBlock.position)) diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt index 7763d2b3d..efa8ccdee 100644 --- a/compiler/test/helpers/Dummies.kt +++ b/compiler/test/helpers/Dummies.kt @@ -6,6 +6,7 @@ import prog8.ast.base.Position import prog8.ast.expressions.Expression import prog8.ast.expressions.InferredTypes import prog8.ast.expressions.NumericLiteralValue +import prog8.ast.statements.Block import prog8.ast.statements.RegisterOrStatusflag import prog8.ast.statements.Subroutine import prog8.ast.statements.VarDecl @@ -76,3 +77,23 @@ internal object DummyCompilationTarget : ICompilationTarget { throw NotImplementedError("dummy") } } + +internal object DummyVarsAndConsts : IVariablesAndConsts { + override val blockVars: Map> + get() = throw NotImplementedError("dummy") + override val blockConsts: Map> + get() = throw NotImplementedError("dummy") + override val blockMemvars: Map> + get() = throw NotImplementedError("dummy") + override val subroutineVars: Map> + get() = throw NotImplementedError("dummy") + override val subroutineConsts: Map> + get() = throw NotImplementedError("dummy") + override val subroutineMemvars: Map> + get() = throw NotImplementedError("dummy") + + override fun addIfUnknown(definingBlock: Block, variable: VarDecl) { + throw NotImplementedError("dummy") + } + +} \ No newline at end of file diff --git a/compilerAst/src/prog8/ast/Extensions.kt b/compilerAst/src/prog8/ast/Extensions.kt index 2cc8b063d..7542a09ca 100644 --- a/compilerAst/src/prog8/ast/Extensions.kt +++ b/compilerAst/src/prog8/ast/Extensions.kt @@ -1,5 +1,12 @@ package prog8.ast +import prog8.ast.base.DataType +import prog8.ast.base.FatalAstException +import prog8.ast.base.Position +import prog8.ast.base.VarDeclType +import prog8.ast.statements.VarDecl +import prog8.ast.statements.VarDeclOrigin +import prog8.ast.statements.ZeropageWish import kotlin.math.abs fun Number.toHex(): String { @@ -29,3 +36,37 @@ fun UInt.toHex(): String { else -> throw IllegalArgumentException("number too large for 16 bits $this") } } + +fun Program.getTempVar(dt: DataType, altNames: Boolean=false): List { + 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] } + if(block.statements.filterIsInstance().any { it.name == tmpvarName[1] }) + return tmpvarName + + // 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 tmpvarName +} diff --git a/compilerAst/src/prog8/ast/Program.kt b/compilerAst/src/prog8/ast/Program.kt index 0e77c0112..f0714666d 100644 --- a/compilerAst/src/prog8/ast/Program.kt +++ b/compilerAst/src/prog8/ast/Program.kt @@ -56,7 +56,7 @@ class Program(val name: String, } val allBlocks: List - get() = modules.flatMap { it.statements.filterIsInstance() } + get() = modules.flatMap { it.statements.asSequence().filterIsInstance() } val entrypoint: Subroutine get() { diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 40361d7f0..1fa024189 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -175,7 +175,8 @@ enum class VarDeclOrigin { USERCODE, SUBROUTINEPARAM, STRINGLITERAL, - ARRAYLITERAL + ARRAYLITERAL, + AUTOGENERATED } diff --git a/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt b/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt index ef1aa297b..e2abbc605 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/AstExtensions.kt @@ -38,7 +38,8 @@ fun AssignTarget.isIOAddress(machine: IMachineDefinition): Boolean { } else false } ident != null -> { - val decl = ident.targetVarDecl(definingModule.program) ?: throw FatalAstException("invalid identifier ${ident.nameInSource}") + val decl = ident.targetVarDecl(definingModule.program) ?: + throw FatalAstException("invalid identifier ${ident.nameInSource}") return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteralValue) machine.isIOAddress((decl.value as NumericLiteralValue).number.toUInt()) else diff --git a/compilerInterfaces/src/prog8/compilerinterface/IVariablesAndConsts.kt b/compilerInterfaces/src/prog8/compilerinterface/IVariablesAndConsts.kt index 44bd72a03..249ea03e3 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/IVariablesAndConsts.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/IVariablesAndConsts.kt @@ -27,4 +27,6 @@ interface IVariablesAndConsts { val subroutineVars: Map> val subroutineConsts: Map> val subroutineMemvars: Map> + + fun addIfUnknown(definingBlock: Block, variable: VarDecl) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 1d2457989..436e98557 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -4,7 +4,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ - (newvaralloc) UnusedCodeRemover after(decl: VarDecl): fix that vars defined in a library can also safely be removed if unused. Currently this breaks programs such as textelite (due to diskio.save().end_address ?) -- check that retval_interm_* are not in the varallocation if they're not used - make it so that subroutine parameters as variables can again be allocated in ZP, if there's still space