diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 24d0b1611..7e8b61441 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -140,7 +140,7 @@ internal class StatementReorderer( // change 'str' and 'ubyte[]' parameters into 'uword' (just treat it as an address) val stringParams = subroutine.parameters.filter { it.type==DataType.STR || it.type==DataType.ARRAY_UB } val parameterChanges = stringParams.map { - val uwordParam = SubroutineParameter(it.name, DataType.UWORD, it.position) + val uwordParam = SubroutineParameter(it.name, DataType.UWORD, it.zp, it.position) IAstModification.ReplaceNode(it, uwordParam, subroutine) } // change 'str' and 'ubyte[]' return types into 'uword' (just treat it as an address) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index 119f7c384..65d8febe1 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -189,7 +189,7 @@ private fun Asmsub_declContext.toAst(): AsmsubDecl { val params = asmsub_params()?.toAst() ?: emptyList() val returns = asmsub_returns()?.toAst() ?: emptyList() val clobbers = asmsub_clobbers()?.clobber()?.toAst() ?: emptySet() - val normalParameters = params.map { SubroutineParameter(it.name, it.type, it.position) } + val normalParameters = params.map { SubroutineParameter(it.name, it.type, it.zp, it.position) } val normalReturntypes = returns.map { it.type } val paramRegisters = params.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag) } val returnRegisters = returns.map { RegisterOrStatusflag(it.registerOrPair, it.statusflag) } @@ -200,7 +200,7 @@ private class AsmSubroutineParameter(name: String, type: DataType, val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, - position: Position) : SubroutineParameter(name, type, position) + position: Position) : SubroutineParameter(name, type, ZeropageWish.DONTCARE, position) private class AsmSubroutineReturn(val type: DataType, val registerOrPair: RegisterOrPair?, @@ -310,6 +310,8 @@ private fun SubroutineContext.toAst() : Subroutine { private fun Sub_paramsContext.toAst(): List = vardecl().map { + val options = it.decloptions() + val zp = getZpOption(options) var datatype = it.datatype()?.toAst() ?: DataType.UNDEFINED if(it.ARRAYSIG()!=null || it.arrayindex()!=null) datatype = ElementToArrayTypes.getValue(datatype) @@ -318,9 +320,20 @@ private fun Sub_paramsContext.toAst(): List = if(identifiers.size>1) throw SyntaxError("parameter name must be singular", identifiers[0].toPosition()) val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME() ?: identifiers[0].VOID() - SubroutineParameter(identifiername.text, datatype, it.toPosition()) + SubroutineParameter(identifiername.text, datatype, zp, it.toPosition()) } +private fun getZpOption(options: DecloptionsContext?): ZeropageWish { + if(options==null) + return ZeropageWish.DONTCARE + return when { + options.ZEROPAGEREQUIRE().isNotEmpty() -> ZeropageWish.REQUIRE_ZEROPAGE + options.ZEROPAGE().isNotEmpty() -> ZeropageWish.PREFER_ZEROPAGE + options.ZEROPAGENOT().isNotEmpty() -> ZeropageWish.NOT_IN_ZEROPAGE + else -> ZeropageWish.DONTCARE + } +} + private fun Assign_targetContext.toAst() : AssignTarget { return when(this) { is IdentifierTargetContext -> { @@ -671,12 +684,7 @@ private fun When_choiceContext.toAst(): WhenChoice { private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl { val options = decloptions() - val zp = when { - options.ZEROPAGEREQUIRE().isNotEmpty() -> ZeropageWish.REQUIRE_ZEROPAGE - options.ZEROPAGE().isNotEmpty() -> ZeropageWish.PREFER_ZEROPAGE - options.ZEROPAGENOT().isNotEmpty() -> ZeropageWish.NOT_IN_ZEROPAGE - else -> ZeropageWish.DONTCARE - } + val zp = getZpOption(options) val identifiers = identifier() val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME() ?: identifiers[0].VOID() val name = if(identifiers.size==1) identifiername.text else "" diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 67a0cd84f..390d0aa9b 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -236,7 +236,7 @@ class VarDecl(val type: VarDeclType, fun fromParameter(param: SubroutineParameter): VarDecl { val dt = if(param.type in ArrayDatatypes) DataType.UWORD else param.type - return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, dt, ZeropageWish.DONTCARE, null, param.name, emptyList(), null, + return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, null, param.name, emptyList(), null, sharedWithAsm = false, splitArray = false, position = param.position @@ -813,6 +813,7 @@ class Subroutine(override val name: String, open class SubroutineParameter(val name: String, val type: DataType, + val zp: ZeropageWish, final override val position: Position) : Node { override lateinit var parent: Node @@ -824,7 +825,7 @@ open class SubroutineParameter(val name: String, throw FatalAstException("can't replace anything in a subroutineparameter node") } - override fun copy() = SubroutineParameter(name, type, position) + override fun copy() = SubroutineParameter(name, type, zp, position) override fun toString() = "Param($type:$name)" override fun referencesIdentifier(nameInSource: List): Boolean = nameInSource.size==1 && name==nameInSource[0] } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index dd04d7ee6..8584a14e8 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,10 +1,6 @@ TODO ==== -@nozp for subroutine arguments doesn't work - still become zeropage vars -@requirezp for subroutine arguments doesn't cause compiler error when zp is disabled "zeropage usage has been disabled by options" - - wrong answer if cast as uword is not done in: const uword W=320; uword x1 = ((WIDTH-256)/2 as uword) + math.sin8u(i)