normal error message instead of crash when typed pointer arrays are used as struct field (currently not supported by the compiler)

This commit is contained in:
Irmen de Jong committed 2026-08-24 19:21:30 +02:00
1 parent 296295011e
commit 2bbbacc46e
4 files changed
+27 -9

No files matched your search

@@ -219,6 +219,11 @@ class DataType private constructor(
fun elementToArray(splitwords: Boolean = true): DataType {
return if (base == BaseDataType.UWORD || base == BaseDataType.WORD || base == BaseDataType.STR) arrayFor(base, splitwords)
else if(base.isPointer) {
if(subType!=null) arrayOfPointersTo(subType)
else if(subTypeFromAntlr!=null) arrayOfPointersFromAntlrTo(sub, subTypeFromAntlr)
else arrayOfPointersTo(sub!!)
}
else arrayFor(base, false)
}
@@ -2331,14 +2331,21 @@ internal class AstChecker(private val program: Program,
if(uniqueFields.isEmpty())
errors.err("struct must contain at least one field", struct.position)
fun validFieldType(field: StructField): Boolean {
val dt=field.type
if(dt.isArray && dt.subType!=null) {
errors.err("arrays of typed pointers are currently not supported, use untyped pointer for now at field '${field.name}'", struct.position)
return false
}
return dt.isBasic
|| dt.base.isNumericOrBool
|| dt.isPointer
|| dt.isArray
}
struct.fields.forEach { field ->
val dt = field.type
val allowed = dt.isBasic
|| dt.base.isNumericOrBool
|| dt.isPointer
|| (dt.isArray && dt.sub!!.isNumericOrBool)
if(!allowed)
errors.err("only booleans, numeric and pointer fields allowed in a struct: '${field.name}'", struct.position)
if(!validFieldType(field))
errors.err("invalid struct field type at '${field.name}'", struct.position)
}
}
+6 -2
View File
@@ -140,8 +140,12 @@ dealing with all of them separately. You first define the struct type like so::
bool elite
}
You can use boolean fields, numeric fields (byte, word, long, float), and pointer fields (including str, which is translated into ^^ubyte).
You cannot nest struct types, but inline arrays are supported as fields. 2D arrays are not allowed as struct fields.
Allowed field datatypes: all numeric types (``byte``, ``ubyte``, ``word``, ``uword``, ``long``, ``float``),
``bool``, ``str``, typed pointers to those or to other structs, and inline 1D arrays of these element types.
Not allowed: struct instances themselves (structs cannot be nested, use a pointer to the struct instead),
arrays of typed pointers such as ``^^Enemy[4]`` (use untyped pointers instead), and 2D arrays.
The typed pointer array and 2D array restrictions are limitations of the current compiler; they may or may not be lifted in a future version.
Fields in a struct are 'packed' (meaning the values are placed back-to-back in memory), and placed in memory in order of declaration. This guarantees exact size and place of the fields.
``sizeof()`` knows how to calculate the combined size of a struct, and ``offsetof()`` can be used to get the byte offset of a given field in the struct.
The size of a struct cannot exceed 1 memory page (256 bytes).
+2
View File
@@ -9,6 +9,8 @@ Future Things and Ideas
- symboldump: some sort of javadocs generated from the p8 source files (instead of just the function signatures). Use markdown for formatting, not html.
- when implementing unsigned longs: remove the (multiple?) "TODO "hack" to allow unsigned long constants to be used as values for signed longs, without needing a cast
- struct/ptr: implement the remaining TODOs in PointerAssignmentsGen.
- struct/ptr: support arrays of typed pointers as struct fields (e.g. ``^^Enemy[4] foos``); currently rejected by AstChecker with "arrays of typed pointers are currently not supported", untyped pointers must be used instead.
- struct/ptr: support 2D arrays as struct fields; currently a parser error ("2D arrays are not allowed as struct fields"), even though 2D arrays are supported for regular variables (see variables.rst).
- struct/ptr: typed function pointers (simplified): ``&&subroutine`` returns opaque typed pointer (no ``funcptr`` keyword), assignment allowed where target type is inferred, calling via ``ptr(args)``. No explicit signature syntax. Useful mostly for 68000 targets.
- struct/ptr: really fixing the pointer dereferencing issues (cursed hybrid between IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator"
- struct/ptr: (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer as assignment target (LHS). RHS value case ``a = func().field`` / ``a = func().next.field`` now works for both VM and 6502 via generic ``peek`` desugar (``AstExpressions.kt:280``, ``CodeDesugarer.kt:654``); still fails for ``func().field = a`` / ``func().next.field = a`` which requires ``Prog8ANTLR.g4:239`` ``assign_target`` grammar change to allow ``functioncall '.' field`` chain (see ``compiler/test/TestPointers.kt`` xtest).