mirror of
https://github.com/irmen/prog8.git
synced 2025-11-24 06:17:39 +00:00
partly fix weird errors for ptr indexed expressions
This commit is contained in:
@@ -2362,6 +2362,12 @@ internal class AstChecker(private val program: Program,
|
||||
errors.err("on..goto index must be an unsigned byte", onGoto.index.position)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visit(idxderef: PtrIndexedDereference) {
|
||||
val dt = idxderef.indexed.arrayvar.inferType(program)
|
||||
if(!dt.isUnsignedWord && !dt.isPointer)
|
||||
errors.err("cannot array index on this field type", idxderef.indexed.position)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun checkUnusedReturnValues(call: FunctionCallStatement, target: Statement, errors: IErrorReporter) {
|
||||
|
||||
@@ -108,14 +108,18 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
||||
val type = idxderef.inferType(program).getOrElse {
|
||||
throw FatalAstException("unknown dt")
|
||||
}
|
||||
require(type.isPointer && type.sub!=null)
|
||||
val deref = PtPointerIndexedDeref(DataType.forDt(type.sub!!), idxderef.position)
|
||||
val indexer = PtArrayIndexer(DataType.forDt(type.sub!!), idxderef.position)
|
||||
val identifier = PtIdentifier(idxderef.indexed.arrayvar.nameInSource.joinToString("."), type, idxderef.indexed.arrayvar.position)
|
||||
indexer.add(identifier)
|
||||
indexer.add(transformExpression(idxderef.indexed.indexer.indexExpr))
|
||||
deref.add(indexer)
|
||||
return deref
|
||||
require(type.isPointer || type.isUnsignedWord)
|
||||
if(type.isUnsignedWord) {
|
||||
TODO("indexing uword field $idxderef") // TODO hmm, wasn't there code elsewhere for this already?
|
||||
} else {
|
||||
val deref = PtPointerIndexedDeref(DataType.forDt(type.sub!!), idxderef.position)
|
||||
val indexer = PtArrayIndexer(DataType.forDt(type.sub!!), idxderef.position)
|
||||
val identifier = PtIdentifier(idxderef.indexed.arrayvar.nameInSource.joinToString("."), type, idxderef.indexed.arrayvar.position)
|
||||
indexer.add(identifier)
|
||||
indexer.add(transformExpression(idxderef.indexed.indexer.indexExpr))
|
||||
deref.add(indexer)
|
||||
return deref
|
||||
}
|
||||
}
|
||||
|
||||
private fun transform(deref: PtrDereference): PtPointerDeref {
|
||||
|
||||
@@ -314,4 +314,28 @@ main {
|
||||
a2.target.array shouldNotBe null
|
||||
}
|
||||
|
||||
test("array indexing on non pointer fields give correct error messages") {
|
||||
val src="""
|
||||
main {
|
||||
struct List {
|
||||
bool s
|
||||
ubyte n
|
||||
uword ptr
|
||||
}
|
||||
sub start() {
|
||||
^^List @shared l1 = List()
|
||||
l1.s[1] = 4444
|
||||
l1.n[1] = true
|
||||
l1.ptr[1] = 4444
|
||||
}
|
||||
}"""
|
||||
|
||||
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[1] shouldContain "cannot array index"
|
||||
errors.errors[2] shouldContain "out of range"
|
||||
}
|
||||
|
||||
})
|
||||
@@ -1624,12 +1624,17 @@ class PtrIndexedDereference(val indexed: ArrayIndexedExpression, override val po
|
||||
TODO("cannot determine type of dereferenced indexed pointer(?) that is not a pointer to a basic type")
|
||||
}
|
||||
|
||||
if(parent is AssignTarget) {
|
||||
if(parent is AssignTarget || parent is Assignment) {
|
||||
val dt = indexed.arrayvar.traverseDerefChainForDt(null)
|
||||
return if(dt.isUndefined)
|
||||
InferredTypes.unknown()
|
||||
else
|
||||
InferredTypes.knownFor(dt)
|
||||
return when {
|
||||
dt.isUndefined -> InferredTypes.unknown()
|
||||
dt.isUnsignedWord -> InferredTypes.knownFor(BaseDataType.UBYTE)
|
||||
dt.isPointer -> {
|
||||
return if(dt.sub!=null) InferredTypes.knownFor(dt.sub!!)
|
||||
else InferredTypes.unknown()
|
||||
}
|
||||
else -> InferredTypes.unknown()
|
||||
}
|
||||
}
|
||||
|
||||
return InferredTypes.unknown()
|
||||
|
||||
@@ -1,55 +1,25 @@
|
||||
main {
|
||||
struct List {
|
||||
bool s
|
||||
^^uword s
|
||||
ubyte n
|
||||
}
|
||||
sub start() {
|
||||
^^List l1 = List() ; TODO fix unused var removal
|
||||
l1.s[2] = 1
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
main {
|
||||
struct List {
|
||||
^^uword s
|
||||
ubyte n
|
||||
}
|
||||
sub start() {
|
||||
^^List @shared l1 = List()
|
||||
l1.s[1] = 4444 ; TODO wrong error message, instead should give an error that you can't index a boolean (only uword or pointer)
|
||||
l1.s[1] = true ; TODO should give an error that you can't index a boolean (only uword or pointer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
main {
|
||||
struct List {
|
||||
bool s
|
||||
ubyte n
|
||||
}
|
||||
sub start() {
|
||||
^^List @shared l1 = List() ; TODO gets removed as 'unused var' when not @shared
|
||||
l1.s[0] = true
|
||||
cx16.r0= l1.s[2]
|
||||
;l1.s[l1.n] = 1
|
||||
;l1.s[0] = 2
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
main {
|
||||
struct List {
|
||||
^^uword s
|
||||
ubyte n
|
||||
}
|
||||
sub start() {
|
||||
^^List l1 = List()
|
||||
l1.s[l1.n] = 1
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
main {
|
||||
struct List {
|
||||
^^uword s
|
||||
ubyte n
|
||||
}
|
||||
sub start() {
|
||||
^^List l1 = List()
|
||||
l1.s[l1.n] = 1
|
||||
l1.s[0] = 2
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user