001: /*=============================================================================
002: * Copyright Texas Instruments 2003. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.translator;
022:
023: import oscript.syntaxtree.*;
024:
025: /**
026: * A translator to implement one part of the language in terms of another.
027: * This simplifies the compiler/interpreter implementation. This translates
028: * from:
029: * <pre>
030: * Permissions "function" <IDENTIFIER> "(" Arglist ")" ("extends" ...)?
031: * "{"
032: * Program
033: * "}"
034: * </pre>
035: * to
036: * <pre>
037: * Permissions "var" <IDENTIFIER> "=" "function" "(" Arglist ")" ("extends" ...)?
038: * "{"
039: * Program
040: * "};"
041: * </pre>
042: *
043: * <!--
044: * Note that current implementation substitutes NodeToken-s for the most
045: * similar NodeToken in the input. This makes row/col #'s the most sane,
046: * but the string representation may be wrong, for example "function"
047: * instead of "var". I did it this way since it is the least overhead,
048: * which matters for the interpreter. That should work find with the
049: * current interpreter and compiler implementations
050: * -->
051: *
052: * @author Rob Clark
053: * @version 0.1
054: */
055: public class FunctionDeclarationTranslator {
056: /**
057: * Convert a {@link FunctionDeclaration} production in the syntaxtree
058: * into an equivalent production.
059: * <pre>
060: * f0 -> Permissions(true)
061: * f1 -> "function"
062: * f2 -> <IDENTIFIER>
063: * f3 -> "("
064: * f4 -> ( Arglist() )?
065: * f5 -> ")"
066: * f6 -> ( "extends" PrimaryExpressionWithTrailingFxnCallExpList() FunctionCallExpressionList() )?
067: * f7 -> "{"
068: * f8 -> Program(true)
069: * f9 -> "}"
070: * </pre>
071: */
072: public static Node translate(FunctionDeclaration n) {
073: if (n.translated == null) {
074: n.translated = new VariableDeclaration(n.f0, // Permissions()
075: n.f1, // "var"
076: n.f2, // <IDENTIFIER>
077: makeNodeOptional(n) // ("=" Expression())?
078: );
079: }
080: return n.translated;
081: }
082:
083: private static NodeOptional makeNodeOptional(FunctionDeclaration n) {
084: NodeSequence ns = new NodeSequence(2);
085:
086: ns.addNode(n.f1); // "="
087:
088: // NOTE: we are cheating a bit by putting the FunctionPrimaryPrefix
089: // directly here, and skipping all the intermediary nodes. This
090: // is faster, and works with the current compiler/interpreter
091: ns.addNode(makeFunctionPrimaryPrefix(n));
092:
093: return new NodeOptional(ns);
094: }
095:
096: private static FunctionPrimaryPrefix makeFunctionPrimaryPrefix(
097: FunctionDeclaration n) {
098: FunctionPrimaryPrefix fpp = new FunctionPrimaryPrefix(n.f1, // "function"
099: n.f3, // "("
100: n.f4, // (Arglist())?
101: n.f5, // ")"
102: n.f6, // ("extends" ...)?
103: n.f7, // "{"
104: n.f8, // Program()
105: n.f9, // "}"
106: n.hasVarInScope, n.hasFxnInScope);
107:
108: fpp.id = oscript.data.Symbol.getSymbol(n.f2.toString()).getId();
109:
110: return fpp;
111: }
112: }
113:
114: /*
115: * Local Variables:
116: * tab-width: 2
117: * indent-tabs-mode: nil
118: * mode: java
119: * c-indentation-style: java
120: * c-basic-offset: 2
121: * eval: (c-set-offset 'substatement-open '0)
122: * eval: (c-set-offset 'case-label '+)
123: * eval: (c-set-offset 'inclass '+)
124: * eval: (c-set-offset 'inline-open '0)
125: * End:
126: */
|