Array Child Helpers

Stmt :=

| 'expand' GiglArrayOption Identifier_t GiglIndexSpecList_c 'with' GiglArrayFillExpr ';'

| 'expandzero' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'destroy' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'alloc' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'dealloc' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'fill' GiglArrayOption Identifier_t GiglIndexSpecList 'with' GiglArrayFillExpr ';'

| 'fillzero' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'release' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'refill' GiglArrayOption Identifier_t GiglIndexSpecList 'with' GiglArrayFillExpr ';'

| 'releasezero' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'refillzero' GiglArrayOption Identifier_t GiglIndexSpecList ';'

| 'iterate' GiglArrayOption 'over' Identifier_t GiglIndexSpecList Stmt

GiglIndexSpecList :=

| <empty>

| GiglIndexSpecList GiglIndexSpec

GiglIndexSpec :=

| '[' GiglIndexRangeList ']'

| '[' Identifier_t ':' GiglIndexRangeList ']'

| '[' ',,' ']'

| '[' Identifier_t ':' ',,' ']'

| '[' ']'

| '[' Identifier_t ':' ']'

GiglIndexRangeList :=

| GiglIndexRange

| GiglIndexRangeList ',' GiglIndexRange

GiglIndexRange :=

| AssignExpr

| AssignExpr ',,' AssignExpr

| AssignExpr ',,'

| ',,' AssignExpr

GiglArrayOption :=

| <empty>

| '<' 'downfrom' '>'

| '<' 'upto' '>'

| '<' 'only' '>'

| '<' 'all' '>'

GiglArrayFillExpr := AssignExpr

These are sets of productions from the nonterminal Stmt in C, which is used to match statements. These productions are for statements that manipulates on a rule child that has array type (called array helper statements). The array could be one-dimensional or multi-demensional. They could work on non-array rule child, which would be effectively the same as zero-dimensional array, but this is not recommended. There are 12 different keywords that can lead such a statement, and there semantics are discussed below (note that the exact effect may depend on the GiglIndexSpecList and the GiglArrayOption parts).

'expand' leads a statement that allocates the array space and fills each entry with the specified expression.

'expandzero' leads a statement that allocates the array space and fills each entry with zero (equivalent to 'expand' statement with the expression be integer literal zero).

'destroy' leads a statement that deallocates the array space and also calls delete on each array entry before that (assuming the array entries are pointers to some valid memory).

'allocate' leads a statement that allocates the array space (but does not fill in the entries).

'dealloc' leads a statement that deallocates the array space (but does not call delete on each array entry).

'fill' leads a statement that fills each entry with the specified expression (it assumes the array space is already allocated and does not do the allocation).

'fillzero' leads a statement that fills each entry with zero (equivalent to 'fill' statement with the expression be integer literal zero).

'release' leads a statement that calls delete on each array entry (but does not deallocate the array space).

'refill' leads a statement that first calls delete on each array entry then fill it with the specified expression.

'releasezero' leads a statement that first calls delete on each array entry then fill it with zero (equivalent to 'refill' statement with the expression be integer literal zero), an alias of 'refillzero'.

'refillzero' leads a statement that first calls delete on each array entry then fill it with with zero (equivalent to 'refill' statement with the expression be integer literal zero), an alias of 'releasezero'.

'iterate' leads a statement that executes the specified statement for each array entry.

