diff --git a/compiler/src/prog8/compiler/astprocessing/BoolRemover.kt b/compiler/src/prog8/compiler/astprocessing/BoolRemover.kt index 5a9477268..06ea6de72 100644 --- a/compiler/src/prog8/compiler/astprocessing/BoolRemover.kt +++ b/compiler/src/prog8/compiler/astprocessing/BoolRemover.kt @@ -59,7 +59,7 @@ internal class BoolRemover(val program: Program) : AstWalker() { if(subroutine.returntypes.any { it==DataType.BOOL } || subroutine.parameters.any {it.type==DataType.BOOL}) { val newReturnTypes = subroutine.returntypes.map { if(it==DataType.BOOL) DataType.UBYTE else it - } + }.toMutableList() val newParams = subroutine.parameters.map { if(it.type==DataType.BOOL) SubroutineParameter(it.name, DataType.UBYTE, it.position) else it }.toMutableList() diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 4e870efb5..30870641e 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -142,6 +142,11 @@ internal class StatementReorderer( val uwordParam = SubroutineParameter(it.name, DataType.UWORD, it.position) IAstModification.ReplaceNode(it, uwordParam, subroutine) } + // change 'str' and 'ubyte[]' return types into 'uword' (just treat it as an address) + subroutine.returntypes.withIndex().forEach { (index, type) -> + if(type==DataType.STR || type==DataType.ARRAY_UB) + subroutine.returntypes[index] = DataType.UWORD + } val varsChanges = mutableListOf() if(!subroutine.isAsmSubroutine) { diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index 9da46e78c..ab77ff5d5 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -27,7 +27,7 @@ class TestMemory: FunSpec({ fun wrapWithProgram(statements: List): Program { val program = Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements.toMutableList(), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements.toMutableList(), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) program.addModule(module) return program @@ -153,7 +153,7 @@ class TestMemory: FunSpec({ val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), null, false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) @@ -165,7 +165,7 @@ class TestMemory: FunSpec({ val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) @@ -177,7 +177,7 @@ class TestMemory: FunSpec({ val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) @@ -189,7 +189,7 @@ class TestMemory: FunSpec({ val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) @@ -202,7 +202,7 @@ class TestMemory: FunSpec({ val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) @@ -215,7 +215,7 @@ class TestMemory: FunSpec({ val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) - val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) + val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) Program("test", DummyFunctions, DummyMemsizer, DummyStringEncoder) .addModule(module) diff --git a/compiler/test/codegeneration/TestAsmGenSymbols.kt b/compiler/test/codegeneration/TestAsmGenSymbols.kt index b2a1b957c..7a6d93e36 100644 --- a/compiler/test/codegeneration/TestAsmGenSymbols.kt +++ b/compiler/test/codegeneration/TestAsmGenSymbols.kt @@ -61,7 +61,7 @@ class TestAsmGenSymbols: StringSpec({ val assign8 = Assignment(tgt, AddressOf(IdentifierReference(listOf("main","label_outside"), Position.DUMMY), null, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY) val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8) - val subroutine = Subroutine("start", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY) + val subroutine = Subroutine("start", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY) val labelInBlock = Label("label_outside", Position.DUMMY) val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", emptyList(),null, false, false, Position.DUMMY) val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index a539f0532..fee945062 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -163,7 +163,7 @@ private fun AsmsubroutineContext.toAst(): Subroutine { val inline = this.inline()!=null val subdecl = asmsub_decl().toAst() val statements = statement_block()?.toAst() ?: mutableListOf() - return Subroutine(subdecl.name, subdecl.parameters.toMutableList(), subdecl.returntypes, + return Subroutine(subdecl.name, subdecl.parameters.toMutableList(), subdecl.returntypes.toMutableList(), subdecl.asmParameterRegisters, subdecl.asmReturnvaluesRegisters, subdecl.asmClobbers, null, true, inline, false, statements, toPosition()) } @@ -171,7 +171,7 @@ private fun AsmsubroutineContext.toAst(): Subroutine { private fun RomsubroutineContext.toAst(): Subroutine { val subdecl = asmsub_decl().toAst() val address = integerliteral().toAst().number.toUInt() - return Subroutine(subdecl.name, subdecl.parameters.toMutableList(), subdecl.returntypes, + return Subroutine(subdecl.name, subdecl.parameters.toMutableList(), subdecl.returntypes.toMutableList(), subdecl.asmParameterRegisters, subdecl.asmReturnvaluesRegisters, subdecl.asmClobbers, address, true, inline = false, statements = mutableListOf(), position = toPosition() ) @@ -295,7 +295,7 @@ private fun SubroutineContext.toAst() : Subroutine { return Subroutine( identifier().text, sub_params()?.toAst()?.toMutableList() ?: mutableListOf(), - if (returntype == null) emptyList() else listOf(returntype), + if (returntype == null) mutableListOf() else mutableListOf(returntype), emptyList(), emptyList(), emptySet(), diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 55d87b5e2..c4985bff3 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -755,7 +755,7 @@ class AnonymousScope(override var statements: MutableList, // (multiple return types can only occur for the latter type) class Subroutine(override val name: String, val parameters: MutableList, - val returntypes: List, + val returntypes: MutableList, val asmParameterRegisters: List, val asmReturnvaluesRegisters: List, val asmClobbers: Set, diff --git a/examples/test.p8 b/examples/test.p8 index 61aefc99b..e919a6d9b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,10 +1,24 @@ -%zeropage basicsafe +%import textio %option no_sysinit +%zeropage basicsafe main { sub start() { - ;sys.exit(99) - ;sys.exit2(99,123,200) - sys.exit3(99,123,200,true) + derp("hello") + mult3("hello") + } + + sub derp(str arg) -> str { + cx16.r0++ + return arg + } + + asmsub mult3(str input @XY) -> ubyte @A, str @XY { + %asm {{ + lda #99 + ldx #100 + ldy #101 + rts + }} } } diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index cc77d54c8..5afba0ef0 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -503,7 +503,7 @@ class IRFileReader { "bool" -> DataType.ARRAY_B "uword_split" -> DataType.ARRAY_UW_SPLIT "word_split" -> DataType.ARRAY_W_SPLIT - else -> throw IRParseException("invalid dt") + else -> throw IRParseException("invalid dt $type") } } else { return when(type) { @@ -514,7 +514,7 @@ class IRFileReader { "float" -> DataType.FLOAT "bool" -> DataType.BOOL // note: 'str' should not occur anymore in IR. Should be 'uword' - else -> throw IRParseException("invalid dt") + else -> throw IRParseException("invalid dt $type") } } }