Every node whose bytecode includes a HALT
statement MUST define a rendering template.
Templates may be either static or dynamic.
Using placeholders, the content behind MAP
calls in the current executing node may be embedded in the template.
Placeholders have the following format:
{{.symbol}}
where symbol
is the corresponding argument to MAP
.
Note that MAP
can only be called on symbols who have a corresponding LOAD
on the same level or futher up the stack.
Consider the following instruction sequence:
LOAD foo 32 MAP foo HALT
If the template contains the placeholder foo
, the contents of that placeholder will be replaced by the cached result of the LOAD foo
external symbol.
However:
LOAD foo 32 HALT
This will not work for the same template, because the foo
symbol has not been exposed with a MAP
call.
LOAD foo 32 MOVE bar # (bar bytecode follows) MAP foo HALT
If the template for the node bar
contains the placeholder foo
, the contents of that placeholder will be replaced by the cached result of the LOAD foo
external symbol.
This works because the MAP
is encountered further down the node execution stack than where the LOAD
was encountered.
However:
LOAD foo 32 MOVE bar # (bar bytecode follows) MAP foo MOVE baz # (baz bytecode follows) HALT
Here, if the template for baz
contains the placeholder foo
, the execution will fail because the MAP
in bar
was invalidated by the MOVE
to baz
.
The pipeline starts with the loading of the template corresponding to the current execution node.
From there, three branches are possible:
MAP
symbols resolves to a sink.
MSINK
has been encountered.
If the resulting output from any of these branches is larger than the output size, failure ensues and execution is terminated.
As indicated above, multiple-page rendering is activated when a MAP
is issued to a symbol that is loaded with 0
size. (LOAD <symbol> 0
).
The result is split into rows using newline (0x0a
) as separator.
Consider the following instruction sequence:
LOAD foo 8 LOAD bar 16 LOAD baz 0 MAP foo MAP bar MAP baz MOUT to_foo 0 MOUT to_bar 1 MNEXT to_next 11 MPREV to_prev 22 HALT INCMP foo 0 INCMP bar 1 INCMP > 11 INCMP < 22
... and the following template (14 bytes, without the placeholders, including line break):
This is {{.foo}} and {{.bar}} {{.baz}}
Then consider that the symbols resolve as follows:
symbol | returned value | rendered value | bytes |
---|---|---|---|
foo | foobar | foobar | 6 |
bar | barbarbar | barbarbar | 9 |
baz | FOO 42 BAR 13 BAZ 666 XYZZY 1984 INKY 1 PINKY 22 BLINKY 333 CLYDE 4444 | (deferred) | (71) |
to_foo | go to foo | 0:go to foo | 11 |
to_bar | visit the bar | 1:visit the bar | 15 |
to_next | next page | 11:next page | 12 |
to_prev | go back | 22:go back | 10 |
Given an output size limit of 94, static part of the template (14 bytes). this results in the following render possibilities for the sink content:
navigation case | bytes left for sink |
---|---|
no navigation | 39 |
next | 27 |
previous | 29 |
next + previous | 17 |
The total sink byte count is 72, whereas the maximum available sink capacity is 39. At least one extra page is needed.
The first page (with next
) has 27 bytes available, which covers the 3 first sink items (22 bytes, include line break). This results in the following output:
This is foobar and barbarbar FOO 42 BAR 13 BAZ 666 0:go to foo 1:visit the bar 11:next page
Any page that is not first page has maximum 29 bytes available. There are 49 bytes left to render from the sink. This means that more pages are needed, and therefore both next
and previous
are needed, leaving a capacity of 17 bytes. This is only sufficient for the next item (11 bytes, with line break), resulting in the following output:
This is foobar and barbarbar XYZZY 1984 0:go to foo 1:visit the bar 11:next page 22:go back
For the next page we again compare with the maximum of 29 bytes. There are 38 bytes left to render. Another intermediate page is required, with the two next entries (16 bytes) fitting inside the capacity (17 bytes). The page then looks like this:
This is foobar and barbarbar INKY 1 PINKY 22 0:go to foo 1:visit the bar 11:next page 22:go back
Lastly, with 22 bytes left to go, we can render within the maximum available space of 29 bytes (only using previous
). Thus:
This is foobar and barbarbar BLINKY 333 CLYDE 4444 0:go to foo 1:visit the bar 22:go back