|
|
Repeat blocks copy a group of script lines once for each value of an integer index, so a series of similar items (a filter cascade, the passes of a multi-stage smoother, a ladder of lookback periods, a family of chart lines) can be written once instead of typed out by hand. The copying is purely textual and happens before the script is parsed, so the expanded text is exactly what you would otherwise have typed.
A block starts with a #repeat line naming the index and its values, and ends with #endrepeat. Inside the block, an index name in braces such as {k} is a marker that is replaced by the index value in each copy. For example:
Data:
out0: C
#repeat k from 1 to 4
out{k}: AEMA(out{k-1}, 2 / 15)
#endrepeat
final: Item("out{#}", ORDER)
RealTest parses this as if the script contained out1: AEMA(out0, 2 / 15), out2: AEMA(out1, 2 / 15) and so on through out4. The out0 seed item outside the block together with out{k-1} inside it is the usual way to chain stages without a special case for the first one, and Item() is the usual way to select one of the expanded items at run time when the number of stages is a Parameter (repeat up to the parameter's maximum value).
Syntax
The index values are given the same way as an optimization range in the Parameters section, but they must be integers and a range must be ascending:
|
Line
|
Description
|
|
#repeat k from 1 to 20
|
every integer from 1 to 20
|
|
#repeat k from 0 to 12 step 3
|
0, 3, 6, 9, 12
|
|
#repeat k from 5 to 80 mult 2
|
5, 10, 20, 40, 80
|
|
#repeat n 5, 8, 13, 21
|
an explicit list of values
|
|
#endrepeat
|
end of the block
|
The def and round clauses of a Parameters range are not allowed, nor are non-integer values. Both directive lines must be the first thing on their line (indentation is fine) and are removed from the expanded text.
Markers
A marker is {expr} with no spaces inside, where expr uses at least one enclosing repeat index and otherwise only integers, the operators + - * / (integer division truncates) and parentheses: {k}, {k-1}, {2*k+1}, {(k-1)*3+j}. A marker can appear anywhere in the block: in item names, formulas, Namespace names, Include paths, string literals, and comments.
Any other text in braces keeps its usual meaning, because none of it names an active index: {#6} or {%} format codes, {color: gray} attribute blocks, the {x} optimize flag, a bare {2}, and ordinary comments are all left alone. Note the flip side: a misspelled index such as out{kk-1} is treated as a comment, so the parser then sees out and reports whatever that produces. A marker that names an index but cannot be evaluated ({k/0}) is an error.
Parameter names are not allowed in a marker. The block is expanded once when the script is parsed, while a parameter takes a different value in every optimization test. Repeat up to the parameter's maximum and select at run time with Item(), as in the first example.
Nesting
Blocks can be nested. Each level needs a different index name, and since the inner #repeat line is substituted like any other line, an inner range can depend on the outer index:
Library:
#repeat k from 1 to 4
#repeat j from 1 to {k}
w{k}_{j}: {k*10+j}
#endrepeat
#endrepeat
Blocks that span sections
A block may contain section headers, so instead of putting the index in every item name you can put it in a Namespace and keep the names inside plain (restate the section header after the Namespace line):
Namespace: pass0
Data:
out: C
#repeat k from 1 to 4
Namespace: pass{k}
Data:
a: AEMA(pass{k-1}.out, 2 / 15)
b: AEMA(a, 2 / 15)
out: a + 0.5 * (a - b)
#endrepeat
Namespace: none
Data:
final: Item("pass{#}.out", ORDER)
The usual Namespace rules apply: inside a namespace only that namespace's own items are visible by bare name, so Data, Library and Parameter items defined outside it must be written inline or referred to by a dotted name such as pass2.out, and a block that sets a namespace leaves it set after #endrepeat, exactly as pasting the text would.
An Include line inside a block is repeated per iteration with its path (and any preceding Namespace line) substituted, but the included file is parsed on its own and does not see the enclosing index.
Errors and the editor
A syntax error inside a block is reported at the line of the script as written, with the failing copy of the block appended to the message, for example (#repeat k = 3). The Data window and the script copy saved with a test show the expanded item names (out1, out2, ...), which is usually what you want when checking a cascade.
The script editor colors a name containing a marker (p{k}a, out{k-1}) as the item it will become, and auto-complete offers the expanded names. A Notes line that begins with the word #repeat is treated as the directive, the same rule that applies to #ifdef.
See also Conditional Comments, Namespace and Combining Scripts.
|
|