001: /***** BEGIN LICENSE BLOCK *****
002: * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003: *
004: * The contents of this file are subject to the Common Public
005: * License Version 1.0 (the "License"); you may not use this file
006: * except in compliance with the License. You may obtain a copy of
007: * the License at http://www.eclipse.org/legal/cpl-v10.html
008: *
009: * Software distributed under the License is distributed on an "AS
010: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011: * implied. See the License for the specific language governing
012: * rights and limitations under the License.
013: *
014: * Copyright (C) 2006 Thomas E Enebo <enebo@acm.org>
015: *
016: * Alternatively, the contents of this file may be used under the terms of
017: * either of the GNU General Public License Version 2 or later (the "GPL"),
018: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
019: * in which case the provisions of the GPL or the LGPL are applicable instead
020: * of those above. If you wish to allow use of your version of this file only
021: * under the terms of either the GPL or the LGPL, and not to allow others to
022: * use your version of this file under the terms of the CPL, indicate your
023: * decision by deleting the provisions above and replace them with the notice
024: * and other provisions required by the GPL or the LGPL. If you do not delete
025: * the provisions above, a recipient may use your version of this file under
026: * the terms of any one of the CPL, the GPL or the LGPL.
027: ***** END LICENSE BLOCK *****/package org.jruby.ast;
028:
029: import java.util.List;
030:
031: import org.jruby.ast.visitor.NodeVisitor;
032: import org.jruby.evaluator.Instruction;
033: import org.jruby.lexer.yacc.ISourcePosition;
034: import org.jruby.parser.StaticScope;
035: import org.jruby.runtime.DynamicScope;
036:
037: /**
038: * Represents the top of the AST. This is a node not present in MRI. It was created to
039: * hold the top-most static scope in an easy to grab way and it also exists to hold BEGIN
040: * and END nodes. These can then be interpreted/compiled in the same places as the rest
041: * of the code.
042: *
043: */
044: // TODO: Store BEGIN and END information into this node
045: // TODO: Implement BEGIN and END logic so they get invoked at the correct time.
046: public class RootNode extends Node {
047: private static final long serialVersionUID = 1754281364026417051L;
048:
049: private transient DynamicScope scope;
050: private StaticScope staticScope;
051: private Node bodyNode;
052:
053: public RootNode(ISourcePosition position, DynamicScope scope,
054: Node bodyNode) {
055: super (position, NodeTypes.ROOTNODE);
056:
057: this .scope = scope;
058: this .staticScope = scope.getStaticScope();
059: this .bodyNode = bodyNode;
060: }
061:
062: /**
063: * Return the dynamic scope for this AST. The variable backed by this is transient so
064: * for serialization this is null. In that case we use staticScope to rebuild the dynamic
065: * scope. The real reason for this method is supporting bindings+eval. We need to pass
066: * our live dynamic scope in so when we eval we can use that dynamic scope.
067: *
068: * @return dynamic scope of this AST
069: */
070: public DynamicScope getScope() {
071: return scope;
072: }
073:
074: /**
075: * The static scoping relationships that should get set first thing before interpretation
076: * of the code represented by this AST. Actually, we use getScope first since that also
077: * can contain a live dynamic scope. We rely on this method only for interpreting a root
078: * node from a serialized format.
079: *
080: * @return the top static scope for the AST
081: */
082: public StaticScope getStaticScope() {
083: return staticScope;
084: }
085:
086: /**
087: * First real AST node to be interpreted
088: *
089: * @return real top AST node
090: */
091: public Node getBodyNode() {
092: return bodyNode;
093: }
094:
095: public Instruction accept(NodeVisitor iVisitor) {
096: return iVisitor.visitRootNode(this );
097: }
098:
099: public List childNodes() {
100: return createList(bodyNode);
101: }
102:
103: }
|