Index | PAL Intro | Commands | Registers | Indices | Stack | Macros | Classes | Attributes | Errors
ps_tree - Introduction to PROSE tree arrays
Pre-requisite Reading
Description
Cloning Tree Arrays
See Also
Author
Please see pal_intro(5) for a general description of PAL and tree_def(5) for a description of how to define tree arrays.
Tree arrays, as described in tree_def(5), provide a mechanism for manipulating tree structures that are identical in functionality to the nexus via paths provided in list sequences (or single argument paths), and for managing variable objects within those paths.
There are two kinds of tree array. The first is a structure whose root node is attached to an attribute value. This type of array does not share a common root with the nexus and is therefore an independent tree structure, and one that cannot be manipulated without the use of special bytecode instructions. This type of array is called imploded.
The second kind is a structure whose root node is actually not a true root node at all as it has a parent. That parent is an object in the nexus. This type of array therefore does share a common root with the nexus and elements within the array can be searched and manipulated just like any other node in the nexus. This type of array is called exploded.
In both cases the tree array is described by an object with a subclass of psTree. This object can be treated like any other variable object. Imploded tree arrays use the class psTreeImp and exploded tree arrays use psTreeExp.
Tree arrays do not have a type. They may contain many objects within them of varying types. While tree arrays are primarily designed to contain variable objects, they behave identically to other objects in the nexus and therefore may contain objects of any class.
Both imploded and exploded tree arrays have a common instruction set. The itree family of commands operate on imploded tree arrays, while the xtree family operate on exploded tree arrays. The instructions dedicated to tree arrays are summarised below:
itree/def Define a new imploded tree array object. This works similarly to var/def except that an attribute is not required (tree arrays do not have a type), nor can a value be given to the definition instruction. A set of related instructions are used to define objects with a variety of different scopes, just like their var counterparts: itree/local, itree/static and itree/global. See tree_def(5). itree/bdef Identical to itree/def except that the psTreeRoot attribute will be assigned to the tree array object when it is created, and given the value of TRUE. This changes the addressing mode so that the topmost item in the tree array must be included in paths passed to the itree/addr and itree/set instructions. There are equivalent instructions for different scopes: itree/blocal, itree/bstatic and itree/bglobal. See tree_def(5). xtree/def Identical to itree/def except for exploded tree array objects. Includes: xtree/local, xtree/static and xtree/global. xtree/bdef Identical to itree/bdef except for exploded tree array objects. Includes: xtree/blocal, xtree/bstatic and xtree/bglobal. itree/addr Returns a pointer to a node within an imploded tree array, allowing the object to be manipulated like any other object in the nexus. The node is addressed using a list sequence or single-value index. See tree_addr(5). xtree/addr Identical to itree/addr except for exploded tree array objects. itree/set Creates a variable object (as if var/def was used) in a given location within an imploded tree array. The node to create is addressed using a list sequence or single-value index. Any elements of the path that do not already exist will be created. See tree_set(5). xtree/set Identical to itree/set except for exploded tree array objects. itree/xconv Converts an exploded tree array to an imploded tree array. Nodes that were attached to the nexus and were members of the exploded tree will be detached and reattached to a new imploded tree. See tree_conv(5). xtree/iconv Converts an imploded tree array to an exploded tree array. Nodes that were part of the imploded array are reattached to the nexus and the imploded array is destroyed. See tree_conv(5). The following example creates an array called "shoot":
.setup % Set-up shoot array attr/load P10, [psString] itree/local P0, [shoot] itree/set P0, P10, @[[movie], [title]], [Skyfall] itree/set P0, P10, @[[movie], [genre]], [Action] itree/set P0, P10, @[[movie], [origin]], [British] itree/set P0, P10, @[[movie], [scene], #1, [title]], [Teaser]The itree/set command is creating each path as required as well as assigning a psString variable object each time. As the tree gets deeper it becomes impractical to continue addressing items from the top of the array. We use itree/addr to get a pointer we can use in subsequent operations:
itree/addr P1, P0, @[[movie], [scene], #1]Unlike itree/set, the itree/addr command will fail if the path does not exist, rather than creating it. Register P1 now contains a pointer to a node deeper in the tree. You would see if you ran reg/dump P1 that it would report the path as .shoot.movie.scene.1 and the root will be marked as local meaning that it is not the global root .prose. We can continue to assign values underneath this path:
attr/load P11, [psFloat], P12, [psInteger] itree/set P0, P11, @[P1, [length]], [129.4] itree/set P0, P12, @[P1, [frames]], [77640] itree/set P0, P12, @[P1, [cameras]], [4]The instructions above are equivalent to the following pseudo-code:
shoot{movie.title}="Skyfall" shoot{movie.genre}="Action" shoot{movie.origin}="British" shoot{movie.scene.1.title}="Teaser" shoot{movie.scene.1.length}=129.4 shoot{movie.scene.1.frames}=77640 shoot{movie.scene.1.cameras}=4Although youll see from a reg/dump P1 that the arrays root node is called "shoot", you never need to include this node when addressing elements with itree/addr or itree/set. This is because we used itree/local to define the array instead of itree/blocal. If we had used the itree/blocal instruction instead, the psTreeRoot attribute would have been set to TRUE on our tree array object, and thereafter we would had to have started all of our addressing with the name of the root node "shoot". Lets now explode the tree to see what the difference is:
xtree/iconv P0Register P0 will still point to the same object as before, but the object will now have the class psTreeExp instead of psTreeImp and the contents of the tree will now be attached directly underneath this object. The pointer in register P1 which we obtained earlier is still valid, so if you were to run reg/dump P0, P1 you would see that the path to the array object is .prose.code.default.main._i0#0.var.shoot, the path to the object in P1 would be .prose.code.default.main._i0#0.var.shoot.movie.scene.1 and the root will be marked as global meaning that we are now sharing a common root with the nexus.
However, nothing changes in the way that we address members of the array if we continue to use xtree/addr or xtree/set. For example:
xtree/addr P1, P0, @[P1, [cameras]] xtree/set P0, P11, @[P1, #3, [x]], [15] xtree/set P0, P11, @[P1, #3, [y]], [-12.1] xtree/set P0, P11, @[P1, #3, [z]], [0] xtree/set P0, P11, @[P1, #3, [velocity]], [-0.5]The root node "shoot" still doesnt appear in our addressing for the same reason that it didnt before, because the psTreeRoot attribute is not set to TRUE. Lets change that now and observe the change in behaviour:
attr/add P0, [psTreeRoot], #1Having made this change, the following command will fail:
xtree/addr P1, P0, @[[movie], [scene]]The xtree/addr instruction will return the error prose.error.sys.NoPathEnt because the psTreeRoot attribute is now set to TRUE so we must include the name of the root node in our addressing. The following will work:
xtree/addr P1, P0, @[[shoot], [movie], [scene]]
For a discussion of cloning tree arrays, see tree_clone(5).
pal_intro(5), pal_commands(5), pal_registers(5), tree_def(5), tree_addr(5), tree_set(5), tree_conv(5), tree_clone(5), var_def(5), ps_classes(5), ps_attributes(5),
PROSE Assembly Language at prose.sourceforge.net.
Copyright (c) 2002-2015 Mark R. Bannister <cambridge@users.sourceforge.net>.
This is free software and can be downloaded from prose.sourceforge.net; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
PAL 1.0 | ps_tree (5) | 29 April 2015 |