diff --git a/codeCore/src/prog8/code/core/Enumerations.kt b/codeCore/src/prog8/code/core/Enumerations.kt index 3623fbc8e..da118438c 100644 --- a/codeCore/src/prog8/code/core/Enumerations.kt +++ b/codeCore/src/prog8/code/core/Enumerations.kt @@ -57,7 +57,7 @@ val BaseDataType.isArray get() = this == BaseDataType.ARRAY || this == BaseDataT val BaseDataType.isPointer get() = this == BaseDataType.POINTER val BaseDataType.isStructInstance get() = this == BaseDataType.STRUCT_INSTANCE val BaseDataType.isPointerArray get() = this == BaseDataType.ARRAY_POINTER -val BaseDataType.isSplitWordArray get() = this == BaseDataType.ARRAY_SPLITW +val BaseDataType.isSplitWordArray get() = this == BaseDataType.ARRAY_SPLITW || this == BaseDataType.ARRAY_POINTER // pointer arrays are also always stored as split uwords val BaseDataType.isIterable get() = this in arrayOf(BaseDataType.STR, BaseDataType.ARRAY, BaseDataType.ARRAY_SPLITW, BaseDataType.ARRAY_POINTER) val BaseDataType.isPassByRef get() = this.isIterable && !this.isPointer val BaseDataType.isPassByValue get() = !this.isIterable || this.isPointer diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 3d74e39a1..9d3721e69 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -81,15 +81,29 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, changeSplit = SplitWish.NOSPLIT } else { - changeDataType = if(decl.datatype.isSplitWordArray) null else DataType.arrayFor(decl.datatype.elementType().base) + changeDataType = if(decl.datatype.isSplitWordArray) null else { + val eltDt = decl.datatype.elementType() + if(eltDt.isPointer) + DataType.arrayOfPointersTo(eltDt.base, eltDt.subType) + else + DataType.arrayFor(eltDt.base) + } changeSplit = SplitWish.SPLIT } } SplitWish.SPLIT -> { - changeDataType = if(decl.datatype.isSplitWordArray) null else DataType.arrayFor(decl.datatype.elementType().base) + changeDataType = if(decl.datatype.isSplitWordArray) null else { + val eltDt = decl.datatype.elementType() + if(eltDt.isPointer) + DataType.arrayOfPointersTo(eltDt.base, eltDt.subType) + else + DataType.arrayFor(eltDt.base) + } } SplitWish.NOSPLIT -> { - changeDataType = if(decl.datatype.isSplitWordArray) DataType.arrayFor(decl.datatype.elementType().base, false) else null + changeDataType = if(decl.datatype.isSplitWordArray && !decl.datatype.elementType().isPointer) + DataType.arrayFor(decl.datatype.elementType().base, false) + else null } } if(changeDataType!=null) { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 0cf3135e6..b61294c17 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -49,7 +49,7 @@ STRUCTS and TYPED POINTERS - DONE: STR should be asssignment compatible with UBYTE^^ but local scoped STR should still be accessed directly using LDA str,Y instead of through the pointer, like arrays. - DONE: replace ^^str by ^^ubyte - DONE: allow return ubyte/uword when pointer type is expected as return value type -- fix actual _msb/_lsb storage of the split-words pointer-arrays +- DONE: fix _msb/_lsb storage of the split-words pointer-arrays - make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator. + unit test. Needs fixes in 6502 codegen too though... (also recheck passing STR and ARRAY types to subroutines) - fixing the pointer dereferencing issues (cursed hybrid beween IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator" - (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer. (type checking now fails on stuff like func().field and func().next.field) diff --git a/examples/test.p8 b/examples/test.p8 index d2ae8674c..4c47d248d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -17,6 +17,12 @@ main { info(n1) word[] @nosplit values = [111,222,-999,-888] + ^^word[10] @shared wordpointers + + wordpointers[0] = 1000 + wordpointers[1] = 2000 + wordpointers[2] = 3000 + wordpointers[3] = 4000 ^^byte @shared bptr ^^ubyte @shared ubptr