Navigation
**********

Nodes are navigated by name, using a navigation stack.

Every movement down adds a node to the stack, and every movement up removes one node from the stack.

Additionally, lateral movement is available, for nodes whose contents span mulitple pages.

Entry point
===========

All VM executions require an entry point.

If not explicitly set in the code, the node name root is used.

Attempting to navigate up from the entry point node will fail and terminate execution.

Lateral navigation
==================

Lateral navigation is only available for node output spanning multiple pages. See Multi-page rendering for details.

Lateral navigation will fail and terminate execution when:

  * executing a single-page node.

  * attempting next beyond the last page.

  * attempting previous on the first page.

Node names
==========

Regular node names must start with an alphabetical character. The rest of the string may contain alphanumeric characters and underscore.

Special node names
------------------

A selection of special node names are available for relative navigation. They are single-character tokens, listed below with their respective ASCII codes.

. (0x2E)
     Repeat the same node.

_ (0x5F)
     Go to the previous node in the stack.

> (0x3E)
     Go to the next page of a multi-page node. Will fail if used in a single-page context and/or resulting page index is out of bounds.

< (0x3C)
     Go to the next page of a multi-page node. Will fail if used on the first (or single) page.

^ (0x5E)
     Go to the topmost node. Will execute each intermediate node in the stack.

Builtin node names
------------------

Uncaught exceptions in the code flow that should not halt execution are routed to a builtin node named _catch.

Navigation stack
================

Consider the following navigation example, illustrating the state of the stack for each step after execution.

instruction
stack
page index
MOVE foo
foo
0
MOVE bar
foo/bar
0
MOVE baz
foo/bar/baz
0
MOVE >
foo/bar/baz
1
MOVE >
foo/bar/baz
2
MOVE <
foo/bar/baz
1
MOVE .
foo/bar/baz
1
MOVE _
foo/bar
0
MOVE baz
foo/bar/baz
0
MOVE ^
foo
0