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: * "for" "(" (PreLoopStatement)? ";" (Expression1)? ";" (Expression2)? ")"
031: * EvaluationUnit
032: * </pre>
033: * to
034: * <pre>
035: * "{"
036: * (PreLoopStatement)? ";"
037: * "while" "(" Expression1 ")"
038: * "{"
039: * EvaluationUnit
040: * (Expression2)?
041: * "}"
042: * "}"
043: * </pre>
044: *
045: * <!--
046: * Note that current implementation substitutes NodeToken-s for the most
047: * similar NodeToken in the input. This makes row/col #'s the most sane,
048: * but the string representation may be wrong, for example "for" instead
049: * of "while". I did it this way since it is the least overhead, which
050: * matters for the interpreter. That should work find with the current
051: * interpreter and compiler implementations
052: * -->
053: *
054: * @author Rob Clark
055: * @version 0.1
056: */
057: public class ForLoopStatementTranslator {
058: /**
059: * Convert a {@link ForLoopStatement} production in the syntaxtree
060: * into an equivalent production.
061: * <PRE>
062: * f0 -> "for"
063: * f1 -> "("
064: * f2 -> ( PreLoopStatement() )?
065: * f3 -> ";"
066: * f4 -> ( Expression() )?
067: * f5 -> ";"
068: * f6 -> ( Expression() )?
069: * f7 -> ")"
070: * f8 -> EvaluationUnit()
071: * </PRE>
072: */
073: public static Node translate(ForLoopStatement n) {
074: if (n.translated == null) {
075: n.translated = new ScopeBlock(n.f0, // "{"
076: makeProgram(n), // Program
077: n.f0, // "}"
078: n.hasVarInScope, n.hasFxnInScope);
079: }
080: return n.translated;
081: }
082:
083: private static Program makeProgram(ForLoopStatement n) {
084: NodeListOptional nlo = new NodeListOptional();
085:
086: if (n.f2.present())
087: nlo.addNode(new EvaluationUnit(new NodeChoice(n.f2.node)));// PreLoopStatement
088: nlo.addNode(makeWhileLoopStatement(n));
089:
090: return new Program(nlo, false);
091: }
092:
093: private static WhileLoopStatement makeWhileLoopStatement(
094: ForLoopStatement n) {
095: return new WhileLoopStatement(n.f0, // "while"
096: n.f1, // "("
097: makeExpression(n), // Expression1
098: n.f7, // ")"
099: makeEvaluationUnit(n) // EvaluationUnit
100: );
101: }
102:
103: private static Expression makeExpression(ForLoopStatement n) {
104: if (n.f4.present())
105: return (Expression) (n.f4.node);
106: else
107: return makeTrueExpression(n);
108: }
109:
110: private static final NodeListOptional EMPTY_NLO = new NodeListOptional();
111: private static final NodeOptional EMPTY_NO = new NodeOptional();
112:
113: private static Expression makeTrueExpression(ForLoopStatement n) {
114: final oscript.parser.Token token = new oscript.parser.Token();
115: token.kind = oscript.parser.OscriptParserConstants.TRUE;
116:
117: token.beginLine = n.f5.beginLine;
118: token.beginColumn = n.f5.beginColumn;
119: token.beginOffset = n.f5.beginOffset;
120: token.endLine = n.f5.endLine;
121: token.endColumn = n.f5.endColumn;
122: token.endOffset = n.f5.endOffset;
123:
124: return new Expression(
125: new AssignmentExpression(
126: new ConditionalExpression(
127: new LogicalOrExpression(
128: new LogicalAndExpression(
129: new BitwiseOrExpression(
130: new BitwiseXorExpression(
131: new BitwiseAndExpression(
132: new EqualityExpression(
133: new RelationalExpression(
134: new ShiftExpression(
135: new AdditiveExpression(
136: new MultiplicativeExpression(
137: new UnaryExpression(
138: EMPTY_NO,
139: new PostfixExpression(
140: new TypeExpression(
141: new NodeChoice(
142: new NodeToken(
143: "true",
144: oscript.data.OString
145: .makeString("true"),
146: token,
147: n.f5.desc))),
148: EMPTY_NO)),
149: EMPTY_NLO),
150: EMPTY_NLO),
151: EMPTY_NLO),
152: EMPTY_NLO),
153: EMPTY_NLO),
154: EMPTY_NLO),
155: EMPTY_NLO),
156: EMPTY_NLO),
157: EMPTY_NLO), EMPTY_NLO),
158: EMPTY_NO), EMPTY_NLO), EMPTY_NLO);
159: }
160:
161: private static EvaluationUnit makeEvaluationUnit(ForLoopStatement n) {
162: NodeListOptional nlo = new NodeListOptional();
163:
164: nlo.addNode(n.f8); // EvaluationUnit
165: if (n.f6.present())
166: nlo.addNode(n.f6.node); // Expression2
167:
168: Program loopBody = new Program(nlo, false);
169:
170: return new EvaluationUnit(new NodeChoice(new ScopeBlock(n.f0, // "{"
171: loopBody, // Program
172: n.f0, // "}"
173: false, n.hasFxnInScope)));
174: }
175: }
176:
177: /*
178: * Local Variables:
179: * tab-width: 2
180: * indent-tabs-mode: nil
181: * mode: java
182: * c-indentation-style: java
183: * c-basic-offset: 2
184: * eval: (c-set-offset 'substatement-open '0)
185: * eval: (c-set-offset 'case-label '+)
186: * eval: (c-set-offset 'inclass '+)
187: * eval: (c-set-offset 'inline-open '0)
188: * End:
189: */
|