001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package bsh;
033:
034: /*
035: Note: great care (and lots of typing) were taken to insure that the
036: namespace and interpreter references are passed on the stack and not
037: (as they were erroneously before) installed in instance variables...
038: Each of these node objects must be re-entrable to allow for recursive
039: situations.
040:
041: The only data which should really be stored in instance vars here should
042: be parse tree data... features of the node which should never change (e.g.
043: the number of arguments, etc.)
044:
045: Exceptions would be public fields of simple classes that just publish
046: data produced by the last eval()... data that is used immediately. We'll
047: try to remember to mark these as transient to highlight them.
048:
049: */
050: class SimpleNode implements Node {
051: public static SimpleNode JAVACODE = new SimpleNode(-1) {
052: public String getSourceFile() {
053: return "<Called from Java Code>";
054: }
055:
056: public int getLineNumber() {
057: return -1;
058: }
059:
060: public String getText() {
061: return "<Compiled Java Code>";
062: }
063: };
064:
065: protected Node parent;
066: protected Node[] children;
067: protected int id;
068: Token firstToken, lastToken;
069:
070: /** the source of the text from which this was parsed */
071: String sourceFile;
072:
073: public SimpleNode(int i) {
074: id = i;
075: }
076:
077: public void jjtOpen() {
078: }
079:
080: public void jjtClose() {
081: }
082:
083: public void jjtSetParent(Node n) {
084: parent = n;
085: }
086:
087: public Node jjtGetParent() {
088: return parent;
089: }
090:
091: //public SimpleNode getParent() { return (SimpleNode)parent; }
092:
093: public void jjtAddChild(Node n, int i) {
094: if (children == null)
095: children = new Node[i + 1];
096: else if (i >= children.length) {
097: Node c[] = new Node[i + 1];
098: System.arraycopy(children, 0, c, 0, children.length);
099: children = c;
100: }
101:
102: children[i] = n;
103: }
104:
105: public Node jjtGetChild(int i) {
106: return children[i];
107: }
108:
109: public SimpleNode getChild(int i) {
110: return (SimpleNode) jjtGetChild(i);
111: }
112:
113: public int jjtGetNumChildren() {
114: return (children == null) ? 0 : children.length;
115: }
116:
117: /*
118: You can override these two methods in subclasses of SimpleNode to
119: customize the way the node appears when the tree is dumped. If
120: your output uses more than one line you should override
121: toString(String), otherwise overriding toString() is probably all
122: you need to do.
123: */
124: public String toString() {
125: return ParserTreeConstants.jjtNodeName[id];
126: }
127:
128: public String toString(String prefix) {
129: return prefix + toString();
130: }
131:
132: /*
133: Override this method if you want to customize how the node dumps
134: out its children.
135: */
136: public void dump(String prefix) {
137: System.out.println(toString(prefix));
138: if (children != null) {
139: for (int i = 0; i < children.length; ++i) {
140: SimpleNode n = (SimpleNode) children[i];
141: if (n != null) {
142: n.dump(prefix + " ");
143: }
144: }
145: }
146: }
147:
148: // ---- BeanShell specific stuff hereafter ---- //
149:
150: /**
151: Detach this node from its parent.
152: This is primarily useful in node serialization.
153: (see BSHMethodDeclaration)
154: */
155: public void prune() {
156: jjtSetParent(null);
157: }
158:
159: /**
160: This is the general signature for evaluation of a node.
161: */
162: public Object eval(CallStack callstack, Interpreter interpreter)
163: throws EvalError {
164: throw new InterpreterError(
165: "Unimplemented or inappropriate for "
166: + getClass().getName());
167: }
168:
169: /**
170: Set the name of the source file (or more generally source) of
171: the text from which this node was parsed.
172: */
173: public void setSourceFile(String sourceFile) {
174: this .sourceFile = sourceFile;
175: }
176:
177: /**
178: Get the name of the source file (or more generally source) of
179: the text from which this node was parsed.
180: This will recursively search up the chain of parent nodes until
181: a source is found or return a string indicating that the source
182: is unknown.
183: */
184: public String getSourceFile() {
185: if (sourceFile == null)
186: if (parent != null)
187: return ((SimpleNode) parent).getSourceFile();
188: else
189: return "<unknown file>";
190: else
191: return sourceFile;
192: }
193:
194: /**
195: Get the line number of the starting token
196: */
197: public int getLineNumber() {
198: return firstToken.beginLine;
199: }
200:
201: /**
202: Get the ending line number of the starting token
203: public int getEndLineNumber() {
204: return lastToken.endLine;
205: }
206: */
207:
208: /**
209: Get the text of the tokens comprising this node.
210: */
211: public String getText() {
212: StringBuffer text = new StringBuffer();
213: Token t = firstToken;
214: while (t != null) {
215: text.append(t.image);
216: if (!t.image.equals("."))
217: text.append(" ");
218: if (t == lastToken || t.image.equals("{")
219: || t.image.equals(";"))
220: break;
221: t = t.next;
222: }
223:
224: return text.toString();
225: }
226: }
|