fix pointer array initialization

This commit is contained in:
Irmen de Jong
2025-07-06 19:42:54 +02:00
parent 2a4a3b786e
commit 8ede098154
6 changed files with 102 additions and 20 deletions
+10 -10
View File
@@ -351,22 +351,22 @@ class DataType private constructor(val base: BaseDataType, val sub: BaseDataType
val isPointer = base.isPointer
val isStructInstance = base.isStructInstance
val isPointerArray = base.isPointerArray
val isBoolArray = base.isArray && sub == BaseDataType.BOOL
val isByteArray = base.isArray && (sub == BaseDataType.UBYTE || sub == BaseDataType.BYTE)
val isUnsignedByteArray = base.isArray && sub == BaseDataType.UBYTE
val isSignedByteArray = base.isArray && sub == BaseDataType.BYTE
val isWordArray = base.isArray && (sub == BaseDataType.UWORD || sub == BaseDataType.WORD)
val isUnsignedWordArray = base.isArray && sub == BaseDataType.UWORD
val isSignedWordArray = base.isArray && sub == BaseDataType.WORD
val isFloatArray = base.isArray && sub == BaseDataType.FLOAT
val isBoolArray = base.isArray && !base.isPointerArray && sub == BaseDataType.BOOL
val isByteArray = base.isArray && !base.isPointerArray && (sub == BaseDataType.UBYTE || sub == BaseDataType.BYTE)
val isUnsignedByteArray = base.isArray && !base.isPointerArray && sub == BaseDataType.UBYTE
val isSignedByteArray = base.isArray && !base.isPointerArray && sub == BaseDataType.BYTE
val isWordArray = base.isArray && !base.isPointerArray && (sub == BaseDataType.UWORD || sub == BaseDataType.WORD)
val isUnsignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.UWORD
val isSignedWordArray = base.isArray && !base.isPointerArray && sub == BaseDataType.WORD
val isFloatArray = base.isArray && !base.isPointerArray && sub == BaseDataType.FLOAT
val isString = base == BaseDataType.STR
val isBool = base == BaseDataType.BOOL
val isFloat = base == BaseDataType.FLOAT
val isLong = base == BaseDataType.LONG
val isStringly = base == BaseDataType.STR || base == BaseDataType.UWORD || (base == BaseDataType.ARRAY && (sub == BaseDataType.UBYTE || sub == BaseDataType.BYTE))
val isSplitWordArray = base.isSplitWordArray
val isSplitUnsignedWordArray = base.isSplitWordArray && sub == BaseDataType.UWORD
val isSplitSignedWordArray = base.isSplitWordArray && sub == BaseDataType.WORD
val isSplitUnsignedWordArray = base.isSplitWordArray && !base.isPointerArray && sub == BaseDataType.UWORD
val isSplitSignedWordArray = base.isSplitWordArray && !base.isPointerArray && sub == BaseDataType.WORD
val isIterable = base.isIterable
val isPassByRef = base.isPassByRef
val isPassByValue = base.isPassByValue
@@ -30,7 +30,8 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
when(decl.type) {
VarDeclType.VAR -> {
if(decl.isArray) {
if(decl.datatype.isSplitWordArray)
// using a array of words as initializer to a pointer array is fine
if (!valueDt.isSplitWordArray || !decl.datatype.isPointerArray)
errors.err("value has incompatible type ($valueType) for the variable (${decl.datatype})", decl.value!!.position)
} else if(!decl.datatype.isString) {
if (valueDt.largerSizeThan(decl.datatype)) {
+30
View File
@@ -1290,4 +1290,34 @@ main {
(st[4] as FunctionCallStatement).args.single() shouldBe instanceOf<AddressOf>()
(st[5] as FunctionCallStatement).args.single() shouldBe instanceOf<AddressOf>()
}
test("initializing arrays of pointers") {
val src="""
%option enable_floats
main {
sub start() {
^^ubyte[4] array1 = [1000, 1100, 1200, 1300]
^^byte[4] array2 = [1000, 1100, 1200, 1300]
^^bool[4] array3 = [1000, 1100, 1200, 1300]
^^word[4] array4 = [1000, 1100, 1200, 1300]
^^uword[4] array5 = [1000, 1100, 1200, 1300]
^^float[4] array6 = [1000, 1100, 1200, 1300]
^^long[4] array7 = [1000, 1100, 1200, 1300]
^^str[4] array8 = [1000, 1100, 1200, 1300]
cx16.r0 = array1[2]
cx16.r1 = array2[2]
cx16.r2 = array3[2]
cx16.r3 = array4[2]
cx16.r4 = array5[2]
cx16.r5 = array6[2]
cx16.r6 = array7[2]
cx16.r7 = array8[2]
}
}"""
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
}
})
+28 -2
View File
@@ -8,13 +8,39 @@ Structs and Pointers
Legacy untyped pointers (uword)
-------------------------------
Work in progress.
Prior to version 12 of the language, the only pointer type available was a plain ``uword`` value (the memory address)
which could be used as a pointer to an ``ubyte`` (the byte value at that memory address).
Array indexing on an ``uword`` simply means to point to the ``ubyte`` at the location of the address + index value.
When the address of a value (explicitly) or a value of a reference type (string, array) was passed as an argument to a subroutine call,
it became one of these plain ``uword`` 'pointers'. The subroutine receiving it always had to interpret the 'pointer'
explicitly for what it actually pointed to, if that wasn't a simple byte.
Some implicit conversions were allowed too (such as putting ``str`` as the type of a subroutine parameter,
which would be changed to ``uword`` by the compiler).
*For backward compatibility reasons, this untyped ``uword`` pointer still exists in the language.*
Since version 12 there now are *typed pointers* that better express the intent and tell the compiler how to use the pointer,
these are explained below.
Typed pointer to simple datatype
--------------------------------
Work in progress.
The syntax for declaring typed pointers is as follows:
``^^type``: pointer to that type
You can declare a pointer to any numeric datatype (bytes, words, longs, floats), booleans,
and also strings. (the latter, ``^^str`` - a pointer to a string - is equivalient to ``^^ubyte`` though because a string is just an array of ubytes.)
``^^float fptr`` declares fptr as a pointer to a float value.
Finally, the type can be a struct type, which then declares a pointer to that struct type. This is explained in the next section.
``^^type[size]``: array with size size containing pointers to type.
So ``^^word[100] values`` declares values to be an array of 100 pointers to words.
Note that an array of pointers (regardless of the type they point to) is always a @split word array by default.
It is not possible to define "pointers to arrays"; ``^^(type[])`` is invalid syntax.
Structs
+31 -6
View File
@@ -1,13 +1,38 @@
%option enable_floats
main {
sub start() {
struct Node {
^^uword s
}
^^ubyte[4] array1 = [1000, 1100, 1200, 1300]
^^byte[4] array2 = [1000, 1100, 1200, 1300]
^^bool[4] array3 = [1000, 1100, 1200, 1300]
^^word[4] array4 = [1000, 1100, 1200, 1300]
^^uword[4] array5 = [1000, 1100, 1200, 1300]
^^float[4] array6 = [1000, 1100, 1200, 1300]
^^long[4] array7 = [1000, 1100, 1200, 1300]
^^str[4] array8 = [1000, 1100, 1200, 1300]
^^Node l1
cx16.r0 = array1[2]
cx16.r1 = array2[2]
cx16.r2 = array3[2]
cx16.r3 = array4[2]
cx16.r4 = array5[2]
cx16.r5 = array6[2]
cx16.r6 = array7[2]
cx16.r7 = array8[2]
l1.s[0] = 4242
l1^^.s[0] = 4242 ; TODO fix parse error
; txt.print_uw(array[1])
; txt.print_uw(array[2])
; txt.print_uw(array[3])
; txt.print_uw(array[4])
; txt.print_uw(array[5])
; txt.print_uw(array[6])
; txt.print_uw(array[7])
;
; func(farray)
}
; sub func(^^float zzz) {
; cx16.r0++
; }
}
+1 -1
View File
@@ -13,7 +13,7 @@
</options>
<keywords keywords="&amp;;&amp;&lt;;&amp;&gt;;-&gt;;@;^^;alias;and;as;asmsub;break;clobbers;continue;do;downto;else;extsub;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;on;or;repeat;return;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%align;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%jmptable;%launcher;%memtop;%option;%output;%zeropage;%zpallowed;%zpreserved;@align64;@alignpage;@alignword;@bank;@dirty;@nosplit;@nozp;@requirezp;@shared;@split;@zp;atascii:;c64os:;cp437:;default:;iso16:;iso5:;iso:;kata:;petscii:;sc:" />
<keywords3 keywords="^^bool;^^byte;^^float;^^str;^^ubyte;^^uword;^^word;bool;byte;const;float;long;str;struct;ubyte;uword;void;word" />
<keywords3 keywords="^^bool;^^byte;^^float;^^long;^^str;^^ubyte;^^uword;^^word;bool;byte;const;float;long;str;struct;ubyte;uword;void;word" />
<keywords4 keywords="abs;bmx;call;callfar;callfar2;cbm;clamp;cmp;conv;cx16;defer;diskio;divmod;floats;len;lsb;lsw;math;max;memory;min;mkword;msb;msw;peek;peekf;peekw;poke;pokef;pokew;psg;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt;strings;sys;txt;verafx" />
</highlighting>
<extensionMap>