The part that are allocated or the entries that are filled/iterated through is encoded in the GiglIndexSpecList (index specification) part. It could be empty, then it refers to the top level of array and with default option it allocates the whole array space and/or fills/iterates through all entries. It can contains an index, a list of index (separated by ','s), or a range of index (indicated with ',,'s) for each dimension up to a certain level and with default option it allocates at and below those level in the sub-arrays specified by those index/indices/ranges and fill in all the entries at the bottom of them. For example, if an array type rule child is "int* a[5][2]", then "expand a[1,,3] with new int(1);" allocates a[1], a[2], a[3] (while assuming the top-level a is already allocated) and fill in a[1][0], a[1][1], a[2][0], a[2][1], a[3][0], a[3][1] with pointers to a new allocated memory spaces containing integer 1, with default options. In addition the index specification can contain named index which may be used in the expression to fill or statement to execute when iterating. Modifying the above example, "expand a[i : 1,,3] with new int(i);" do the same allocation, but fill in a[1][0] and a[1][1] with pointers to integer 1, a[2][0] and a[2][1] with pointers to integer 2, and a[2][0] and a[2][1] with pointers to integer 3. For more discussions and examples, please refer to here.

The exact semantics of the index specification may also depend on the GiglArrayOption (array statement option) part. There are four disjoint options from which one of which is applied, which is shown as follows (if the option part is empty, it by default takes the 'downfrom' option, which is the most common usage).

'downfrom' means allocation/deallocation applies to spaces starting from the lowest level in the index specification and goes to the bottom level, and fill/release/iterate applies to entries at the bottom level.

'upto' means allocation/deallocation applies to spaces upto the lowest level in the index specification, and fill/release/iterate applies to that lowest level in the index specification (which may not be bottom level array entries).

'all' means allocation/deallocation applies to all dimension levels, and fill/release/iterate applies to entries at the bottom level.

'only' means allocation/deallocation applies to spaces only at the lowest level in the index specification, and fill/release/iterate applies to that same level (which may not be bottom level array entries).

The GiglArrayFillExpr part is for specifying the expression to be filled in some of the array helper statements. the implementation of it shares most of the features with the implementation of the lambda configuration feature, which is also discussed in here. A simple example is that a random number generator call may fill in different entries with different numbers.

  • Identifier_t is a terminal in C that matches any valid identifier, which is the name of the array (rule child) in the productions from Stmt, and the name of the index variable in the productions from GiglIndexSpec.

    • AssignExpr is a nonterminal in C to match an expression with precedence equal or higher than assignments (almost every expression, excluding those constructed by comma operators).

PrimaryExpr :=

| '<' TypeName '>' GiglArrayInitializer


GiglArrayInitializer :=

| '{' GiglArrayInitList '}'

| '{' GiglArrayInitList ',' '}'

GiglArrayInitList :=

| GiglArrayInit

| GiglArrayInitList ',' GiglArrayInit

GiglArrayInit :=

| AssignExpr

| GiglArrayInitializer

These are productions from the nonterminal PrimaryExpr in C, which is to match expressions with the highest precedence (i.e. those without operators inside). Here, they are use for an expression that can be used to pass in to the node constructor for some array type rule child. This expression can be stored in a variable declared with the 'gigltable' specifier with the proper template (see below). Note, it does not work for assigning directly to the array child. The syntax starts with the type of the element in the array entries wrapped in '<' and '>', then followed by a part that is similar to an array initializer in C.

  • TypeName is a nonterminal in C that matches the name of a type (including modifiers like pointers). Note this is different from TypeName_t a terminal in C that only as the identifier part. Here it is used for the type of the element in the array entries.

    • AssignExpr is a nonterminal in C to match an expression with precedence equal or higher than assignments (almost every expression, excluding those constructed by comma operators).

TypeSpecifier := 'gigltable' '<' TypeName '>'

This is a bridging production from the nonterminal TypeSpecifier in C, which is to used to match keywords for types such as 'int', 'double' etc. Here, it used for declaring a variable of type that is compatible to pass in to the node constructor for some array type rule child, which could be constructed by some special syntax in GIGL (see above). This is implemented as an std::vector templated type in C++ and can be used inside the scope of the item type definition wherever a std::vector can be used (GIGL's implementation currently does not support C++ templates in general so this can be a special work-around).

  • TypeName is a nonterminal in C that matches the name of a type (including modifiers like pointers). Note this is different from TypeName_t a terminal in C that only as the identifier part. Here it is used for the type of the element in the array entries.