mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
fix some struct type and symbol lookup errors
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
package prog8tests.compiler
|
||||
|
||||
import io.kotest.assertions.withClue
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.engine.spec.tempdir
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import io.kotest.matchers.types.instanceOf
|
||||
import prog8.code.ast.PtReturn
|
||||
import prog8.code.ast.PtSubSignature
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8.vm.VmRunner
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
import kotlin.io.path.readText
|
||||
|
||||
@@ -38,4 +45,169 @@ thing {
|
||||
VmRunner().runProgram(virtfile.readText(), true)
|
||||
}
|
||||
|
||||
test("passing struct instances to subroutines and returning a struct instance is not allowed") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
}
|
||||
|
||||
struct Node {
|
||||
bool flag
|
||||
}
|
||||
|
||||
sub faulty(Node arg) -> Node {
|
||||
return cx16.r0
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors)
|
||||
val err = errors.errors
|
||||
err.size shouldBe 3
|
||||
err[0] shouldContain "uword doesn't match"
|
||||
err[1] shouldContain "structs can only be passed via a pointer"
|
||||
err[2] shouldContain "structs can only be returned via a pointer"
|
||||
}
|
||||
|
||||
test("pointers in subroutine return values") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
^^thing.Node @shared ptr = thing.new()
|
||||
}
|
||||
}
|
||||
|
||||
thing {
|
||||
struct Node {
|
||||
bool flag
|
||||
^^Node next
|
||||
}
|
||||
|
||||
sub new() -> ^^Node {
|
||||
cx16.r0++
|
||||
^^Node pointer = 2000
|
||||
return pointer
|
||||
}
|
||||
}"""
|
||||
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
// TODO compileText(C64Target(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
|
||||
test("creating instances") {
|
||||
val src="""
|
||||
main {
|
||||
struct MyNode {
|
||||
bool flag
|
||||
^^MyNode next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
^^MyNode @shared m1 = MyNode()
|
||||
^^MyNode @shared m2 = MyNode(true, 0)
|
||||
|
||||
^^thing.Node @shared n1 = thing.Node()
|
||||
^^thing.Node @shared n2 = thing.Node(true, 0)
|
||||
}
|
||||
}
|
||||
|
||||
thing {
|
||||
struct Node {
|
||||
bool flag
|
||||
^^Node next
|
||||
}
|
||||
}"""
|
||||
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
compileText(VMTarget(), true, src, outputDir) shouldNotBe null
|
||||
// TODO compileText(C64Target(), false, src, outputDir) shouldNotBe null
|
||||
// TODO compileText(C64Target(), true, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
|
||||
test("creating instances with optimization should all be removed") {
|
||||
val src="""
|
||||
main {
|
||||
struct MyNode {
|
||||
bool flag
|
||||
^^MyNode next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
^^MyNode m1 = MyNode()
|
||||
^^MyNode m2 = MyNode(true, 0)
|
||||
|
||||
^^thing.Node n1 = thing.Node()
|
||||
^^thing.Node n2 = thing.Node(true, 0)
|
||||
}
|
||||
}
|
||||
|
||||
thing {
|
||||
struct Node {
|
||||
bool flag
|
||||
^^Node next
|
||||
}
|
||||
}"""
|
||||
|
||||
var result = compileText(VMTarget(), true, src, outputDir)!!
|
||||
withClue("all variables should have been optimized away") {
|
||||
val start = result.codegenAst!!.entrypoint()!!
|
||||
start.children.size shouldBe 2
|
||||
start.children[0] shouldBe instanceOf<PtSubSignature>()
|
||||
start.children[1] shouldBe instanceOf<PtReturn>()
|
||||
}
|
||||
// TODO compileText(C64Target(), true, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
|
||||
test("creating instances should have correct number of args") {
|
||||
val src="""
|
||||
main {
|
||||
struct Node {
|
||||
bool flag
|
||||
ubyte value
|
||||
^^Node next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
^^Node ptr = Node(true) ; error
|
||||
}
|
||||
}"""
|
||||
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors)
|
||||
val err = errors.errors
|
||||
err.size shouldBe 1
|
||||
err[0] shouldContain("expected 3 or 0, got 1")
|
||||
}
|
||||
|
||||
|
||||
test("pointer uword compatibility") {
|
||||
val src="""
|
||||
main {
|
||||
struct MyNode {
|
||||
bool flag
|
||||
^^MyNode next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
cx16.r0 = MyNode()
|
||||
|
||||
^^MyNode @shared ptr1 = cx16.r0
|
||||
|
||||
ptr1 = 2000
|
||||
ptr1 = 20
|
||||
ptr1 = 20.2222
|
||||
}
|
||||
}"""
|
||||
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors)
|
||||
val err = errors.errors
|
||||
err.size shouldBe 1
|
||||
err[0] shouldContain("15:16: can only assign uword or correct pointer type to a pointer")
|
||||
}
|
||||
|
||||
})
|
||||
@@ -73,7 +73,7 @@ class TestSubroutines: FunSpec({
|
||||
func.statements.isEmpty() shouldBe true
|
||||
}
|
||||
|
||||
test("cannot call a subroutine via pointer") {
|
||||
test("cannot call a subroutine via a pointer") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
|
||||
Reference in New Issue
Block a user