mirror of
https://github.com/irmen/prog8.git
synced 2024-11-23 07:32:10 +00:00
add missing unit tests and type checking for 'in' expression
This commit is contained in:
parent
b697375573
commit
02c315c194
@ -1208,12 +1208,26 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(containment: ContainmentCheck) {
|
override fun visit(containment: ContainmentCheck) {
|
||||||
if(!containment.iterable.inferType(program).isIterable)
|
val elementDt = containment.element.inferType(program)
|
||||||
errors.err("value set for containment check must be an iterable type", containment.iterable.position)
|
val iterableDt = containment.iterable.inferType(program)
|
||||||
|
|
||||||
if(containment.parent is BinaryExpression)
|
if(containment.parent is BinaryExpression)
|
||||||
errors.err("containment check is currently not supported in complex expressions", containment.position)
|
errors.err("containment check is currently not supported in complex expressions", containment.position)
|
||||||
|
|
||||||
// TODO check that iterable contains the same types as the element that is searched
|
if(iterableDt.isIterable) {
|
||||||
|
val iterableEltDt = ArrayToElementTypes.getValue(iterableDt.getOr(DataType.UNDEFINED))
|
||||||
|
val invalidDt = if (elementDt.isBytes) {
|
||||||
|
iterableEltDt !in ByteDatatypes
|
||||||
|
} else if (elementDt.isWords) {
|
||||||
|
iterableEltDt !in WordDatatypes
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
if (invalidDt)
|
||||||
|
errors.err("element datatype doesn't match iterable datatype", containment.position)
|
||||||
|
} else {
|
||||||
|
errors.err("value set for containment check must be an iterable type", containment.iterable.position)
|
||||||
|
}
|
||||||
|
|
||||||
super.visit(containment)
|
super.visit(containment)
|
||||||
}
|
}
|
||||||
|
@ -134,11 +134,4 @@ _after:
|
|||||||
}
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
|
||||||
if(expr.operator=="in") {
|
|
||||||
println("IN-TEST: $expr\n in: $parent")
|
|
||||||
}
|
|
||||||
return noModifications
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -800,4 +800,50 @@ class TestProg8Parser: FunSpec( {
|
|||||||
val encodedletter = Petscii.encodePetscii("A", true).getOrElse { fail("petscii error") }.single()
|
val encodedletter = Petscii.encodePetscii("A", true).getOrElse { fail("petscii error") }.single()
|
||||||
letter.value shouldBe NumericLiteralValue(DataType.UBYTE, encodedletter.toDouble(), Position.DUMMY)
|
letter.value shouldBe NumericLiteralValue(DataType.UBYTE, encodedletter.toDouble(), Position.DUMMY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("`in` containment checks") {
|
||||||
|
val text="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
str string = "hello"
|
||||||
|
ubyte[] array = [1,2,3,4]
|
||||||
|
|
||||||
|
ubyte cc
|
||||||
|
if cc in [' ', '@', 0] {
|
||||||
|
}
|
||||||
|
|
||||||
|
if cc in "email" {
|
||||||
|
}
|
||||||
|
|
||||||
|
cc = 99 in array
|
||||||
|
cc = '@' in string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
val result = compileText(C64Target, false, text, writeAssembly = false).assertSuccess()
|
||||||
|
val start = result.program.entrypoint
|
||||||
|
val containmentChecks = start.statements.takeLast(4)
|
||||||
|
(containmentChecks[0] as IfElse).condition shouldBe instanceOf<ContainmentCheck>()
|
||||||
|
(containmentChecks[1] as IfElse).condition shouldBe instanceOf<ContainmentCheck>()
|
||||||
|
(containmentChecks[2] as Assignment).value shouldBe instanceOf<ContainmentCheck>()
|
||||||
|
(containmentChecks[3] as Assignment).value shouldBe instanceOf<ContainmentCheck>()
|
||||||
|
}
|
||||||
|
|
||||||
|
test("invalid `in` containment checks") {
|
||||||
|
val text="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
ubyte cc
|
||||||
|
ubyte[] array = [1,2,3]
|
||||||
|
cc = 99 in 12345
|
||||||
|
cc = 9999 in array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(C64Target, false, text, writeAssembly = false, errors = errors).assertFailure()
|
||||||
|
errors.errors.size shouldBe 2
|
||||||
|
errors.errors[0] shouldContain "must be an iterable type"
|
||||||
|
errors.errors[1] shouldContain "datatype doesn't match"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@ -3,8 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.7)
|
For next compiler release (7.7)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- add unit tests for correctly parsing the "in" operator
|
...
|
||||||
|
|
||||||
|
|
||||||
Need help with
|
Need help with
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
Loading…
Reference in New Issue
Block a user