mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 05:02:58 +00:00
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:
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in new issue
Block a user