Arrays
Arrays in Pollen can be declared with elements of primitive type, class type, and function reference type.
Creation and Initialization
Arrays of Primitive Type
Here are several arrays of primitive type, showing explicit as well as default initialization.
uint8 arr1[3] // array of 3 uint8, by default each element initialized to 0.
uint8 arr2[3] = {7} // array of 3 uint8, each element initialized to 7.
The above arrays are target arrays. They will be initialized at load time. They must be initialized to constants, not variable values or function returns.
A host array as the attribute host
. Here is a host array. It will be initialized during the host phase:
host uint8[3] arr3 = {5,5,7} // host array of 3 uint8, initialized to 5,5,7.
Host arrays have the ability to be initialized to host variable values or host functions.
host uint8[3] arr4 = { myHostVar, hostFcnInit(), hostFcnInit() } // host array init to host values
For all arrays the type of the array is on the left and is followed by the array name. The specification of the size can follow either the type or the name.
Arrays of Class Type
host Led ledArr[2] = { new Led(7) }
This is a host array of two Leds. The new Led()
call will invoke the host constructor so the array is allocated and initialized to two Led elements statically. Target arrays are supported; they differ by the abscence of the host
attribute.
Led leds[3] = { null } // initialized to 3 nulls
This target array is allocated and initialized to three null elements at load time. Constructors cannot be called in target array initialization.
Arrays of Function References
Arrays can have an element type which is a function reference. The element type can be a module function reference.
Mod.on(uint8) onf // A function reference to Mod.on()
host Mod.on on_functions[3] = { onf } // Array of references to Mod.on()
The element type can also be a protocol function reference. This is useful
in supporting generic code as the protocol function can be implemented by
multiple functions with the same signature. Iterating over the array provides a
generic way of calling these multiple functions. OnP
is a protocol which
contains the function declaration on(uint8)
.
OnP.on on_functions[3] = { onf1, onf2, onf3 }
The function references in the initializer has been initialized to functions in modules which
implement OnP
.
An example of generic code using arrays of function references is here. More information on function references is here.
Arrays Without Dimension and the Pegging Operator
Arrays can be declared with no dimension at all. That is, there is no dimension
and also no initializer. Such arrays are not allocated
as arrays. Instead they are pegged (using the pegging operator @=
) to other arrays at runtime.
Only arrays declared without dimension can be pegged. A pegged array overlays in memory
the array to which it was pegged.
byte arrNoDim[] // no initializer!
Here is an array of characters:
byte arrStr[] = { 'h', 'e', 'l', 'l', 'o' , ' ', 'm', 'a', 'r', 'y'}
The first array can be pegged to the second array and then accessed through it:
arrNoDim @= arrStr // array pegging
string str = arrNoDim[6]
print str // prints 'mary'
A uint32
array can be pegged to a uint8
(or bool
, int16
, etc.) array and vice versa. This is useful for
flexible memory access and it can also be used to obtain some of the functionality of a type cast as shown below.
uint8 _src_u8[4] = {0,1,2,3}
uint32 arr_u32[]
bool arr_b[]
arr_u32 @= _src_u8 // access the source as an unsigned 32 bit
arr_b @= _src_u8 // access the source as a boolean
An array without dimension can also be pegged to a class reference, allowing access to the object as if it were overlaid by an array.
Arrays with Host Dimension
Arrays can have dimensions specified by a host variable, as below:
host uint8 numLeds = 1 // a host array dimension variable
Led leds[numLeds] = {null}
The value of variable numLeds
is computed during the host phase. Thus its value at load time will be known. This
supports static allocation and initialization for arrays of computed size. Such
an array can adjust to changing requirements without changing source code. Also
static allocation avoids all the problems associated with dynamic memory
management.
More information on host array initialization is here.
Accessing and Modifying an Array
Array access uses the []
operator.
myVar = myArray[idx] // idx can be any unary expression
Assigning an array element is an ordinary assignment with the array element expression on the right hand side.
myArray[idx] = newValue
The type of the array element must be compatible with the type of the expression on the other side of the assignment operator.
Iterating Over an Array
The for
and while
statements can be used to iterate over an array. strlen()
, the function shown below, can be found in the pollen.text
package in the bundle pollen.core
.
public uint16 strlen(string s) {
byte b [] @= s
uint16 i = 0
while (b[i] != '\0') { // look for the string terminator character
i++
}
return i
}
In the example below, numLeds
is a host variable computed at host time. Its value will default to 1
if no host initialization assignment occurs.
host uint8 numLeds = 1 // a host array dimension variable
Led leds[numLeds] = {null}
for (uint8 i = 0; i < numLeds; i++) {
// process leds element
}