Rendering
*********

Every node whose bytecode includes a HALT statement MUST define a rendering template.

Templates may be either static or dynamic.

Dynamic templates
=================

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.

Examples
--------

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.

Rendering pipeline
==================

The pipeline starts with the loading of the template corresponding to the current execution node.

From there, three branches are possible:

 1. No sink has been defined.

 2. One of the encountered MAP symbols resolves to a sink.

 3. 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.

No sink
-------

 1. Expand all placeholders in the template.

 2. Expand all menu items

MAP sink
--------

 1. Expand all non-sink placeholders in the template.

 2. Expand all menu items.

 3. Group sink items up to the remaining output size.

 4. If any item alone exceeds the remaining output size, fail and terminate execution.

 5. If any item together with the lateral navigation menu items exceed the remaining output size, fail and terminate execution.

 6. Check the page navigation index (see Lateral navigation).

 7. Replace sink symbol result with group item corresponding to navigation index.

 8. Expand all sink placeholders in the template.

 9. Expand all menu items (including lateral navigation).

Menu sink
---------

 1. Remove all menu items (any following menu expansion will only contain lateral navigation items, when and if they apply).

 2. Copy menu items to sink placeholder.

 3. Continue from MAP sink.

Multiple-page rendering
=======================

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.

Missing navigation
------------------

If no lateral navigation has been activated, any sinks will still be processed.

The sink placeholder will then be replaced with the first item in the group.

Multi-page example
------------------

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}}

Data accounting
...............

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

Rendering logic
...............

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