The [] operator can be used to extract slices or atomic elements from strings or lists. It supports two forms:
BracketExpression ::=
Expression "[" Expression "]" |
Expression "[" Expression ".." Expression "]" |
Expression "[".." Expression "]" |
Expression "[" Expression ".." "]"
The first extracts a single element from a list (or extracts a one character slice in case of a string); while the second extracts a slice based on start and end indexes.
Lists and strings are indexed starting at 1. For instance, we have:
a := 'Hello world'; ASSERT a[1] = 'H'; ASSERT a[1..5] = 'Hello'; ASSERT a[7..11] = 'world';
Indexes must be valid. For instance,
a := 'Hello world'; ASSERT a[7..9999] = 'world';
will abort the script execution.
There is a difference between lists and strings when using the [] operator. When using a list, the first form with a single index will yield an element, while the second form will yield a list.
More specifically, we have:
a := {10, 20, 10, 30, 40, 7, "Hello", FALSE};
ASSERT a[7] = "Hello";
ASSERT NOT SYS.IsList(a[2]);
ASSERT SYS.IsList({a[2]});
ASSERT SYS.IsList(a[2..4]);
while this distinction disappears when dealing with character string. Extracting a slice from a string will always return a string, no matter which of the two forms of slicing is being used.
When the upper limit of the slice is not specified, as in:
a := "Hello"; b := a[1..];
the slice extraction must happen until the end of the string (or list).
Hence, a[b..] is always equivalent to a[b..#a].
Similarly, for the sake of symmetry,
a[..b] is always equivalent to a[1..b], whether one is
dealing with lists or with strings.