mirror of
https://github.com/irmen/prog8.git
synced 2026-04-21 02:16:41 +00:00
fix a ptr indexing error
This commit is contained in:
@@ -424,6 +424,9 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
||||
}
|
||||
|
||||
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(parent is PtrIndexedDereference)
|
||||
return noModifications
|
||||
|
||||
if(arrayIndexedExpression.indexer.constIndex()==0) {
|
||||
val dt = arrayIndexedExpression.arrayvar.inferType(program).getOrUndef()
|
||||
if(dt.isPointer) {
|
||||
|
||||
@@ -220,8 +220,13 @@ _after:
|
||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl()
|
||||
if(arrayVar!=null && (arrayVar.datatype.isUnsignedWord || (arrayVar.datatype.isPointer && arrayVar.datatype.sub==BaseDataType.UBYTE))) {
|
||||
val wordIndex = TypecastExpression(indexExpr, DataType.UWORD, true, indexExpr.position)
|
||||
val address = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", wordIndex, arrayIndexedExpression.position)
|
||||
return if(parent is AssignTarget) {
|
||||
val address = BinaryExpression(
|
||||
arrayIndexedExpression.arrayvar.copy(),
|
||||
"+",
|
||||
wordIndex,
|
||||
arrayIndexedExpression.position
|
||||
)
|
||||
return if (parent is AssignTarget) {
|
||||
// assignment to array
|
||||
val memwrite = DirectMemoryWrite(address, arrayIndexedExpression.position)
|
||||
val newtarget = AssignTarget(
|
||||
@@ -238,6 +243,8 @@ _after:
|
||||
val memread = DirectMemoryRead(address, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
}
|
||||
} else if(arrayVar!=null && (arrayVar.datatype.isPointer || arrayVar.datatype.isArray)) {
|
||||
return noModifications
|
||||
} else {
|
||||
// it could be a pointer dereference instead of a simple array variable
|
||||
val dt = arrayIndexedExpression.arrayvar.traverseDerefChainForDt(null)
|
||||
|
||||
@@ -108,7 +108,8 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
val type = idxderef.inferType(program).getOrElse {
|
||||
throw FatalAstException("unknown dt")
|
||||
}
|
||||
val deref = PtPointerIndexedDeref(type, idxderef.position)
|
||||
require(type.isPointer && type.sub!=null)
|
||||
val deref = PtPointerIndexedDeref(DataType.forDt(type.sub!!), idxderef.position)
|
||||
deref.add(transform(idxderef.indexed))
|
||||
return deref
|
||||
}
|
||||
@@ -697,7 +698,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
}
|
||||
|
||||
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
||||
val dt = srcArr.arrayvar.targetVarDecl()!!.datatype
|
||||
val dt = srcArr.arrayvar.inferType(program)
|
||||
if(!dt.isArray && !dt.isString && !dt.isPointer)
|
||||
throw FatalAstException("array indexing can only be used on array, string or pointer variables ${srcArr.position}")
|
||||
val eltType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
|
||||
@@ -7,6 +7,7 @@ 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.PtAssignment
|
||||
import prog8.code.ast.PtReturn
|
||||
import prog8.code.ast.PtSubSignature
|
||||
import prog8.code.core.BaseDataType
|
||||
@@ -292,4 +293,25 @@ main {
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
test("uword as pointer versus pointer to uword difference") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
uword @shared ptr1
|
||||
^^uword @shared ptr2
|
||||
|
||||
ptr1[2] = 1
|
||||
ptr2[2] = 1
|
||||
}
|
||||
}"""
|
||||
|
||||
val result = compileText(VMTarget(), false, src, outputDir)!!
|
||||
val st = result.codegenAst!!.entrypoint()!!.children
|
||||
st.size shouldBe 8
|
||||
val a1 = st[5] as PtAssignment
|
||||
val a2 = st[6] as PtAssignment
|
||||
a1.target.memory shouldNotBe null
|
||||
a2.target.array shouldNotBe null
|
||||
}
|
||||
|
||||
})
|
||||
@@ -428,6 +428,12 @@ class ArrayIndexedExpression(var arrayvar: IdentifierReference,
|
||||
}
|
||||
else -> InferredTypes.knownFor(target.datatype)
|
||||
}
|
||||
} else {
|
||||
val dt = arrayvar.inferType(program).getOrUndef()
|
||||
if(dt.isPointer) {
|
||||
if(dt.sub!=null)
|
||||
return InferredTypes.knownFor(dt.sub!!)
|
||||
}
|
||||
}
|
||||
return InferredTypes.unknown()
|
||||
}
|
||||
@@ -1340,6 +1346,9 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
||||
InferredTypes.knownFor(targetStmt.datatype)
|
||||
}
|
||||
null -> {
|
||||
val param = definingSubroutine?.parameters?.find { it.name==nameInSource.singleOrNull() }
|
||||
if(param!=null)
|
||||
return InferredTypes.knownFor(param.type)
|
||||
val fieldType = traverseDerefChainForDt(null)
|
||||
if(fieldType.isUndefined)
|
||||
InferredTypes.unknown()
|
||||
@@ -1363,6 +1372,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
||||
val vardecl = definingScope.lookup(nameInSource.take(1)) as? VarDecl
|
||||
if (vardecl?.datatype?.isPointer != true)
|
||||
return DataType.UNDEFINED
|
||||
require(vardecl.datatype.subType!=null) { "pointer type should point to a struct ${vardecl.position}" }
|
||||
struct = vardecl.datatype.subType as StructDecl
|
||||
fieldDt = vardecl.datatype
|
||||
}
|
||||
@@ -1625,7 +1635,8 @@ class PtrIndexedDereference(val indexed: ArrayIndexedExpression, override val po
|
||||
return InferredTypes.unknown()
|
||||
}
|
||||
|
||||
override fun replaceChildNode(node: Node, replacement: Node) = throw FatalAstException("can't replace here")
|
||||
override fun replaceChildNode(node: Node, replacement: Node) =
|
||||
throw FatalAstException("can't replace here")
|
||||
override fun referencesIdentifier(nameInSource: List<String>) = indexed.referencesIdentifier(nameInSource)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user