mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
fix bool param lookup problem
This commit is contained in:
parent
bdb7de34be
commit
1163543a98
@ -159,7 +159,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
}
|
||||
argOrder.forEach {
|
||||
val param = callee.parameters[it]
|
||||
val targetVar = callee.searchAsmParameter(param.name)!!
|
||||
val targetVar = callee.searchParameter(param.name)!!
|
||||
asmgen.popCpuStack(param.type, targetVar, (call as Node).definingSubroutine)
|
||||
}
|
||||
}
|
||||
|
@ -55,9 +55,10 @@ internal class VerifyFunctionArgTypes(val program: Program, val errors: IErrorRe
|
||||
return Pair("invalid number of arguments", call.position)
|
||||
val mismatch = argtypes.zip(consideredParamTypes).indexOfFirst { !argTypeCompatible(it.first, it.second) }
|
||||
if(mismatch>=0) {
|
||||
val actual = argtypes[mismatch].toString()
|
||||
val expected = consideredParamTypes[mismatch].toString()
|
||||
return Pair("argument ${mismatch + 1} type mismatch, was: $actual expected: $expected", call.args[mismatch].position)
|
||||
val actual = argtypes[mismatch]
|
||||
val expected = consideredParamTypes[mismatch]
|
||||
if(expected==DataType.BOOL && actual==DataType.UBYTE && call.args[mismatch].constValue(program)?.number !in setOf(0.0, 1.0))
|
||||
return Pair("argument ${mismatch + 1} type mismatch, was: $actual expected: $expected", call.args[mismatch].position)
|
||||
}
|
||||
if(target.isAsmSubroutine) {
|
||||
if(target.asmReturnvaluesRegisters.size>1) {
|
||||
@ -85,9 +86,9 @@ internal class VerifyFunctionArgTypes(val program: Program, val errors: IErrorRe
|
||||
argtypes.zip(consideredParamTypes).forEachIndexed { index, pair ->
|
||||
val anyCompatible = pair.second.any { argTypeCompatible(pair.first, it) }
|
||||
if (!anyCompatible) {
|
||||
val actual = pair.first.toString()
|
||||
val actual = pair.first
|
||||
return if(pair.second.size==1) {
|
||||
val expected = pair.second[0].toString()
|
||||
val expected = pair.second[0]
|
||||
Pair("argument ${index + 1} type mismatch, was: $actual expected: $expected", call.args[index].position)
|
||||
} else {
|
||||
val expected = pair.second.toList().toString()
|
||||
|
@ -7,15 +7,54 @@ 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.ast.expressions.*
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.IfElse
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.compiler.printProgram
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
|
||||
class TestTypecasts: FunSpec({
|
||||
|
||||
test("correct handling of bool parameters") {
|
||||
val text="""
|
||||
main {
|
||||
|
||||
sub thing(bool b1, bool b2) -> bool {
|
||||
return (b1 and b2) or b1
|
||||
}
|
||||
|
||||
sub start() {
|
||||
bool boolvalue1 = true
|
||||
bool boolvalue2 = false
|
||||
uword xx
|
||||
|
||||
boolvalue1 = thing(true, false)
|
||||
boolvalue2 = thing(xx, xx)
|
||||
|
||||
if boolvalue1 and boolvalue2
|
||||
boolvalue1=false
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
|
||||
val stmts = result.program.entrypoint.statements
|
||||
stmts.size shouldBe 9
|
||||
val fcall1 = ((stmts[6] as Assignment).value as IFunctionCall)
|
||||
fcall1.args[0] shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY)
|
||||
fcall1.args[1] shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||
val fcall2 = ((stmts[7] as Assignment).value as IFunctionCall)
|
||||
(fcall2.args[0] as TypecastExpression).type shouldBe DataType.BOOL
|
||||
(fcall2.args[1] as TypecastExpression).type shouldBe DataType.BOOL
|
||||
val ifCond = (stmts[8] as IfElse).condition as BinaryExpression
|
||||
ifCond.operator shouldBe "&"
|
||||
(ifCond.left as IdentifierReference).nameInSource shouldBe listOf("boolvalue1")
|
||||
(ifCond.right as IdentifierReference).nameInSource shouldBe listOf("boolvalue2")
|
||||
}
|
||||
|
||||
test("correct evaluation of words in boolean expressions") {
|
||||
val text="""
|
||||
main {
|
||||
|
@ -77,7 +77,7 @@ interface IStatementContainer {
|
||||
|
||||
fun searchSymbol(name: String): Statement? {
|
||||
if(this is Subroutine && isAsmSubroutine)
|
||||
return searchAsmParameter(name)
|
||||
return searchParameter(name)
|
||||
|
||||
// this is called quite a lot and could perhaps be optimized a bit more,
|
||||
// but adding a memoization cache didn't make much of a practical runtime difference...
|
||||
@ -138,6 +138,10 @@ interface IStatementContainer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this is Subroutine && !isAsmSubroutine)
|
||||
return searchParameter(name)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -770,9 +770,7 @@ class Subroutine(override val name: String,
|
||||
// code to provide the ability to reference asmsub parameters via qualified name:
|
||||
private val asmParamsDecls = mutableMapOf<String, VarDecl>()
|
||||
|
||||
fun searchAsmParameter(name: String): VarDecl? {
|
||||
require(isAsmSubroutine)
|
||||
|
||||
fun searchParameter(name: String): VarDecl? {
|
||||
val existingDecl = asmParamsDecls[name]
|
||||
if(existingDecl!=null)
|
||||
return existingDecl
|
||||
|
@ -5,9 +5,6 @@ For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- add ARRAY_OF_BOOL array type
|
||||
|
||||
- test various scenarios of using bool type vs byte actually produces tighter code
|
||||
make unit test of them?
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
@ -3,22 +3,19 @@
|
||||
|
||||
main {
|
||||
|
||||
bool boolvalue1 = true
|
||||
bool boolvalue2 = false
|
||||
ubyte @shared ubvalue1 = true
|
||||
ubyte @shared ubvalue2 = false
|
||||
|
||||
sub thing(bool b1, bool b2) -> bool {
|
||||
return b1 and b2
|
||||
return (b1 and b2) or b1
|
||||
}
|
||||
|
||||
sub start() {
|
||||
bool boolvalue1 = true
|
||||
bool boolvalue2 = false
|
||||
uword xx
|
||||
|
||||
ubvalue1 = boolvalue1 & 1
|
||||
ubvalue2 = 1 & boolvalue1
|
||||
ubvalue1 = boolvalue1 & 0
|
||||
ubvalue2 = boolvalue1 & 8
|
||||
boolvalue1 = boolvalue2 & 1 ==0
|
||||
; boolvar & 1 -> boolvar, (boolvar & 1 == 0) -> not boolvar
|
||||
boolvalue1 = thing(true, false)
|
||||
boolvalue2 = thing(xx, xx)
|
||||
|
||||
if boolvalue1 and boolvalue2
|
||||
boolvalue1=false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user