mirror of
https://github.com/irmen/prog8.git
synced 2025-10-25 05:18:38 +00:00
fix ptr errors
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,10 +7,13 @@ build/
|
||||
dist/
|
||||
output/
|
||||
out/
|
||||
out-new/
|
||||
out-old/
|
||||
.*cache/
|
||||
*.directory
|
||||
*.prg
|
||||
*.bin
|
||||
*.p8ir
|
||||
*.labels.txt
|
||||
*.vm.txt
|
||||
*.vice-mon-list
|
||||
|
||||
@@ -202,6 +202,17 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
|
||||
}
|
||||
}
|
||||
|
||||
fun dereference(): DataType {
|
||||
require(isPointer || isUnsignedWord)
|
||||
return when {
|
||||
isUnsignedWord -> forDt(BaseDataType.UBYTE)
|
||||
sub!=null -> forDt(sub)
|
||||
subType!=null -> DataType(BaseDataType.STRUCT_INSTANCE, null, subType)
|
||||
subTypeFromAntlr!=null -> DataType(BaseDataType.STRUCT_INSTANCE, null, null, subTypeFromAntlr)
|
||||
else -> throw IllegalArgumentException("cannot dereference this pointer type")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = when(base) {
|
||||
BaseDataType.ARRAY -> {
|
||||
when(sub) {
|
||||
|
||||
@@ -166,10 +166,6 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
|
||||
}
|
||||
|
||||
override fun visit(deref: PtrDereference) {
|
||||
val first = deref.identifier.targetStatement()
|
||||
if(first==null)
|
||||
errors.undefined(deref.identifier.nameInSource, deref.identifier.position)
|
||||
|
||||
if(deref.field!=null) {
|
||||
// check chain and field
|
||||
val dt = deref.identifier.inferType(program).getOrUndef()
|
||||
@@ -191,10 +187,6 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter,
|
||||
if(fieldDt==null) {
|
||||
errors.err("unknown field '${deref.field}' in struct '${struct.name}'", deref.position)
|
||||
}
|
||||
} else {
|
||||
if (first !is VarDecl || !first.datatype.isStructInstance) {
|
||||
errors.err("cannot find struct type", deref.identifier.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -507,6 +507,18 @@ _after:
|
||||
return listOf(IAstModification.ReplaceNode(deref, memread, parent))
|
||||
}
|
||||
}
|
||||
|
||||
if(deref.chain.isEmpty() && deref.field==null) {
|
||||
val expr = deref.parent as? BinaryExpression
|
||||
if (expr != null && expr.operator == ".") {
|
||||
if (expr.left is IdentifierReference && expr.right === deref) {
|
||||
// replace (a) . (b^^) by (a.b)^^
|
||||
val identifier = IdentifierReference((expr.left as IdentifierReference).nameInSource + deref.identifier.nameInSource, expr.left.position)
|
||||
val replacement = PtrDereference(identifier, emptyList(), null, deref.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, replacement, expr.parent))
|
||||
}
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
||||
@@ -393,9 +393,9 @@ main {
|
||||
val dr1 = (st[3] as Assignment).target.pointerDereference!!
|
||||
val dr2 = (st[4] as Assignment).value as PtrDereference
|
||||
|
||||
val dr3 = (st[6] as Assignment).value as PtrDereference
|
||||
val dr4 = (st[7] as Assignment).value as PtrDereference
|
||||
val dr5 = (st[8] as Assignment).target.pointerDereference!!
|
||||
val dr3 = (st[7] as Assignment).value as PtrDereference
|
||||
val dr4 = (st[8] as Assignment).value as PtrDereference
|
||||
val dr5 = (st[9] as Assignment).target.pointerDereference!!
|
||||
|
||||
dr0.identifier.nameInSource shouldBe listOf("l1", "s")
|
||||
dr0.chain.size shouldBe 0
|
||||
|
||||
@@ -1631,7 +1631,7 @@ class PtrIndexedDereference(val indexed: ArrayIndexedExpression, override val po
|
||||
val vardecl = indexed.arrayvar.targetVarDecl()
|
||||
if(vardecl!=null &&vardecl.datatype.isPointer) {
|
||||
if(vardecl.datatype.sub!=null)
|
||||
return InferredTypes.knownFor(vardecl.datatype.sub!!)
|
||||
return InferredTypes.knownFor(vardecl.datatype.dereference())
|
||||
TODO("cannot determine type of dereferenced indexed pointer(?) that is not a pointer to a basic type")
|
||||
}
|
||||
|
||||
@@ -1641,7 +1641,7 @@ class PtrIndexedDereference(val indexed: ArrayIndexedExpression, override val po
|
||||
dt.isUndefined -> InferredTypes.unknown()
|
||||
dt.isUnsignedWord -> InferredTypes.knownFor(BaseDataType.UBYTE)
|
||||
dt.isPointer -> {
|
||||
return if(dt.sub!=null) InferredTypes.knownFor(dt.sub!!)
|
||||
return if(dt.sub!=null) InferredTypes.knownFor(dt.dereference())
|
||||
else InferredTypes.unknown()
|
||||
}
|
||||
else -> InferredTypes.unknown()
|
||||
@@ -1657,6 +1657,8 @@ class PtrIndexedDereference(val indexed: ArrayIndexedExpression, override val po
|
||||
}
|
||||
|
||||
class PtrDereference(val identifier: IdentifierReference, val chain: List<String>, val field: String?, override val position: Position) : Expression() {
|
||||
// TODO why both identifier and chain?
|
||||
|
||||
override lateinit var parent: Node
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
@@ -1674,7 +1676,7 @@ class PtrDereference(val identifier: IdentifierReference, val chain: List<String
|
||||
if(first==null)
|
||||
return InferredTypes.unknown()
|
||||
if(first is StructFieldRef) {
|
||||
return InferredTypes.knownFor(first.type)
|
||||
return InferredTypes.knownFor(first.type.dereference())
|
||||
}
|
||||
val vardecl = identifier.targetVarDecl()
|
||||
if(vardecl==null || vardecl.datatype.isUndefined || (!vardecl.datatype.isPointer && !vardecl.datatype.isStructInstance) )
|
||||
@@ -1683,7 +1685,7 @@ class PtrDereference(val identifier: IdentifierReference, val chain: List<String
|
||||
if(chain.isEmpty()) {
|
||||
return if(field==null) {
|
||||
require(vardecl.datatype.sub!=null) { "can only dereference a pointer to a simple datatype " }
|
||||
InferredTypes.knownFor(vardecl.datatype.sub!!)
|
||||
InferredTypes.knownFor(vardecl.datatype.dereference())
|
||||
} else {
|
||||
// lookup struct field type
|
||||
val struct = vardecl.datatype.subType as StructDecl
|
||||
@@ -1691,7 +1693,7 @@ class PtrDereference(val identifier: IdentifierReference, val chain: List<String
|
||||
if (fieldDt == null)
|
||||
InferredTypes.unknown()
|
||||
else
|
||||
InferredTypes.knownFor(fieldDt)
|
||||
InferredTypes.knownFor(fieldDt.dereference())
|
||||
}
|
||||
} else {
|
||||
// lookup type of field at the end of a dereference chain
|
||||
@@ -1705,13 +1707,13 @@ class PtrDereference(val identifier: IdentifierReference, val chain: List<String
|
||||
struct = fieldDt.subType as StructDecl
|
||||
}
|
||||
if(field==null) {
|
||||
return InferredTypes.knownFor(DataType.pointer(struct))
|
||||
return InferredTypes.knownFor(DataType.structInstance(struct))
|
||||
}
|
||||
val fieldDt = struct.getFieldType(field)
|
||||
return if(fieldDt==null)
|
||||
InferredTypes.unknown()
|
||||
else
|
||||
InferredTypes.knownFor(fieldDt)
|
||||
InferredTypes.knownFor(fieldDt.dereference())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,9 @@ STRUCTS and TYPED POINTERS
|
||||
- DONE: fix _msb/_lsb storage of the split-words pointer-arrays
|
||||
- DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants.
|
||||
- DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator.
|
||||
- fix ptr indexed problems (see todo.p8)
|
||||
- fix ptr problems in re.p8
|
||||
- Can we now get rid of PtPointerIndexedDeref ? Both for expression (value) as assigntarget? All code for translate(idxderef: PtPointerIndexedDeref) in ExpressionGen?
|
||||
- why does PtrDereference have both identifier and chain property? what goes where? is the distinction needed?
|
||||
- add unit tests for all changes (pointers and structs)
|
||||
- 6502 codegen: remove checks in checkForPointerTypesOn6502()
|
||||
- 6502 codegen should warn about writing to initialized struct instances when using romable code, like with arrays "can only be used as read-only in ROMable code"
|
||||
|
||||
@@ -5,7 +5,7 @@ main {
|
||||
}
|
||||
sub start() {
|
||||
^^List l1 = List()
|
||||
cx16.r1 = l1.s^^ ; TODO fix "undefined symbol" error (and fix the unit test too)
|
||||
cx16.r1 = l1.s^^
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@ class PtPointerDeref(type: DataType, val chain: List<String>, val field: String?
|
||||
get() = children.single() as PtExpression
|
||||
|
||||
init {
|
||||
require(!type.isUndefined)
|
||||
require(!type.isUndefined && !type.isPointer) { "no support for pointer to pointer" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user