Rows: Arrays, Slicing & FLEX

The mode of a is REF [] INT; the mode of primes is [] INT.

29.1 Declaring rows

The mode of a is REF [] INT; the mode of primes is [] INT. Bounds are part of the *value*, not the mode — so procedures accept rows of any size.

[1:10] INT a;                 # variable row, bounds 1..10 #
[10] INT b;                   # lower bound defaults to 1 #
[0:n - 1] REAL v;             # bounds computed at run time #
[1:3, 1:3] REAL m;            # two-dimensional #
[] INT primes = (2, 3, 5, 7); # constant row from a row display #
[,] INT grid = ((1, 2, 3), (4, 5, 6));

29.2 Bounds and indexing

Subscripts are checked at run time; a68g reports out-of-bounds accesses with the source line.

BEGIN
   [] INT p = (2, 3, 5, 7, 11, 13);
   print((LWB p, UPB p, newline));               # 1 6 #
   [,] INT g = ((1, 2, 3), (4, 5, 6));
   print((1 UPB g, 2 UPB g, newline));           # 2 rows, 3 columns #
   print((g[2, 3], newline));                    # 6 #
   INT s := 0;
   FOR i FROM LWB p TO UPB p DO s +:= p[i] OD;
   print(("sum = ", whole(s, 0), newline))
END

29.3 Slicing and trimming

@ may also be written AT.

BEGIN
   [1:8] INT a := (10, 20, 30, 40, 50, 60, 70, 80);
   print((a[3:5], newline));          # 30 40 50 #
   a[3:5] := (0, 0, 0);               # slices of variables are assignable #
   print((a, newline));
   [] INT tail = a[5:];               # from 5 to the upper bound #
   [] INT shifted = a[2:4 @ 0];       # revise lower bound: indices 0..2 #
   print((LWB shifted, UPB shifted, newline));

   [1:3, 1:3] INT m := ((1, 2, 3), (4, 5, 6), (7, 8, 9));
   print((m[2, ], newline));          # row 2: 4 5 6 #
   print((m[, 3], newline));          # column 3: 3 6 9 #
   print((m[1:2, 2:3], newline))      # sub-matrix #
END

29.4 Rows as parameters and results

Calls: sum(iota(100)), fill(a, 0), fill(a[1:4], 9) (a slice is a REF [] INT too).

PROC sum = ([] INT a) INT:
BEGIN
   INT s := 0;
   FOR i FROM LWB a TO UPB a DO s +:= a[i] OD;
   s
END;

PROC fill = (REF [] INT a, INT v) VOID:
   FOR i FROM LWB a TO UPB a DO a[i] := v OD;

PROC iota = (INT n) [] INT:
BEGIN
   [1:n] INT r;
   FOR i TO n DO r[i] := i OD;
   r                       # the row VALUE is returned (copied out) #
END;

29.5 FLEX rows

Ordinary row variables have fixed bounds once generated. FLEX rows may change bounds on assignment:

STRING is FLEX [1:0] CHAR, which is why s := "longer text" works for any length.

BEGIN
   FLEX [1:0] INT list;                 # initially empty #
   list := (1, 2, 3);                   # now 1..3 #
   print((UPB list, newline));
   [UPB list + 1] INT bigger;           # grow by one: build a new row ... #
   bigger[1:UPB list] := list;
   bigger[UPB bigger] := 4;
   list := bigger;                      # ... and assign it #
   print((list, newline))
END

29.6 Rows of rows and rows of structures

Selecting a field from a row of structures yields a row of fields (see §30.2).

[] [] INT ragged = ((1, 2), (3, 4, 5), 6);   # 6 is rowed to a 1-element row #
print((UPB ragged[2], newline));              # 3 #