mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
cleaning up pointer indexing
This commit is contained in:
@@ -322,7 +322,7 @@ class TestMemory: FunSpec({
|
||||
test("array not in mapped IO ram") {
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.arrayFor(BaseDataType.UBYTE), ZeropageWish.DONTCARE,
|
||||
SplitWish.DONTCARE, null, "address", emptyList(), null, false, 0u, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), null, ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, null, false, position = Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
@@ -336,7 +336,7 @@ class TestMemory: FunSpec({
|
||||
val address = 0x1000u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.arrayFor(BaseDataType.UBYTE), ZeropageWish.DONTCARE,
|
||||
SplitWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, 0u, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), null, ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, null, false, position = Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
@@ -350,7 +350,7 @@ class TestMemory: FunSpec({
|
||||
val address = 0xd800u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.arrayFor(BaseDataType.UBYTE), ZeropageWish.DONTCARE,
|
||||
SplitWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, 0u, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), null, ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, null, false, position = Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), mutableListOf(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
|
||||
@@ -7,6 +7,8 @@ import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import io.kotest.matchers.types.instanceOf
|
||||
import prog8.ast.expressions.ArrayIndexedExpression
|
||||
import prog8.ast.expressions.DirectMemoryRead
|
||||
import prog8.ast.expressions.PtrDereference
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.VarDecl
|
||||
@@ -193,6 +195,8 @@ main {
|
||||
cx16.r1 = matchstate^^.next^^.next^^.ptr
|
||||
cx16.r2 = matchstate.ptr
|
||||
cx16.r3 = matchstate.next.next.ptr
|
||||
cx16.r4 = matchstate.ptr^^
|
||||
cx16.r5 = matchstate.next.next.ptr^^
|
||||
|
||||
matchstate^^.ptr = 2222
|
||||
matchstate^^.next^^.next^^.ptr = 2222
|
||||
@@ -203,7 +207,7 @@ main {
|
||||
|
||||
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 11
|
||||
st.size shouldBe 13
|
||||
val a0v = (st[2] as Assignment).value as PtrDereference
|
||||
a0v.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
a0v.chain.size shouldBe 0
|
||||
@@ -228,31 +232,98 @@ main {
|
||||
a3v.field shouldBe "ptr"
|
||||
a3v.derefPointerValue shouldBe false
|
||||
|
||||
val t0 = (st[6] as Assignment).target.pointerDereference!!
|
||||
val a4v = (st[6] as Assignment).value as PtrDereference
|
||||
a4v.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
a4v.chain shouldBe listOf("ptr")
|
||||
a4v.field shouldBe null
|
||||
a4v.derefPointerValue shouldBe true
|
||||
|
||||
val a5v = (st[7] as Assignment).value as PtrDereference
|
||||
a5v.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
a5v.chain shouldBe listOf("next", "next", "ptr")
|
||||
a5v.field shouldBe null
|
||||
a5v.derefPointerValue shouldBe true
|
||||
|
||||
val t0 = (st[8] as Assignment).target.pointerDereference!!
|
||||
t0.derefPointerValue shouldBe false
|
||||
t0.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
t0.chain.size shouldBe 0
|
||||
t0.field shouldBe "ptr"
|
||||
|
||||
val t1 = (st[7] as Assignment).target.pointerDereference!!
|
||||
val t1 = (st[9] as Assignment).target.pointerDereference!!
|
||||
t1.derefPointerValue shouldBe false
|
||||
t1.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
t1.chain shouldBe listOf("next", "next")
|
||||
t1.field shouldBe "ptr"
|
||||
|
||||
val t2 = (st[8] as Assignment).target.pointerDereference!!
|
||||
val t2 = (st[10] as Assignment).target.pointerDereference!!
|
||||
t2.derefPointerValue shouldBe false
|
||||
t2.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
t2.chain.size shouldBe 0
|
||||
t2.field shouldBe "ptr"
|
||||
|
||||
val t3 = (st[9] as Assignment).target.pointerDereference!!
|
||||
val t3 = (st[11] as Assignment).target.pointerDereference!!
|
||||
t3.derefPointerValue shouldBe false
|
||||
t3.identifier.nameInSource shouldBe listOf("matchstate")
|
||||
t3.chain shouldBe listOf("next", "next")
|
||||
t3.field shouldBe "ptr"
|
||||
}
|
||||
|
||||
test("word size pointer indexing on pointers") {
|
||||
val src="""
|
||||
%option enable_floats
|
||||
|
||||
main {
|
||||
|
||||
struct List {
|
||||
^^uword s
|
||||
ubyte n
|
||||
^^List next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
ubyte[10] array
|
||||
uword @shared wordptr
|
||||
^^bool @shared boolptr
|
||||
^^float @shared floatptr
|
||||
^^byte @shared byteptr
|
||||
^^ubyte @shared ubyteptr
|
||||
^^List @shared listptr
|
||||
^^List @shared listptr2
|
||||
|
||||
bool @shared zz
|
||||
float @shared fl
|
||||
byte @shared bb
|
||||
|
||||
zz = boolptr[999]
|
||||
fl = floatptr[999]
|
||||
bb = byteptr[999]
|
||||
cx16.r0L = ubyteptr[999]
|
||||
cx16.r1L = wordptr[999]
|
||||
cx16.r2L = array[9]
|
||||
listptr2 = listptr[999]
|
||||
}
|
||||
}"""
|
||||
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 28
|
||||
|
||||
val a_zz = (st[20] as Assignment).value
|
||||
a_zz shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
val a_fl = (st[21] as Assignment).value
|
||||
a_fl shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
val a_bb = (st[22] as Assignment).value
|
||||
a_bb shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
val a_r0 = (st[23] as Assignment).value
|
||||
a_r0 shouldBe instanceOf<DirectMemoryRead>()
|
||||
val a_r1 = (st[24] as Assignment).value
|
||||
a_r1 shouldBe instanceOf<DirectMemoryRead>()
|
||||
val a_r2 = (st[25] as Assignment).value
|
||||
a_r2 shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
val a_lptr2 = (st[25] as Assignment).value
|
||||
a_lptr2 shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
}
|
||||
|
||||
test("block scoping still parsed correctly") {
|
||||
val src="""
|
||||
main {
|
||||
@@ -551,6 +622,9 @@ main {
|
||||
}
|
||||
sub start() {
|
||||
^^List @shared l1 = List()
|
||||
bool ss = l1.s[1]
|
||||
ubyte ub = l1.n[1]
|
||||
uword uw = l1.ptr[1]
|
||||
l1.s[1] = 4444
|
||||
l1.n[1] = true
|
||||
l1.ptr[1] = 4444
|
||||
@@ -559,10 +633,15 @@ main {
|
||||
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors) shouldBe null
|
||||
errors.errors.size shouldBe 4
|
||||
errors.errors[0] shouldContain "cannot array index"
|
||||
errors.errors.size shouldBe 8
|
||||
errors.errors[0] shouldContain "invalid assignment value"
|
||||
errors.errors[1] shouldContain "cannot array index"
|
||||
errors.errors[2] shouldContain "out of range"
|
||||
errors.errors[2] shouldContain "invalid assignment value"
|
||||
errors.errors[3] shouldContain "cannot array index"
|
||||
errors.errors[4] shouldContain "cannot array index"
|
||||
errors.errors[5] shouldContain "cannot array index"
|
||||
errors.errors[6] shouldContain "out of range"
|
||||
errors.errors[7] shouldContain "cannot assign word to byte"
|
||||
}
|
||||
|
||||
test("dereferences of ptr variables mark those as used in the callgraph") {
|
||||
@@ -604,24 +683,26 @@ main {
|
||||
}
|
||||
sub start() {
|
||||
^^List l1 = List()
|
||||
cx16.r0 = l1.s[0]
|
||||
l1.s[0] = 4242
|
||||
cx16.r1 = l1.s^^
|
||||
|
||||
^^word @shared wptr
|
||||
|
||||
cx16.r1 = l1.s^^
|
||||
cx16.r0 = l1.s[0]
|
||||
cx16.r2 = l1^^.s^^
|
||||
l1.s[0] = 4242
|
||||
cx16.r1 = l1.s^^
|
||||
|
||||
cx16.r0s = wptr[0]
|
||||
cx16.r1s = wptr^^
|
||||
wptr[0] = 4242
|
||||
cx16.r1s = wptr^^
|
||||
wptr[0] = 4242
|
||||
}
|
||||
|
||||
}"""
|
||||
|
||||
val result = compileText(VMTarget(), true, src, outputDir, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 11
|
||||
val dr0 = (st[2] as Assignment).value as PtrDereference
|
||||
val dr1 = (st[3] as Assignment).target.pointerDereference!!
|
||||
val dr2 = (st[4] as Assignment).value as PtrDereference
|
||||
val dr0 = (st[4] as Assignment).value as PtrDereference
|
||||
val dr1 = (st[5] as Assignment).target.pointerDereference!!
|
||||
val dr2 = (st[6] as Assignment).value as PtrDereference
|
||||
|
||||
val dr3 = (st[7] as Assignment).value as PtrDereference
|
||||
val dr4 = (st[8] as Assignment).value as PtrDereference
|
||||
|
||||
@@ -124,16 +124,17 @@ class TestAstChecks: FunSpec({
|
||||
main {
|
||||
sub start() {
|
||||
&ubyte a = 10000
|
||||
uword @shared z = 500
|
||||
a[4] = (z % 3) as ubyte
|
||||
cx16.r0L = a[4]
|
||||
a[4] = cx16.r1L
|
||||
}
|
||||
}
|
||||
"""
|
||||
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
|
||||
compileText(C64Target(), true, text, outputDir, writeAssembly = true, errors=errors)
|
||||
errors.errors.size shouldBe 1
|
||||
errors.errors.size shouldBe 2
|
||||
errors.warnings.size shouldBe 0
|
||||
errors.errors[0] shouldContain "indexing requires"
|
||||
errors.errors[1] shouldContain "indexing requires"
|
||||
}
|
||||
|
||||
test("unicode in identifier names is working") {
|
||||
|
||||
Reference in New Issue
Block a user