!7 sclass Node { new LinkedHashSet children; toString { ret shortClassName(this) + ": " + toString2(); } abstract S toString2(); void add(Node n) { children.add(n); } } sclass TextNode > Node { S text; *() {} *(S *text) {} S toString2() { ret text; } } sclass TokNode > Node { L tok; *() {} *(LS *tok) {} S toString2() { ret sfu(tok); } public bool equals(O o) { ret stdEq(this, o, 'tok); } public int hashCode() { ret stdHash2(this, 'tok); } } p-exp { S input = first(mL("Monolog examples")); TextNode root = new(input); processNode(root); showFrame(jDynamicTree(root, func(Node n) -> Collection { n.children })); } svoid processNode(Node n) { if (n instanceof TextNode) { TextNode tn = cast n; L tok = javaTokPlusCurly_dontKeep(tn.text); n.add(TokNode(tok)); } indexOfSubList(tok, ll("=", "", ">") splitAtDoubleArrow(n); }