From 1679ca79b4f580af02613e0a4341e86bde6dfec0 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 13 Dec 2024 20:47:03 +0100 Subject: [PATCH] can now use boolean params mapped to Rx register --- .../compiler/astprocessing/AstPreprocessor.kt | 9 +++---- compiler/test/ast/TestAstChecks.kt | 12 +++------ .../src/prog8/ast/statements/AstStatements.kt | 14 +++++++++- docs/source/todo.rst | 4 --- examples/test.p8 | 26 ++++++++++++++----- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt index 7b5d9b2f2..8e120a544 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt @@ -232,12 +232,11 @@ class AstPreprocessor(val program: Program, .filter { it.name !in namesInSub && it.name !in existingAliases } .forEach { if (it.registerOrPair in Cx16VirtualRegisters) { - if(it.type.isInteger) { - val regname = it.registerOrPair!!.asScopedNameVirtualReg(it.type) - var alias = Alias(it.name, IdentifierReference(regname, it.position), it.position) - mods += IAstModification.InsertFirst(alias, subroutine) + if(it.type.isIntegerOrBool) { + val mappedParamVar = VarDecl.fromParameter(it) + mods += IAstModification.InsertFirst(mappedParamVar, subroutine) } else { - errors.err("using R0-R15 as register param requires integer type", it.position) + errors.err("using R0-R15 as register param requires integer or boolean type", it.position) } } else errors.err("can only use R0-R15 as register param for normal subroutines", it.position) diff --git a/compiler/test/ast/TestAstChecks.kt b/compiler/test/ast/TestAstChecks.kt index 693bb80be..94204b434 100644 --- a/compiler/test/ast/TestAstChecks.kt +++ b/compiler/test/ast/TestAstChecks.kt @@ -351,25 +351,21 @@ main { errors.warnings[1] shouldContain "footgun" } - test("reg params R0-R15 cannot be used for non integer types") { + test("reg params R0-R15 cannot be used for invalid types") { val src=""" main { - sub func(bool flag @R1) { - if flag - return + sub func(str value @R1) { + return } - extsub ${'$'}2000 = extok(bool flag @R0) - sub start() { func(true) - extok(true) } }""" val errors = ErrorReporterForTests(keepMessagesAfterReporting = true) compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null errors.errors.size shouldBe 1 errors.warnings.size shouldBe 0 - errors.errors[0] shouldContain "requires integer type" + errors.errors[0] shouldContain "requires integer or boolean type" } }) diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 7f0eec495..ce8e78f13 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -258,8 +258,20 @@ class VarDecl(val type: VarDeclType, private var autoHeapValueSequenceNumber = 0 fun fromParameter(param: SubroutineParameter): VarDecl { + val decltype: VarDeclType + val value: Expression? + if(param.registerOrPair==null) { + // regular parameter variable + decltype = VarDeclType.VAR + value = null + } else { + // parameter variable memory mapped to a R0-R15 virtual register + val regname = param.registerOrPair.asScopedNameVirtualReg(param.type) + decltype = VarDeclType.MEMORY + value = AddressOf(IdentifierReference(regname, param.position), null, param.position) + } val dt = if(param.type.isArray) DataType.forDt(BaseDataType.UWORD) else param.type - return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, null, param.name, emptyList(), null, + return VarDecl(decltype, VarDeclOrigin.SUBROUTINEPARAM, dt, param.zp, null, param.name, emptyList(), value, sharedWithAsm = false, splitArray = false, alignment = 0u, diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bb6532f33..8ebd970cc 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,10 +1,6 @@ TODO ==== -@R0 parameters in normal subs are currently done via injected alias statements. -This means a bool parameter cannot be put into r0 because it is defined as a byte. (error: "using R0-R15 as register param requires integer type") -Can we inject them as regular memory mapped variables instead? &bool param = $02 (where $02 is the zp location of r0L) - ... diff --git a/examples/test.p8 b/examples/test.p8 index c72f5b3cb..b9dd41017 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,15 +3,27 @@ %option no_sysinit main { - sub func(bool flag @R1) { - if flag - return + sub start() { + regparams(true, 42, 9999) } - extsub $2000 = extok(bool flag @R0) + sub regparams(bool arg1 @R0, byte arg2 @R1, uword arg3 @R2) { + txt.print_bool(arg1) + txt.nl() + txt.print_b(arg2) + txt.nl() + txt.print_uw(arg3) + txt.nl() - sub start() { - func(true) - extok(true) + cx16.r0=0 + cx16.r1=$ffff + cx16.r2=11222 + + txt.print_bool(arg1) + txt.nl() + txt.print_b(arg2) + txt.nl() + txt.print_uw(arg3) + txt.nl() } }