Each mutable object can tell who is its parent.
These parent pointer are maintained automatically at a very low cost (single move instruction).
They simplify handling of document data models and allow integrity checks if needed.
class Node {
tag = "";
children = Array(Node);
setTag(v String) this { tag := v }
add(c Node) this { ... }
parent() Node { sys_getParent(this) ... } // {1}
getAt(index int) Node { ... }
}
root = Node.setTag("document")
.add(Node.setTag("head"))
.add(Node.setTag("body")
.add(Node.setTag("div")));
div = root[1][0];
sys_log(div.parent().parent().tag); // prints "document"
In this example we build a toy HTML DOM and traverse it.
The built-in sys_getParent
function in line {1} extracts the actual parent pointer that is automatically maintained by argentum runtime.
This parent pointers also assist a new "splice" operation, that allows to extract an existing object from one part of the object hierarchy and insert it in other place:
// Example continued
root.children[1] := Node; // Now body is no more nested in the root document.
// it will be deleted,
// but its nested div is still retained with `div` variable.
sys_spliceAt(root.children, 1, div); // Now div is inserted in root collection.
Splice operation checks if the new host object is not nested in the object-been-spliced, and if so, doesn't do splicing and returns false. So splicing is a 100% safe (but not 100% successful) operation.
Splicing also available for scalar fields:
// Continued example
class Pair {
a = Node;
b = Node;
}
p = Pair;
head = root[0];
root := Node; // Now all document is deleted, but head remains.
p.a @= head; // "Splice to field" operator @=
TL;DR
Now parts of tree-like data structures can be rearranged in safe manner instead of copy-destroy sequences as it was before.
Now parent pointers are built-in all Argentum objects.