001 /* Generated By:JavaCC: Do not edit this line. JJTJSParserState.java Version 5.0 */
002 package org.descripter.js.parse;
003 
004 public class JJTJSParserState {
005   private java.util.List<Node> nodes;
006   private java.util.List<Integer> marks;
007 
008   private int sp;        // number of nodes on stack
009   private int mk;        // current mark
010   private boolean node_created;
011 
012   public JJTJSParserState() {
013     nodes = new java.util.ArrayList<Node>();
014     marks = new java.util.ArrayList<Integer>();
015     sp = 0;
016     mk = 0;
017   }
018 
019   /* Determines whether the current node was actually closed and
020      pushed.  This should only be called in the final user action of a
021      node scope.  */
022   public boolean nodeCreated() {
023     return node_created;
024   }
025 
026   /* Call this to reinitialize the node stack.  It is called
027      automatically by the parser's ReInit() method. */
028   public void reset() {
029     nodes.clear();
030     marks.clear();
031     sp = 0;
032     mk = 0;
033   }
034 
035   /* Returns the root node of the AST.  It only makes sense to call
036      this after a successful parse. */
037   public Node rootNode() {
038     return nodes.get(0);
039   }
040 
041   /* Pushes a node on to the stack. */
042   public void pushNode(Node n) {
043     nodes.add(n);
044     ++sp;
045   }
046 
047   /* Returns the node on the top of the stack, and remove it from the
048      stack.  */
049   public Node popNode() {
050     if (--sp < mk) {
051       mk = marks.remove(marks.size()-1);
052     }
053     return nodes.remove(nodes.size()-1);
054   }
055 
056   /* Returns the node currently on the top of the stack. */
057   public Node peekNode() {
058     return nodes.get(nodes.size()-1);
059   }
060 
061   /* Returns the number of children on the stack in the current node
062      scope. */
063   public int nodeArity() {
064     return sp - mk;
065   }
066 
067 
068   public void clearNodeScope(Node n) {
069     while (sp > mk) {
070       popNode();
071     }
072     mk = marks.remove(marks.size()-1);
073   }
074 
075 
076   public void openNodeScope(Node n) {
077     marks.add(mk);
078     mk = sp;
079     n.jjtOpen();
080   }
081 
082 
083   /* A definite node is constructed from a specified number of
084      children.  That number of nodes are popped from the stack and
085      made the children of the definite node.  Then the definite node
086      is pushed on to the stack. */
087   public void closeNodeScope(Node n, int num) {
088     mk = marks.remove(marks.size()-1);
089     while (num-- > 0) {
090       Node c = popNode();
091       c.jjtSetParent(n);
092       n.jjtAddChild(c, num);
093     }
094     n.jjtClose();
095     pushNode(n);
096     node_created = true;
097   }
098 
099 
100   /* A conditional node is constructed if its condition is true.  All
101      the nodes that have been pushed since the node was opened are
102      made children of the conditional node, which is then pushed
103      on to the stack.  If the condition is false the node is not
104      constructed and they are left on the stack. */
105   public void closeNodeScope(Node n, boolean condition) {
106     if (condition) {
107       int a = nodeArity();
108       mk = marks.remove(marks.size()-1);
109       while (a-- > 0) {
110         Node c = popNode();
111         c.jjtSetParent(n);
112         n.jjtAddChild(c, a);
113       }
114       n.jjtClose();
115       pushNode(n);
116       node_created = true;
117     } else {
118       mk = marks.remove(marks.size()-1);
119       node_created = false;
120     }
121   }
122 }