diff --git a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt index 9c105a9e9..4d55977d2 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt @@ -85,12 +85,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return when (segment) { is PtFunctionCall -> { val segWithArg = PtFunctionCall(segment.functionName, segment.void, segment.type, segment.position) - segWithArg.children.add(0, PtMachineRegister(sourceReg, sourceDt, segment.position)) + segWithArg.children.add(PtMachineRegister(sourceReg, sourceDt, segment.position)) + segWithArg.children.addAll(segment.args) segWithArg } is PtBuiltinFunctionCall -> { val segWithArg = PtBuiltinFunctionCall(segment.name, segment.void, segment.hasNoSideEffects, segment.type, segment.position) - segWithArg.children.add(0, PtMachineRegister(sourceReg, sourceDt, segment.position)) + segWithArg.children.add(PtMachineRegister(sourceReg, sourceDt, segment.position)) + segWithArg.children.addAll(segment.args) segWithArg } else -> throw AssemblyError("weird segment type") diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index ca5240684..b0cdcc416 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1132,6 +1132,14 @@ internal class AstChecker(private val program: Program, throw FatalAstException("pipe is missing one or more expressions") if(pipe.segments.any { it !is IFunctionCall }) throw FatalAstException("pipe segments can only be function calls") + + if(compilerOptions.compTarget !is VMTarget) { + pipe.segments.forEach { + it as IFunctionCall + if (it.args.size > 0) + errors.err("only unary functions supported in pipe expressions for now", it.position) + } + } } override fun visit(postIncrDecr: PostIncrDecr) { diff --git a/compiler/test/TestPipes.kt b/compiler/test/TestPipes.kt index d82023ad8..c60099b4b 100644 --- a/compiler/test/TestPipes.kt +++ b/compiler/test/TestPipes.kt @@ -17,6 +17,7 @@ import prog8.code.target.C64Target import prog8.compiler.astprocessing.AstPreprocessor import prog8.parser.Prog8Parser.parseModule import prog8.code.core.SourceCode +import prog8.code.target.VMTarget import prog8tests.helpers.* @@ -473,4 +474,39 @@ class TestPipes: FunSpec({ errors.errors[1] shouldContain ":7:42: invalid number of arguments" errors.errors[2] shouldContain ":7:56: invalid number of arguments" } + + test("non-unary funcions in pipe ok for target virtual") { + val text = """ + main { + sub start() { + uword @shared wvalue = add(3,4) |> add(48) |> mkword(234) + } + sub add(ubyte first, ubyte second) -> ubyte { + return first+second + } + }""" + val errors = ErrorReporterForTests() + val result = compileText(VMTarget(), optimize = false, text, writeAssembly = true, errors=errors)!! + errors.errors.size shouldBe 0 + errors.warnings.size shouldBe 0 + result.program.entrypoint.statements.size shouldBe 3 + } + + test("non-unary funcions in pipe not yet ok for other targets") { + // NOTE: once other targets also support this, merge this into the test above + val text = """ + main { + sub start() { + uword @shared wvalue = add(3,4) |> add(48) |> mkword(234) + } + sub add(ubyte first, ubyte second) -> ubyte { + return first+second + } + }""" + val errors = ErrorReporterForTests() + compileText(C64Target(), optimize = false, text, writeAssembly = true, errors=errors) shouldBe null + errors.errors.size shouldBe 2 + errors.errors[0] shouldContain "only unary" + errors.errors[1] shouldContain "only unary" + } }) diff --git a/examples/test.p8 b/examples/test.p8 index a17b0cd6b..3992c3880 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -16,9 +16,14 @@ main { } sub start() { + ; TODO: test with builtin function using multiple args (such as mkword) ubyte source=99 ubyte value = add(3,4) |> add(10) |> mul(2) |> math.sin8u() ; TODO should not work yet on vm codegen, but it compiles.... :/ txt.print_ub(value) + txt.nl() + uword wvalue = add(3,4) |> add($30) |> mkword($ea) + txt.print_uwhex(wvalue, true) + txt.nl() ; expected output: aaabbb aaa bbb