diff --git a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt index 0e7cfb34c..a89391108 100644 --- a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt +++ b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt @@ -197,6 +197,16 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val } } } + else { + // if the argument is an identifier reference and the param is UWORD, add the missing &. + if(arg is IdentifierReference && DataType.UWORD == param.type) { + modifications += IAstModification.ReplaceNode( + arg, + AddressOf(arg, arg.position), + call as Node + ) + } + } } } is BuiltinFunctionPlaceholder -> { @@ -226,6 +236,16 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val } } } + else { + // if the argument is an identifier reference and the param is UWORD, add the missing &. + if(pair.second is IdentifierReference && DataType.UWORD in pair.first.possibleDatatypes) { + modifications += IAstModification.ReplaceNode( + call.args[index], + AddressOf(pair.second as IdentifierReference, pair.second.position), + call as Node + ) + } + } } } else -> { } diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index 6b9b6799a..67bef934a 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -5,6 +5,10 @@ import io.kotest.matchers.ints.shouldBeGreaterThan import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain +import io.kotest.matchers.types.instanceOf +import prog8.ast.IFunctionCall +import prog8.ast.expressions.AddressOf +import prog8.ast.expressions.IdentifierReference import prog8.code.target.C64Target import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText @@ -12,6 +16,41 @@ import prog8tests.helpers.compileText class TestTypecasts: FunSpec({ + test("add missing & to function arguments") { + val text=""" + main { + + sub handler(uword fptr) { + } + + sub start() { + uword variable + + pushw(variable) + pushw(handler) + pushw(&handler) + handler(variable) + handler(handler) + handler(&handler) + } + }""" + val result = compileText(C64Target(), false, text, writeAssembly = false)!! + val stmts = result.program.entrypoint.statements + stmts.size shouldBe 8 + val arg1 = (stmts[2] as IFunctionCall).args.single() + val arg2 = (stmts[3] as IFunctionCall).args.single() + val arg3 = (stmts[4] as IFunctionCall).args.single() + val arg4 = (stmts[5] as IFunctionCall).args.single() + val arg5 = (stmts[6] as IFunctionCall).args.single() + val arg6 = (stmts[7] as IFunctionCall).args.single() + arg1 shouldBe instanceOf() + arg2 shouldBe instanceOf() + arg3 shouldBe instanceOf() + arg4 shouldBe instanceOf() + arg5 shouldBe instanceOf() + arg6 shouldBe instanceOf() + } + test("correct typecasts") { val text = """ %import floats diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 9fc81c272..6b8b36cd3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- if passing a subroutine or label name as an uword argument, without &, add the addressof automatically - convert the sounds in cx16 tehtriz to use the psg module instead - notify petaxian that it could use the psg module too?