UnwrapLeft, error reporting improvements
[sbp.git] / src / edu / berkeley / sbp / Tree.java
1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
2
3 package edu.berkeley.sbp;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.util.*;
6 import java.io.*;
7 import java.util.*;
8 import java.lang.reflect.*;
9
10 /** <font color=blue>a tree (or node in a tree); see jargon.txt for details</font> */
11 public class Tree<NodeType>
12     extends PrintableTree<Tree<NodeType>>
13     implements Iterable<Tree<NodeType>> {
14
15     private final Input.Region     location;
16     private final NodeType         ihead;
17     private final Tree<NodeType>[] children;
18
19     /** the number of children the tree has */
20     public int               size() { return children.length; }
21
22     /** the element at the head of the tree */
23     public NodeType                 head()        { return ihead; }
24     public NodeType              getHead()        { return ihead; }
25
26     /** the tree's children */
27     public Iterable<Tree<NodeType>> children()    { return this; }
28
29     /** the tree's children */
30     public Iterator<Tree<NodeType>> iterator()    { return new ArrayIterator(children); }
31
32     /** get the <tt>i</t>th child */
33     public Tree<NodeType> child(int i)            { return children[i]; }
34
35     /** get the input region that this tree was parsed from */
36     public Input.Region    getRegion() { return location; }
37
38     public Tree(Input.Region loc, NodeType head)                            { this(loc, head, null); }
39     public Tree(Input.Region loc, NodeType head, Tree<NodeType>[] children) { this(loc, head, children, false); }
40
41     // FIXME: fairly inefficient because we keep copying arrays
42     /** package-private constructor, allows setting the "lift" bit */
43     Tree(Input.Region loc, NodeType head, Tree<NodeType>[] children, boolean lift) {
44         this(loc, head, children, lift, false);
45     }
46     Tree(Input.Region loc, NodeType head, Tree<NodeType>[] children, boolean lift, boolean liftLeft) {
47         this.location = loc;
48         this.ihead = head;
49         // FIXME: lift+liftLeft togheter
50         if (liftLeft && children != null && children.length > 0) {
51             Tree<NodeType> last = children[0];
52             this.children = new Tree[(children.length-1)+last.children.length];
53             System.arraycopy(children, 1, this.children, last.children.length, children.length-1);
54             if (last.children.length > 0)
55                 System.arraycopy(last.children, 0, this.children, 0, last.children.length);
56         } else if (lift && children != null && children.length > 0) {
57             Tree<NodeType> last = children[children.length-1];
58             this.children = new Tree[(children.length-1)+last.children.length];
59             System.arraycopy(children, 0, this.children, 0, children.length-1);
60             if (last.children.length > 0)
61                 System.arraycopy(last.children, 0, this.children, children.length-1, last.children.length);
62         } else {
63             this.children = ArrayUtil.clone(children, Tree.class);
64         }
65     }
66
67
68     // PrintableTree /////////////////////////////////////////////////////////////////////////////
69
70     protected String headToString() { return head()==null?null:head().toString(); }
71     protected String headToJava()   {
72       // FIXME
73         if (head()==null) return null;
74         if (head() instanceof ToJava) {
75             StringBuffer sb = new StringBuffer();
76             ((ToJava)head()).toJava(sb);
77             return sb.toString();
78         }
79         return (head()==null?"null":("\""+StringUtil.toJavaString(head().toString())+"\""));
80     }
81     protected String left()   { return "{"; }
82     protected String right()  { return "}"; }
83     protected boolean ignoreSingleton() { return false; }
84
85
86 }