diff --git a/compiler/src/prog8/compiler/astprocessing/AsmInstructionNamesReplacer.kt b/compiler/src/prog8/compiler/astprocessing/AsmInstructionNamesReplacer.kt index 639477068..4fac42a21 100644 --- a/compiler/src/prog8/compiler/astprocessing/AsmInstructionNamesReplacer.kt +++ b/compiler/src/prog8/compiler/astprocessing/AsmInstructionNamesReplacer.kt @@ -55,23 +55,47 @@ class AsmInstructionNamesReplacer( noModifications } + private val subsWithParamRefsToFix = mutableListOf() + + override fun applyModifications(): Int { + var count = super.applyModifications() + subsWithParamRefsToFix.forEach { subroutine -> + subroutine.statements.withIndex().reversed().forEach { (index,stmt) -> + if(stmt is VarDecl && stmt.origin==VarDeclOrigin.SUBROUTINEPARAM) { + val param = subroutine.parameters.single { it.name == stmt.name} + val decl = VarDecl.fromParameter(param) + subroutine.statements[index] = decl + decl.linkParents(subroutine) + count++ + } + } + } + return count + } + override fun after(subroutine: Subroutine, parent: Node): Iterable { - val parameters = subroutine.parameters.map { - if(it.name.length==3 && it.name.all { it.isLetter() } && !it.definingModule.isLibrary) - SubroutineParameter("p8p_${it.name}", it.type, it.position) else it + val changedParams = mutableListOf>() + subroutine.parameters.withIndex().forEach { (index, param) -> + if(param.name.length==3 && param.name.all { it.isLetter() } && !param.definingModule.isLibrary) { + changedParams.add(index to SubroutineParameter("p8p_${param.name}", param.type, param.position)) + } } - // TODO for all decls in the subroutine, update their subroutineParameter if something changed - + changedParams.forEach { (index, newParam) -> subroutine.parameters[index] = newParam } val newName = if(subroutine in subroutines) "p8p_${subroutine.name}" else subroutine.name - return if(newName!=subroutine.name || parameters.map{ it.name} != subroutine.parameters.map {it.name}) - listOf(IAstModification.ReplaceNode(subroutine, - Subroutine(newName, parameters.toMutableList(), subroutine.returntypes, - subroutine.asmParameterRegisters, subroutine.asmReturnvaluesRegisters, subroutine.asmClobbers, subroutine.asmAddress, subroutine.isAsmSubroutine, - subroutine.inline, subroutine.statements, subroutine.position), parent)) - else + return if(newName!=subroutine.name || changedParams.isNotEmpty()) { + val newSub = Subroutine(newName, subroutine.parameters, subroutine.returntypes, + subroutine.asmParameterRegisters, subroutine.asmReturnvaluesRegisters, subroutine.asmClobbers, subroutine.asmAddress, subroutine.isAsmSubroutine, + subroutine.inline, subroutine.statements, subroutine.position) + if(changedParams.isNotEmpty()) + subsWithParamRefsToFix += newSub + listOf(IAstModification.ReplaceNode(subroutine, newSub, parent)) + } else { + if(changedParams.isNotEmpty()) + subsWithParamRefsToFix += subroutine noModifications + } } } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 22a5cc0e2..6c850d2e9 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -314,9 +314,7 @@ internal class StatementReorderer(val program: Program, AddressOf(sourceIdent, assign.position), AddressOf(identifier, assign.position), NumericLiteral.optimalInteger(numelements*eltsize, assign.position) - ), - true, - assign.position + ), false, assign.position ) return listOf(IAstModification.ReplaceNode(assign, memcopy, assign.parent)) } diff --git a/compilerAst/src/prog8/ast/walk/AstWalker.kt b/compilerAst/src/prog8/ast/walk/AstWalker.kt index 213bc648f..12687683e 100644 --- a/compilerAst/src/prog8/ast/walk/AstWalker.kt +++ b/compilerAst/src/prog8/ast/walk/AstWalker.kt @@ -190,7 +190,7 @@ abstract class AstWalker { } } - fun applyModifications(): Int { + open fun applyModifications(): Int { // check if there are double removes, keep only the last one val removals = modifications.filter { it.first is IAstModification.Remove } if(removals.isNotEmpty()) { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 52b7b3303..2cf0d8a00 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- AsmInstructionNamesReplacer: fix the TODO about the params -- create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code -- regression test the various projects +- regression test the various projects before release ... @@ -21,6 +19,7 @@ Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ Compiler: +- create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code - add a mechanism to allocate variables into golden ram (see MachineDefinition.GOLDEN) - ir: mechanism to determine for chunks which registers are getting input values from "outside" - ir: mechanism to determine for chunks which registers are passing values out? (i.e. are used again in another chunk)