001/* A visitor for parse trees of the expression language that generates C code.
002
003 Copyright (c) 2003-2018 The Regents of the University of California
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA OR RESEARCH IN MOTION
012 LIMITED BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
013 INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
014 SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
015 OR RESEARCH IN MOTION LIMITED HAVE BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED
019 SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
021 PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
022 BASIS, AND THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION
023 LIMITED HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
024 ENHANCEMENTS, OR MODIFICATIONS.
025
026
027 */
028package ptolemy.data.expr;
029
030import java.lang.reflect.Method;
031import java.util.HashMap;
032import java.util.List;
033
034import ptolemy.kernel.util.IllegalActionException;
035import ptolemy.kernel.util.InternalErrorException;
036
037///////////////////////////////////////////////////////////////////
038//// ParseTreeCodeGenerator
039
040/**
041 This class visits parse trees and generates soot instructions that evaluate the parse tree.
042
043 @author Steve Neuendorffer
044 @version $Id$
045 @since Ptolemy II 4.0
046 @Pt.ProposedRating Red (neuendor)
047 @Pt.AcceptedRating Red (cxh)
048 @see ptolemy.data.expr.ASTPtRootNode
049 */
050public class CParseTreeCodeGenerator extends AbstractParseTreeVisitor {
051    ///////////////////////////////////////////////////////////////////
052    ////                         public methods                    ////
053    /** Generate code for a node.
054     *  @param node The node for which code is generated.
055     *  @exception IllegalActionException If type inference fails.
056     */
057    public void generateCode(ASTPtRootNode node) throws IllegalActionException {
058        ParseTreeTypeInference typeInference = new ParseTreeTypeInference();
059        typeInference.inferTypes(node); // FIXME: scope?
060
061        //    _scope = scope;
062        _nodeToLocalName = new HashMap();
063        _nodeNumber = 0;
064        node.visit(this);
065        _nodeToLocalName = null;
066
067        //   _scope = null;
068    }
069
070    @Override
071    public void visitArrayConstructNode(ASTPtArrayConstructNode node)
072            throws IllegalActionException {
073        _generateAllChildren(node);
074
075        String nodeName = "node" + _nodeNumber++;
076        _nodeToLocalName.put(node, nodeName);
077
078        System.out.println(nodeName + " = FIXME:Array");
079    }
080
081    @Override
082    public void visitBitwiseNode(ASTPtBitwiseNode node)
083            throws IllegalActionException {
084        _generateAllChildren(node);
085
086        int numChildren = node.jjtGetNumChildren();
087
088        _assert(numChildren > 0, node,
089                "The number of child nodes must be greater than zero");
090
091        String nodeName = "node" + _nodeNumber++;
092        _nodeToLocalName.put(node, nodeName);
093
094        // Make sure that exactly one of AND, OR, XOR is set.
095        _assert(node.isBitwiseAnd() ^ node.isBitwiseOr() ^ node.isBitwiseXor(),
096                node, "Invalid operation");
097
098        StringBuffer statement = new StringBuffer(
099                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
100
101        for (int i = 1; i < numChildren; i++) {
102            if (node.isBitwiseAnd()) {
103                statement.append("&");
104            } else if (node.isBitwiseOr()) {
105                statement.append("|");
106            } else if (node.isBitwiseXor()) {
107                statement.append("^");
108            } else {
109                throw new RuntimeException("Unrecognized node");
110            }
111
112            statement.append(_nodeToLocalName.get(node.jjtGetChild(i)));
113        }
114
115        System.out.println(statement.toString());
116    }
117
118    @Override
119    public void visitFunctionApplicationNode(ASTPtFunctionApplicationNode node)
120            throws IllegalActionException {
121        // Method calls are generally not cached...  They are repeated
122        // every time the tree is evaluated.
123        int numChildren = node.jjtGetNumChildren();
124        int argCount = numChildren - 1;
125
126        for (int i = 1; i < numChildren; i++) {
127            _generateChild(node, i);
128        }
129
130        String nodeName = "node" + _nodeNumber++;
131        _nodeToLocalName.put(node, nodeName);
132
133        if (_isValidName(node.getFunctionName())) {
134            //          Local local = _getLocalForName(node.getFunctionName());
135            //             Local resultLocal = Jimple.v().newLocal("token",
136            //                     RefType.v(PtolemyUtilities.tokenClass));
137            //             _body.getLocals().add(resultLocal);
138            if (argCount == 1) {
139                // array..
140                System.out.println(nodeName + " = ");
141                System.out.println(_nodeToLocalName.get(node.jjtGetChild(0))
142                        + "[" + _nodeToLocalName.get(node.jjtGetChild(1))
143                        + "]");
144            } else if (argCount == 2) {
145                // matrix..
146                System.out.println(nodeName + " = ");
147                System.out.println(_nodeToLocalName.get(node.jjtGetChild(0))
148                        + "[" + _nodeToLocalName.get(node.jjtGetChild(1)) + ","
149                        + _nodeToLocalName.get(node.jjtGetChild(1)) + "]");
150            } else {
151                throw new IllegalActionException("Wrong number of indices "
152                        + "when referencing " + node.getFunctionName());
153            }
154
155            return;
156        }
157
158        if (node.getFunctionName().compareTo("eval") == 0) {
159            throw new IllegalActionException("unimplemented case");
160        }
161
162        if (node.getFunctionName().compareTo("matlab") == 0) {
163            throw new IllegalActionException("unimplemented case");
164        }
165
166        // Otherwise, try to reflect the method name.
167        // The array of token types that the method takes.
168        ptolemy.data.type.Type[] argTypes = new ptolemy.data.type.Type[argCount];
169
170        for (int i = 0; i < argCount; i++) {
171            argTypes[i] = ((ASTPtRootNode) node.jjtGetChild(i + 1)).getType();
172        }
173
174        // Find the method...
175        CachedMethod cachedMethod = CachedMethod.findMethod(
176                node.getFunctionName(), argTypes, CachedMethod.FUNCTION);
177
178        if (!cachedMethod.isValid()) {
179            throw new IllegalActionException(
180                    "Function " + cachedMethod + " not found.");
181        }
182
183        if (cachedMethod instanceof CachedMethod.BaseConvertCachedMethod
184                || cachedMethod instanceof CachedMethod.ArrayMapCachedMethod
185                || cachedMethod instanceof CachedMethod.MatrixMapCachedMethod) {
186            throw new IllegalActionException("CodeGeneration not supported for "
187                    + cachedMethod.getClass());
188        }
189
190        Method method = cachedMethod.getMethod();
191
192        //CachedMethod.ArgumentConversion[] conversions = cachedMethod
193        //        .getConversions();
194
195        //for (int i = 0; i < argCount; i++) {
196        // Insert the appropriate conversion.
197        //    String argName = (String) _nodeToLocalName.get(node
198        //            .jjtGetChild(i + 1));
199
200        // _convertTokenArgToJavaArg(
201        //    tokenLocal, argTypes[i], conversions[i]);
202        //            args.add(argLocal);
203        //}
204
205        System.out.println(
206                nodeName + " = FIXME:method invocation of " + method.getName());
207
208        // Convert the result back to a token.
209        String convertedReturnName = "FIXME"; //_convertJavaResultToToken(returnLocal, returnType);
210        _nodeToLocalName.put(node, convertedReturnName);
211    }
212
213    // Add code to the method being generated to convert the given
214    // returnLocal, with the given returnType to a token type.  Return
215    // the new token local.
216
217    /*private Local _convertJavaResultToToken(
218     Local returnLocal, Type returnType)
219     throws IllegalActionException {
220     Local tokenLocal;
221     FIXME!
222     if (returnType instanceof RefType &&
223     SootUtilities.derivesFrom(
224     ((RefType)returnType).getSootClass(),
225     PtolemyUtilities.tokenClass)) {
226     tokenLocal = returnLocal;
227     } else if (returnType.equals(
228     ArrayType.v(PtolemyUtilities.tokenType, 1))) {
229     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
230     PtolemyUtilities.arrayTokenClass,
231     PtolemyUtilities.arrayTokenConstructor,
232     returnLocal);
233     } else if (returnType.equals(DoubleType.v())) {
234     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
235     PtolemyUtilities.doubleTokenClass,
236     PtolemyUtilities.doubleTokenConstructor,
237     returnLocal);
238     } else if (returnType.equals(LongType.v())) {
239     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
240     PtolemyUtilities.longTokenClass,
241     PtolemyUtilities.longTokenConstructor,
242     returnLocal);
243     } else if (returnType.equals(RefType.v("java.lang.String"))) {
244     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
245     PtolemyUtilities.stringTokenClass,
246     PtolemyUtilities.stringTokenConstructor,
247     returnLocal);
248     } else if (returnType.equals(BooleanType.v())) {
249     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
250     PtolemyUtilities.booleanTokenClass,
251     PtolemyUtilities.booleanTokenConstructor,
252     returnLocal);
253     } else if (returnType.equals(RefType.v("ptolemy.math.Complex"))) {
254     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
255     PtolemyUtilities.complexTokenClass,
256     PtolemyUtilities.complexTokenConstructor,
257     returnLocal);
258     } else if (returnType.equals(RefType.v("ptolemy.math.FixPoint"))) {
259     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
260     PtolemyUtilities.fixTokenClass,
261     PtolemyUtilities.fixTokenConstructor,
262     returnLocal);
263     } else if (returnType.equals(ArrayType.v(BooleanType.v(),2))) {
264     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
265     PtolemyUtilities.booleanMatrixTokenClass,
266     PtolemyUtilities.booleanMatrixTokenConstructor,
267     returnLocal);
268
269     } else if (returnType.equals(ArrayType.v(IntType.v(),2))) {
270     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
271     PtolemyUtilities.intMatrixTokenClass,
272     PtolemyUtilities.intMatrixTokenConstructor,
273     returnLocal);
274
275     } else if (returnType.equals(ArrayType.v(LongType.v(),2))) {
276     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
277     PtolemyUtilities.doubleMatrixTokenClass,
278     PtolemyUtilities.doubleMatrixTokenConstructor,
279     returnLocal);
280
281     } else if (returnType.equals(ArrayType.v(DoubleType.v(),2))) {
282     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
283     PtolemyUtilities.doubleMatrixTokenClass,
284     PtolemyUtilities.doubleMatrixTokenConstructor,
285     returnLocal);
286
287     } else if (returnType.equals(ArrayType.v(RefType.v("ptolemy.math.Complex"),2))) {
288     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
289     PtolemyUtilities.complexMatrixTokenClass,
290     PtolemyUtilities.complexMatrixTokenConstructor,
291     returnLocal);
292
293     } else if (returnType.equals(ArrayType.v(RefType.v("ptolemy.math.FixPoint"),2))) {
294     tokenLocal = PtolemyUtilities.addTokenLocalBefore(_body, _insertPoint, "token",
295     PtolemyUtilities.fixMatrixTokenClass,
296     PtolemyUtilities.fixMatrixTokenConstructor,
297     returnLocal);
298
299     } else {
300     throw new IllegalActionException("unrecognized case");
301     }
302     return tokenLocal;
303     }
304
305     private Local _convertTokenArgToJavaArg(Local tokenLocal,
306     ptolemy.data.type.Type tokenType,
307     CachedMethod.ArgumentConversion conversion)
308     throws IllegalActionException {
309
310     if (conversion == CachedMethod.IDENTITY_CONVERSION) {
311     Local tempLocal = Jimple.v().newLocal("arg" ,
312     PtolemyUtilities.tokenType);
313     _body.getLocals().add(tempLocal);
314
315     // Add the new local to the list of arguments
316     _units.insertBefore(
317     Jimple.v().newAssignStmt(
318     tempLocal,
319     tokenLocal),
320     _insertPoint);
321     return tempLocal;
322     } else if (conversion == CachedMethod.ARRAYTOKEN_CONVERSION) {
323     Local tempLocal = Jimple.v().newLocal("arg" ,
324     RefType.v(PtolemyUtilities.arrayTokenClass));
325     _body.getLocals().add(tempLocal);
326     Local resultLocal = Jimple.v().newLocal("arg" ,
327     ArrayType.v(RefType.v(PtolemyUtilities.objectClass), 1));
328     _body.getLocals().add(resultLocal);
329
330     // Add the new local to the list of arguments
331     _units.insertBefore(
332     Jimple.v().newAssignStmt(
333     tempLocal,
334     Jimple.v().newCastExpr(
335     tokenLocal,
336     RefType.v(PtolemyUtilities.arrayTokenClass))), _insertPoint);
337     _units.insertBefore(
338     Jimple.v().newAssignStmt(
339     resultLocal,
340     Jimple.v().newVirtualInvokeExpr(
341     tempLocal,
342     PtolemyUtilities.arrayValueMethod)), _insertPoint);
343     return resultLocal;
344     } else if (conversion == CachedMethod.NATIVE_CONVERSION) {
345     if (tokenType == ptolemy.data.type.BaseType.DOUBLE) {
346     Local tempLocal = Jimple.v().newLocal("arg" ,
347     RefType.v(PtolemyUtilities.doubleTokenClass));
348     _body.getLocals().add(tempLocal);
349     Local resultLocal = Jimple.v().newLocal("arg" ,
350     DoubleType.v());
351     _body.getLocals().add(resultLocal);
352     // Add the new local to the list of arguments
353     _units.insertBefore(
354     Jimple.v().newAssignStmt(
355     tempLocal,
356     Jimple.v().newCastExpr(
357     tokenLocal,
358     RefType.v(PtolemyUtilities.doubleTokenClass))), _insertPoint);
359     _units.insertBefore(
360     Jimple.v().newAssignStmt(
361     resultLocal,
362     Jimple.v().newVirtualInvokeExpr(
363     tempLocal,
364     PtolemyUtilities.doubleValueMethod)), _insertPoint);
365     return resultLocal;
366     } else if (tokenType == ptolemy.data.type.BaseType.UNSIGNED_BYTE) {
367     Local tempLocal = Jimple.v().newLocal("arg" ,
368     RefType.v(PtolemyUtilities.unsignedByteTokenClass));
369     _body.getLocals().add(tempLocal);
370     Local resultLocal = Jimple.v().newLocal("arg" ,
371     ByteType.v());
372     _body.getLocals().add(resultLocal);
373     // Add the new local to the list of arguments
374     _units.insertBefore(
375     Jimple.v().newAssignStmt(
376     tempLocal,
377     Jimple.v().newCastExpr(
378     tokenLocal,
379     RefType.v(PtolemyUtilities.unsignedByteTokenClass))), _insertPoint);
380     _units.insertBefore(
381     Jimple.v().newAssignStmt(
382     resultLocal,
383     Jimple.v().newVirtualInvokeExpr(
384     tempLocal,
385     PtolemyUtilities.unsignedByteValueMethod)), _insertPoint);
386     return resultLocal;
387     } else if (tokenType == ptolemy.data.type.BaseType.INT) {
388     Local tempLocal = Jimple.v().newLocal("arg" ,
389     RefType.v(PtolemyUtilities.intTokenClass));
390     _body.getLocals().add(tempLocal);
391     Local resultLocal = Jimple.v().newLocal("arg" ,
392     IntType.v());
393     _body.getLocals().add(resultLocal);
394     // Add the new local to the list of arguments
395     _units.insertBefore(
396     Jimple.v().newAssignStmt(
397     tempLocal,
398     Jimple.v().newCastExpr(
399     tokenLocal,
400     RefType.v("ptolemy.data.IntToken"))), _insertPoint);
401     _units.insertBefore(
402     Jimple.v().newAssignStmt(
403     resultLocal,
404     Jimple.v().newVirtualInvokeExpr(
405     tempLocal,
406     PtolemyUtilities.intValueMethod)), _insertPoint);
407     return resultLocal;
408     } else if (tokenType == ptolemy.data.type.BaseType.LONG) {
409     Local tempLocal = Jimple.v().newLocal("arg" ,
410     RefType.v(PtolemyUtilities.longTokenClass));
411     _body.getLocals().add(tempLocal);
412     Local resultLocal = Jimple.v().newLocal("arg" ,
413     LongType.v());
414     _body.getLocals().add(resultLocal);
415     // Add the new local to the list of arguments
416     _units.insertBefore(
417     Jimple.v().newAssignStmt(
418     tempLocal,
419     Jimple.v().newCastExpr(
420     tokenLocal,
421     RefType.v("ptolemy.data.LongToken"))), _insertPoint);
422     _units.insertBefore(
423     Jimple.v().newAssignStmt(
424     resultLocal,
425     Jimple.v().newVirtualInvokeExpr(
426     tempLocal,
427     PtolemyUtilities.longValueMethod)), _insertPoint);
428     return resultLocal;
429     }  else if (tokenType == ptolemy.data.type.BaseType.STRING) {
430     Local tempLocal = Jimple.v().newLocal("arg" ,
431     RefType.v(PtolemyUtilities.stringTokenClass));
432     _body.getLocals().add(tempLocal);
433     Local resultLocal = Jimple.v().newLocal("arg" ,
434     RefType.v("java.lang.String"));
435     _body.getLocals().add(resultLocal);
436     // Add the new local to the list of arguments
437
438     _units.insertBefore(
439     Jimple.v().newAssignStmt(
440     tempLocal,
441     Jimple.v().newCastExpr(
442     tokenLocal,
443     RefType.v("ptolemy.data.StringToken"))), _insertPoint);
444     _units.insertBefore(
445     Jimple.v().newAssignStmt(
446     resultLocal,
447     Jimple.v().newVirtualInvokeExpr(
448     tempLocal,
449     PtolemyUtilities.stringValueMethod)), _insertPoint);
450     return resultLocal;
451     }  else if (tokenType == ptolemy.data.type.BaseType.BOOLEAN) {
452     Local tempLocal = Jimple.v().newLocal("arg" ,
453     RefType.v(PtolemyUtilities.booleanTokenClass));
454     _body.getLocals().add(tempLocal);
455     Local resultLocal = Jimple.v().newLocal("arg" ,
456     BooleanType.v());
457     _body.getLocals().add(resultLocal);
458     // Add the new local to the list of arguments
459
460     _units.insertBefore(
461     Jimple.v().newAssignStmt(
462     tempLocal,
463     Jimple.v().newCastExpr(
464     tokenLocal,
465     RefType.v("ptolemy.data.BooleanToken"))), _insertPoint);
466     _units.insertBefore(
467     Jimple.v().newAssignStmt(
468     resultLocal,
469     Jimple.v().newVirtualInvokeExpr(
470     tempLocal,
471     PtolemyUtilities.booleanValueMethod)), _insertPoint);
472     return resultLocal;
473     } else if (tokenType == ptolemy.data.type.BaseType.COMPLEX) {
474     Local tempLocal = Jimple.v().newLocal("arg" ,
475     RefType.v(PtolemyUtilities.complexTokenClass));
476     _body.getLocals().add(tempLocal);
477     Local resultLocal = Jimple.v().newLocal("arg" ,
478     RefType.v("ptolemy.math.Complex"));
479     _body.getLocals().add(resultLocal);
480     // Add the new local to the list of arguments
481
482     _units.insertBefore(
483     Jimple.v().newAssignStmt(
484     tempLocal,
485     Jimple.v().newCastExpr(
486     tokenLocal,
487     RefType.v("ptolemy.data.ComplexToken"))), _insertPoint);
488     _units.insertBefore(
489     Jimple.v().newAssignStmt(
490     resultLocal,
491     Jimple.v().newVirtualInvokeExpr(
492     tempLocal,
493     PtolemyUtilities.complexValueMethod)), _insertPoint);
494     return resultLocal;
495     } else if (tokenType == ptolemy.data.type.BaseType.FIX) {
496     Local tempLocal = Jimple.v().newLocal("arg" ,
497     RefType.v(PtolemyUtilities.intTokenClass));
498     _body.getLocals().add(tempLocal);
499     Local resultLocal = Jimple.v().newLocal("arg" ,
500     RefType.v("ptolemy.math.FixPoint"));
501     _body.getLocals().add(resultLocal);
502     // Add the new local to the list of arguments
503
504     _units.insertBefore(
505     Jimple.v().newAssignStmt(
506     tempLocal,
507     Jimple.v().newCastExpr(
508     tokenLocal,
509     RefType.v("ptolemy.data.FixToken"))), _insertPoint);
510     _units.insertBefore(
511     Jimple.v().newAssignStmt(
512     resultLocal,
513     Jimple.v().newVirtualInvokeExpr(
514     tempLocal,
515     PtolemyUtilities.fixValueMethod)), _insertPoint);
516     return resultLocal;
517     } else if (tokenType == ptolemy.data.type.BaseType.DOUBLE_MATRIX) {
518     Local tempLocal = Jimple.v().newLocal("arg" ,
519     RefType.v(PtolemyUtilities.doubleMatrixTokenClass));
520     _body.getLocals().add(tempLocal);
521     Local resultLocal = Jimple.v().newLocal("arg" ,
522     ArrayType.v(DoubleType.v(),2));
523     _body.getLocals().add(resultLocal);
524     // Add the new local to the list of arguments
525
526     _units.insertBefore(
527     Jimple.v().newAssignStmt(
528     tempLocal,
529     Jimple.v().newCastExpr(
530     tokenLocal,
531     RefType.v("ptolemy.data.DoubleMatrixToken"))), _insertPoint);
532     _units.insertBefore(
533     Jimple.v().newAssignStmt(
534     resultLocal,
535     Jimple.v().newVirtualInvokeExpr(
536     tempLocal,
537     PtolemyUtilities.doubleMatrixMethod)), _insertPoint);
538     return resultLocal;
539     } else if (tokenType == ptolemy.data.type.BaseType.INT_MATRIX) {
540     Local tempLocal = Jimple.v().newLocal("arg" ,
541     RefType.v(PtolemyUtilities.intMatrixTokenClass));
542     _body.getLocals().add(tempLocal);
543     Local resultLocal = Jimple.v().newLocal("arg" ,
544     ArrayType.v(IntType.v(),2));
545     _body.getLocals().add(resultLocal);
546     // Add the new local to the list of arguments
547
548     _units.insertBefore(
549     Jimple.v().newAssignStmt(
550     tempLocal,
551     Jimple.v().newCastExpr(
552     tokenLocal,
553     RefType.v("ptolemy.data.IntMatrixToken"))), _insertPoint);
554     _units.insertBefore(
555     Jimple.v().newAssignStmt(
556     resultLocal,
557     Jimple.v().newVirtualInvokeExpr(
558     tempLocal,
559     PtolemyUtilities.intMatrixMethod)), _insertPoint);
560     return resultLocal;
561     } else if (tokenType == ptolemy.data.type.BaseType.LONG_MATRIX) {
562     Local tempLocal = Jimple.v().newLocal("arg" ,
563     RefType.v(PtolemyUtilities.longMatrixTokenClass));
564     _body.getLocals().add(tempLocal);
565     Local resultLocal = Jimple.v().newLocal("arg" ,
566     ArrayType.v(LongType.v(),2));
567     _body.getLocals().add(resultLocal);
568     // Add the new local to the list of arguments
569
570     _units.insertBefore(
571     Jimple.v().newAssignStmt(
572     tempLocal,
573     Jimple.v().newCastExpr(
574     tokenLocal,
575     RefType.v("ptolemy.data.LongMatrixToken"))), _insertPoint);
576     _units.insertBefore(
577     Jimple.v().newAssignStmt(
578     resultLocal,
579     Jimple.v().newVirtualInvokeExpr(
580     tempLocal,
581     PtolemyUtilities.longMatrixMethod)), _insertPoint);
582     return resultLocal;
583     } else if (tokenType == ptolemy.data.type.BaseType.BOOLEAN_MATRIX) {
584     Local tempLocal = Jimple.v().newLocal("arg" ,
585     RefType.v(PtolemyUtilities.booleanMatrixTokenClass));
586     _body.getLocals().add(tempLocal);
587     Local resultLocal = Jimple.v().newLocal("arg" ,
588     ArrayType.v(BooleanType.v(),2));
589     _body.getLocals().add(resultLocal);
590     // Add the new local to the list of arguments
591
592     _units.insertBefore(
593     Jimple.v().newAssignStmt(
594     tempLocal,
595     Jimple.v().newCastExpr(
596     tokenLocal,
597     RefType.v("ptolemy.data.BooleanMatrixToken"))), _insertPoint);
598     _units.insertBefore(
599     Jimple.v().newAssignStmt(
600     resultLocal,
601     Jimple.v().newVirtualInvokeExpr(
602     tempLocal,
603     PtolemyUtilities.booleanMatrixMethod)), _insertPoint);
604     return resultLocal;
605     } else if (tokenType == ptolemy.data.type.BaseType.COMPLEX_MATRIX) {
606     Local tempLocal = Jimple.v().newLocal("arg" ,
607     RefType.v(PtolemyUtilities.complexMatrixTokenClass));
608     _body.getLocals().add(tempLocal);
609     Local resultLocal = Jimple.v().newLocal("arg" ,
610     ArrayType.v(RefType.v("ptolemy.math.Complex"),2));
611     _body.getLocals().add(resultLocal);
612     // Add the new local to the list of arguments
613
614     _units.insertBefore(
615     Jimple.v().newAssignStmt(
616     tempLocal,
617     Jimple.v().newCastExpr(
618     tokenLocal,
619     RefType.v("ptolemy.data.ComplexMatrixToken"))), _insertPoint);
620     _units.insertBefore(
621     Jimple.v().newAssignStmt(
622     resultLocal,
623     Jimple.v().newVirtualInvokeExpr(
624     tempLocal,
625     PtolemyUtilities.complexMatrixMethod)), _insertPoint);
626     return resultLocal;
627     } else if (tokenType == ptolemy.data.type.BaseType.FIX_MATRIX) {
628     Local tempLocal = Jimple.v().newLocal("arg" ,
629     RefType.v(PtolemyUtilities.fixMatrixTokenClass));
630     _body.getLocals().add(tempLocal);
631     Local resultLocal = Jimple.v().newLocal("arg" ,
632     ArrayType.v(RefType.v("ptolemy.math.FixPoint"),2));
633     _body.getLocals().add(resultLocal);
634     // Add the new local to the list of arguments
635
636     _units.insertBefore(
637     Jimple.v().newAssignStmt(
638     tempLocal,
639     Jimple.v().newCastExpr(
640     tokenLocal,
641     RefType.v("ptolemy.data.FixMatrixToken"))), _insertPoint);
642     _units.insertBefore(
643     Jimple.v().newAssignStmt(
644     tempLocal,
645     Jimple.v().newVirtualInvokeExpr(
646     tempLocal,
647     PtolemyUtilities.fixMatrixMethod)), _insertPoint);
648     return resultLocal;
649     } else {// if (argTypes[i] instanceof ArrayType) {
650     throw new IllegalActionException(
651     "CodeGeneration not supported for arrayType");
652     }
653     } else {
654     throw new IllegalActionException(
655     "CodeGeneration not supported for argument " +
656     "conversion " + conversion);
657     }
658
659     }
660     */
661    @Override
662    public void visitFunctionalIfNode(ASTPtFunctionalIfNode node)
663            throws IllegalActionException {
664        throw new IllegalActionException(
665                "Cannot generate code" + " for functional if!");
666
667        // Note that we take care to have short-circuit evaluation here.
668
669        /* _generateChild(node, 0);
670
671         Local conditionTokenLocal =
672         (Local)_nodeToLocal.get(node.jjtGetChild(0));
673
674         Local booleanTokenLocal = Jimple.v().newLocal("result" ,
675         RefType.v(PtolemyUtilities.booleanTokenClass));
676         _body.getLocals().add(booleanTokenLocal);
677         Local flagLocal = Jimple.v().newLocal("result" ,
678         BooleanType.v());
679         _body.getLocals().add(flagLocal);
680
681         Local resultLocal = Jimple.v().newLocal("result" ,
682         PtolemyUtilities.tokenType);
683         _body.getLocals().add(resultLocal);
684
685         Stmt startTrue = Jimple.v().newNopStmt();
686         Stmt endTrue = Jimple.v().newNopStmt();
687
688         // Check the condition
689         _units.insertBefore(
690         Jimple.v().newAssignStmt(
691         booleanTokenLocal,
692         Jimple.v().newCastExpr(
693         conditionTokenLocal,
694         RefType.v(PtolemyUtilities.booleanTokenClass))), _insertPoint);
695         _units.insertBefore(
696         Jimple.v().newAssignStmt(
697         flagLocal,
698         Jimple.v().newVirtualInvokeExpr(
699         booleanTokenLocal,
700         PtolemyUtilities.booleanValueMethod)), _insertPoint);
701         // If condition is true then skip to start of true branch.
702         _units.insertBefore(
703         Jimple.v().newIfStmt(
704         Jimple.v().newEqExpr(
705         flagLocal,
706         IntConstant.v(1)),
707         startTrue),
708         _insertPoint);
709
710         // Otherwise, do the false branch,
711         _generateChild(node, 2);
712         // Assign the false result
713         _units.insertBefore(
714         Jimple.v().newAssignStmt(
715         resultLocal,
716         (Local)_nodeToLocal.get(node.jjtGetChild(2))), _insertPoint);
717         // And continue on.
718         _units.insertBefore(Jimple.v().newGotoStmt(endTrue),
719         _insertPoint);
720
721         _units.insertBefore(startTrue,
722         _insertPoint);
723
724         // Otherwise, do the true branch,
725         _generateChild(node, 1);
726         // Assign the true result
727         _units.insertBefore(
728         Jimple.v().newAssignStmt(
729         resultLocal,
730         (Local)_nodeToLocal.get(node.jjtGetChild(1))), _insertPoint);
731         _units.insertBefore(endTrue, _insertPoint);
732
733         _nodeToLocal.put(node, resultLocal);
734         */
735    }
736
737    @Override
738    public void visitFunctionDefinitionNode(ASTPtFunctionDefinitionNode node)
739            throws IllegalActionException {
740        throw new IllegalActionException(
741                "Cannot generate code" + " for function definitions!");
742    }
743
744    @Override
745    public void visitLeafNode(ASTPtLeafNode node)
746            throws IllegalActionException {
747        String nodeName = "node" + _nodeNumber++;
748        _nodeToLocalName.put(node, nodeName);
749
750        if (node.isConstant() && node.isEvaluated()) {
751            System.out.println(nodeName + " = " + node.getToken());
752            return;
753        }
754
755        System.out.println(
756                nodeName + " = " + _getLocalNameForName(node.getName()));
757    }
758
759    @Override
760    public void visitLogicalNode(ASTPtLogicalNode node)
761            throws IllegalActionException {
762        _generateAllChildren(node);
763
764        int numChildren = node.jjtGetNumChildren();
765
766        String nodeName = "node" + _nodeNumber++;
767        _nodeToLocalName.put(node, nodeName);
768
769        // Note: doesn't ensure short circuit
770        StringBuffer statement = new StringBuffer(
771                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
772
773        for (int i = 1; i < numChildren; i++) {
774            if (node.isLogicalAnd()) {
775                statement.append("&&");
776            } else if (node.isLogicalOr()) {
777                statement.append("||");
778            } else {
779                throw new RuntimeException("Unrecognized node");
780            }
781
782            statement.append(_nodeToLocalName.get(node.jjtGetChild(i)));
783        }
784
785        System.out.println(statement.toString());
786    }
787
788    @Override
789    public void visitMatrixConstructNode(ASTPtMatrixConstructNode node)
790            throws IllegalActionException {
791        _generateAllChildren(node);
792
793        String nodeName = "node" + _nodeNumber++;
794        _nodeToLocalName.put(node, nodeName);
795
796        System.out.println(nodeName + " = FIXME:Matrix");
797    }
798
799    @Override
800    public void visitMethodCallNode(ASTPtMethodCallNode node)
801            throws IllegalActionException {
802        _generateAllChildren(node);
803
804        String nodeName = "node" + _nodeNumber++;
805        _nodeToLocalName.put(node, nodeName);
806
807        System.out.println(nodeName + " = FIXME:MethodCall");
808
809        /*    // Method calls are generally not cached...  They are repeated
810         // every time the tree is evaluated.
811
812         int argCount = node.jjtGetNumChildren();
813         _generateAllChildren(node);
814         // The first child is the token on which to invoke the method.
815
816         // Handle indexing into a record.
817         ptolemy.data.type.Type baseTokenType =
818         ((ASTPtRootNode)node.jjtGetChild(0)).getType();
819         if (argCount == 1 &&
820         baseTokenType instanceof RecordType) {
821         RecordType type = (RecordType)baseTokenType;
822         if (type.labelSet().contains(node.getMethodName())) {
823         Local originalBaseLocal = (Local)
824         _nodeToLocal.get(node.jjtGetChild(0));
825         Local baseLocal = Jimple.v().newLocal("base",
826         RefType.v(PtolemyUtilities.recordTokenClass));
827         _body.getLocals().add(baseLocal);
828         // Cast the record.
829         _units.insertBefore(
830         Jimple.v().newAssignStmt(
831         baseLocal,
832         Jimple.v().newCastExpr(
833         originalBaseLocal,
834         RefType.v(PtolemyUtilities.recordTokenClass))), _insertPoint);
835
836         // invoke get()
837         Local returnLocal = Jimple.v().newLocal("returnValue",
838         RefType.v(PtolemyUtilities.tokenClass));
839         _body.getLocals().add(returnLocal);
840         _units.insertBefore(
841         Jimple.v().newAssignStmt(
842         returnLocal,
843         Jimple.v().newVirtualInvokeExpr(
844         baseLocal,
845         PtolemyUtilities.recordGetMethod,
846         StringConstant.v(node.getMethodName()))), _insertPoint);
847         _nodeToLocal.put(node, returnLocal);
848
849         return;
850         }
851         }
852
853         // The array of token types that the method takes.
854         ptolemy.data.type.Type[] argTypes =
855         new ptolemy.data.type.Type[node.jjtGetNumChildren()];
856         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
857         argTypes[i] = ((ASTPtRootNode)node.jjtGetChild(i)).getType();
858         }
859
860         // Find the method...
861         CachedMethod cachedMethod =
862         CachedMethod.findMethod(node.getMethodName(),
863         argTypes, CachedMethod.METHOD);
864
865         if (!cachedMethod.isValid()) {
866         throw new IllegalActionException("Function " + cachedMethod +
867         " not found.");
868         }
869
870         if (cachedMethod instanceof CachedMethod.ArrayMapCachedMethod ||
871         cachedMethod instanceof CachedMethod.MatrixMapCachedMethod) {
872         throw new IllegalActionException(
873         "CodeGeneration not supported for " +
874         cachedMethod.getClass());
875         }
876
877         Method method = cachedMethod.getMethod();
878
879         // Find the corresponding soot method.
880         SootMethod sootMethod = SootUtilities.getSootMethodForMethod(method);
881
882         Local originalBaseLocal = (Local)_nodeToLocal.get(node.jjtGetChild(0));
883         RefType baseType = RefType.v(sootMethod.getDeclaringClass());
884         Local baseLocal = Jimple.v().newLocal("base",
885         baseType);
886         _body.getLocals().add(baseLocal);
887
888         if (cachedMethod instanceof CachedMethod.BaseConvertCachedMethod) {
889         RefType tempBaseType = PtolemyUtilities.getSootTypeForTokenType(
890         argTypes[0]);
891         Local tempBaseLocal = _convertTokenArgToJavaArg(
892         originalBaseLocal, argTypes[0],
893         ((CachedMethod.BaseConvertCachedMethod)
894         cachedMethod).getBaseConversion());
895         _units.insertBefore(
896         Jimple.v().newAssignStmt(
897         baseLocal,
898         Jimple.v().newCastExpr(
899         tempBaseLocal,
900         baseType)), _insertPoint);
901         } else {
902         _units.insertBefore(
903         Jimple.v().newAssignStmt(
904         baseLocal,
905         Jimple.v().newCastExpr(
906         originalBaseLocal,
907         baseType)), _insertPoint);
908         }
909
910
911         // The list of locals that are arguments to the function.
912         List args = new LinkedList();
913
914         CachedMethod.ArgumentConversion[] conversions =
915         cachedMethod.getConversions();
916         for (int i = 1; i < node.jjtGetNumChildren(); i++) {
917         Local tokenLocal = (Local)_nodeToLocal.get(node.jjtGetChild(i));
918
919         // Insert the appropriate conversion.
920         Local argLocal = _convertTokenArgToJavaArg(
921         tokenLocal, argTypes[i-1], conversions[i-1]);
922         args.add(argLocal);
923         }
924
925         Type returnType = sootMethod.getReturnType();
926         Local returnLocal = Jimple.v().newLocal("returnValue",
927         returnType);
928         _body.getLocals().add(returnLocal);
929
930         // Actually invoke the method.
931         _units.insertBefore(
932         Jimple.v().newAssignStmt(
933         returnLocal,
934         Jimple.v().newVirtualInvokeExpr(
935         baseLocal, sootMethod, args)), _insertPoint);
936
937         // Convert the result back to a token.
938         Local tokenLocal = _convertJavaResultToToken(returnLocal, returnType);
939
940
941         //      RefType objectType = RefType.v(PtolemyUtilities.objectClass);
942         //         Local argValuesLocal = Jimple.v().newLocal("tokenArray",
943         //                 ArrayType.v(objectType, 1));
944         //         _body.getLocals().add(argValuesLocal);
945         //         _units.insertBefore(
946         //                 Jimple.v().newAssignStmt(
947         //                         argValuesLocal,
948         //                         Jimple.v().newNewArrayExpr(
949         //                                 objectType,
950         //                                 IntConstant.v(node.jjtGetNumChildren()))));
951
952         //         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
953         //             _units.insertBefore(
954         //                     Jimple.v().newAssignStmt(
955         //                             Jimple.v().newArrayRef(
956         //                                     argValuesLocal,
957         //                                     IntConstant.v(i)),
958         //                             (Local)_nodeToLocal.get(node.jjtGetChild(i))));
959         //         }
960
961         //         RefType typeType = RefType.v("ptolemy.data.type.Type");
962         //         Local argTypesLocal = Jimple.v().newLocal("tokenTypes",
963         //                 ArrayType.v(typeType, 1));
964         //         _body.getLocals().add(argTypesLocal);
965         //         Local typeLocal = Jimple.v().newLocal("classType",
966         //                 typeType);
967         //         _body.getLocals().add(typeLocal);
968         //         Local tokenLocal = Jimple.v().newLocal("token",
969         //                 PtolemyUtilities.tokenType);
970         //         _body.getLocals().add(tokenLocal);
971
972         //         _units.insertBefore(
973         //                 Jimple.v().newAssignStmt(
974         //                         argTypesLocal,
975         //                         Jimple.v().newNewArrayExpr(
976         //                                 typeType,
977         //                                 IntConstant.v(argCount))));
978
979         //         Local indexLocal = Jimple.v().newLocal("index", IntType.v());
980         //         _body.getLocals().add(indexLocal);
981
982         //         // The list of initializer instructions.
983         //         List initializerList = new LinkedList();
984         //         initializerList.add(
985         //                 Jimple.v().newAssignStmt(
986         //                         indexLocal,
987         //                         IntConstant.v(0)));
988
989         //         // The list of body instructions.
990         //         List bodyList = new LinkedList();
991         //         bodyList.add(
992         //                 Jimple.v().newAssignStmt(
993         //                         tokenLocal,
994         //                         Jimple.v().newArrayRef(
995         //                                 argValuesLocal,
996         //                                 indexLocal)));
997         //         bodyList.add(
998         //                 Jimple.v().newAssignStmt(
999         //                         typeLocal,
1000         //                         Jimple.v().newVirtualInvokeExpr(
1001         //                                 tokenLocal,
1002         //                                 PtolemyUtilities.tokenGetTypeMethod)));
1003         //         bodyList.add(
1004         //                 Jimple.v().newAssignStmt(
1005         //                         Jimple.v().newArrayRef(
1006         //                                 argTypesLocal,
1007         //                                 indexLocal),
1008         //                         typeLocal));
1009
1010
1011         //         // Increment the index.
1012         //         bodyList.add(
1013         //                 Jimple.v().newAssignStmt(
1014         //                         indexLocal,
1015         //                         Jimple.v().newAddExpr(
1016         //                                 indexLocal,
1017         //                                 IntConstant.v(1))));
1018
1019         //         Expr conditionalExpr =
1020         //             Jimple.v().newLtExpr(
1021         //                     indexLocal,
1022         //                     IntConstant.v(argCount));
1023
1024         //         Stmt stmt = Jimple.v().newNopStmt();
1025         //         _units.insertBefore(stmt);
1026
1027         //         SootUtilities.createForLoopBefore(_body,
1028         //                 stmt,
1029         //                 initializerList,
1030         //                 bodyList,
1031         //                 conditionalExpr);
1032
1033         //         SootMethod methodCallEvaluationMethod =
1034         //             Scene.v().getMethod("<ptolemy.data.expr.ParseTreeEvaluator: ptolemy.data.Token methodCall(java.lang.String,int,ptolemy.data.type.Type[],java.lang.Object[])>");
1035         //         List argList = new ArrayList();
1036         //         argList.add(StringConstant.v(node.getMethodName()));
1037         //         argList.add(IntConstant.v(argCount));
1038         //         argList.add(argTypesLocal);
1039         //         argList.add(argValuesLocal);
1040
1041         //         _units.insertBefore(
1042         //                 Jimple.v().newAssignStmt(
1043         //                         tokenLocal,
1044         //                         Jimple.v().newStaticInvokeExpr(
1045         //                                 methodCallEvaluationMethod,
1046         //                                 argList)));
1047
1048         _nodeToLocal.put(node, tokenLocal);
1049         */
1050    }
1051
1052    @Override
1053    public void visitPowerNode(ASTPtPowerNode node)
1054            throws IllegalActionException {
1055        _generateAllChildren(node);
1056
1057        int numChildren = node.jjtGetNumChildren();
1058        _assert(numChildren > 0, node,
1059                "The number of child nodes must be greater than zero");
1060
1061        String nodeName = "node" + _nodeNumber++;
1062        _nodeToLocalName.put(node, nodeName);
1063
1064        StringBuffer statement = new StringBuffer(
1065                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
1066
1067        for (int i = 1; i < numChildren; i++) {
1068            statement.append("^" + _nodeToLocalName.get(node.jjtGetChild(i)));
1069        }
1070
1071        System.out.println(statement.toString());
1072    }
1073
1074    @Override
1075    public void visitProductNode(ASTPtProductNode node)
1076            throws IllegalActionException {
1077        _generateAllChildren(node);
1078
1079        List lexicalTokenList = node.getLexicalTokenList();
1080        int numChildren = node.jjtGetNumChildren();
1081
1082        _assert(numChildren > 0, node,
1083                "The number of child nodes must be greater than zero");
1084        _assert(numChildren == lexicalTokenList.size() + 1, node,
1085                "The number of child nodes is "
1086                        + "not equal to number of operators plus one");
1087
1088        String nodeName = "node" + _nodeNumber++;
1089        _nodeToLocalName.put(node, nodeName);
1090
1091        StringBuffer statement = new StringBuffer(
1092                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
1093
1094        for (int i = 1; i < numChildren; i++) {
1095            Token operator = (Token) lexicalTokenList.get(i - 1);
1096
1097            if (operator.kind == PtParserConstants.MULTIPLY) {
1098                statement.append("*");
1099            } else if (operator.kind == PtParserConstants.DIVIDE) {
1100                statement.append("/");
1101            } else if (operator.kind == PtParserConstants.MODULO) {
1102                statement.append("%");
1103            } else {
1104                _assert(false, node, "Invalid operation");
1105            }
1106
1107            statement.append(_nodeToLocalName.get(node.jjtGetChild(i)));
1108        }
1109
1110        System.out.println(statement.toString());
1111    }
1112
1113    @Override
1114    public void visitRecordConstructNode(ASTPtRecordConstructNode node)
1115            throws IllegalActionException {
1116        throw new IllegalActionException(
1117                "Cannot generate code" + " for records!");
1118    }
1119
1120    @Override
1121    public void visitRelationalNode(ASTPtRelationalNode node)
1122            throws IllegalActionException {
1123        _generateAllChildren(node);
1124
1125        int numChildren = node.jjtGetNumChildren();
1126        _assert(numChildren == 2, node,
1127                "The number of child nodes must be two");
1128
1129        String nodeName = "node" + _nodeNumber++;
1130        _nodeToLocalName.put(node, nodeName);
1131
1132        Token operator = node.getOperator();
1133
1134        StringBuffer statement = new StringBuffer(
1135                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
1136
1137        if (operator.kind == PtParserConstants.EQUALS) {
1138            statement.append("==");
1139        } else if (operator.kind == PtParserConstants.NOTEQUALS) {
1140            statement.append("!=");
1141        } else if (operator.kind == PtParserConstants.GTE) {
1142            statement.append(">=");
1143        } else if (operator.kind == PtParserConstants.GT) {
1144            statement.append(">");
1145        } else if (operator.kind == PtParserConstants.LTE) {
1146            statement.append("<=");
1147        } else if (operator.kind == PtParserConstants.LT) {
1148            statement.append("<");
1149        } else {
1150            throw new IllegalActionException(
1151                    "Invalid operation " + operator.image);
1152        }
1153
1154        statement.append(_nodeToLocalName.get(node.jjtGetChild(1)));
1155        System.out.println(statement.toString());
1156    }
1157
1158    @Override
1159    public void visitShiftNode(ASTPtShiftNode node)
1160            throws IllegalActionException {
1161        _generateAllChildren(node);
1162
1163        int numChildren = node.jjtGetNumChildren();
1164        _assert(numChildren == 2, node,
1165                "The number of child nodes must be two");
1166
1167        Token operator = node.getOperator();
1168
1169        String nodeName = "node" + _nodeNumber++;
1170        _nodeToLocalName.put(node, nodeName);
1171
1172        StringBuffer statement = new StringBuffer(
1173                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
1174
1175        if (operator.kind == PtParserConstants.SHL) {
1176            statement.append("<<");
1177        } else if (operator.kind == PtParserConstants.SHR) {
1178            statement.append(">>");
1179        } else if (operator.kind == PtParserConstants.LSHR) {
1180            statement.append("<");
1181        } else {
1182            _assert(false, node, "Invalid operation");
1183        }
1184
1185        statement.append(_nodeToLocalName.get(node.jjtGetChild(1)));
1186        System.out.println(statement.toString());
1187    }
1188
1189    @Override
1190    public void visitSumNode(ASTPtSumNode node) throws IllegalActionException {
1191        _generateAllChildren(node);
1192
1193        List lexicalTokenList = node.getLexicalTokenList();
1194        int numChildren = node.jjtGetNumChildren();
1195
1196        _assert(numChildren > 0, node,
1197                "The number of child nodes must be greater than zero");
1198        _assert(numChildren == lexicalTokenList.size() + 1, node,
1199                "The number of child nodes is "
1200                        + "not equal to number of operators plus one");
1201
1202        String nodeName = "node" + _nodeNumber++;
1203        _nodeToLocalName.put(node, nodeName);
1204
1205        StringBuffer statement = new StringBuffer(
1206                nodeName + " = " + _nodeToLocalName.get(node.jjtGetChild(0)));
1207
1208        for (int i = 1; i < numChildren; i++) {
1209            Token operator = (Token) lexicalTokenList.get(i - 1);
1210
1211            if (operator.kind == PtParserConstants.PLUS) {
1212                statement.append("+");
1213            } else if (operator.kind == PtParserConstants.MINUS) {
1214                statement.append("-");
1215            } else {
1216                _assert(false, node, "Invalid operation");
1217            }
1218
1219            statement.append(_nodeToLocalName.get(node.jjtGetChild(i)));
1220        }
1221
1222        System.out.println(statement.toString());
1223    }
1224
1225    @Override
1226    public void visitUnaryNode(ASTPtUnaryNode node)
1227            throws IllegalActionException {
1228        _generateAllChildren(node);
1229        _assert(node.jjtGetNumChildren() == 1, node,
1230                "Unary node must have exactly one child!");
1231
1232        String nodeName = "node" + _nodeNumber++;
1233        _nodeToLocalName.put(node, nodeName);
1234
1235        StringBuffer statement = new StringBuffer(nodeName + " = ");
1236
1237        if (node.isMinus()) {
1238            // Note: not quite ptolemy semantics.
1239            statement.append("-" + _nodeToLocalName.get(node.jjtGetChild(0)));
1240        } else if (node.isNot()) {
1241            statement.append("!" + _nodeToLocalName.get(node.jjtGetChild(0)));
1242        } else if (node.isBitwiseNot()) {
1243            statement.append("~" + _nodeToLocalName.get(node.jjtGetChild(0)));
1244        } else {
1245            _assert(false, node, "Unrecognized unary node");
1246        }
1247
1248        System.out.println(statement.toString());
1249    }
1250
1251    ///////////////////////////////////////////////////////////////////
1252    ////                         protected methods                 ////
1253
1254    /**
1255     * Assert that the given boolean value, which describes the given
1256     * parse tree node is true.  If it is false, then throw a new
1257     * InternalErrorException that describes the node that includes
1258     * the given message.
1259     * @param flag The value to be checked.  If false, then an
1260     * InternalErrorException is thrown.
1261     * @param node The node.
1262     * @param message The error message to be included in the exception
1263     * if the flag parameter is false.
1264     */
1265    protected void _assert(boolean flag, ASTPtRootNode node, String message) {
1266        if (!flag) {
1267            throw new InternalErrorException(message + ": " + node.toString());
1268        }
1269    }
1270
1271    /** Loop through all of the children of this node,
1272     *  visiting each one of them, which will cause their token
1273     *  value to be determined.
1274     *  @param node The node.
1275     *  @exception IllegalActionException If thrown while
1276     *  generating a child.
1277     */
1278    protected void _generateAllChildren(ASTPtRootNode node)
1279            throws IllegalActionException {
1280        int numChildren = node.jjtGetNumChildren();
1281
1282        for (int i = 0; i < numChildren; i++) {
1283            _generateChild(node, i);
1284        }
1285    }
1286
1287    /** Visit the child with the given index of the given node.
1288     *  This is usually called while visiting the given node.
1289     *  @param node The node.
1290     *  @param i The index of the child to be visited.
1291     *  @exception IllegalActionException If thrown while visiting a child
1292     *  node.
1293     */
1294    protected void _generateChild(ASTPtRootNode node, int i)
1295            throws IllegalActionException {
1296        ASTPtRootNode child = (ASTPtRootNode) node.jjtGetChild(i);
1297        child.visit(this);
1298    }
1299
1300    /** Get the local name for this this name.
1301     *  @param name The name to be looked up.
1302     *  @return The local name.
1303     *  @exception IllegalActionException  Always thrown in this base class.
1304     */
1305    protected String _getLocalNameForName(String name)
1306            throws IllegalActionException {
1307        //   if (_scope != null) {
1308        //             return "FIXME";
1309        //         }
1310        throw new IllegalActionException("The ID " + name + " is undefined.");
1311    }
1312
1313    /** Return true if the name is a valid name.  This base class
1314     *  always returns false.
1315     *  @param name The name to be looked up.
1316     *  @return True if the name is valid.  This base class always returns
1317     *  false.
1318     *  @exception IllegalActionException Not thrown in this base class.
1319     */
1320    protected boolean _isValidName(String name) throws IllegalActionException {
1321        //    if (_scope != null) {
1322        //             try {
1323        //                 return (_scope.getType(name) != null);
1324        //             } catch (Exception ex) {
1325        //                 return false;
1326        //             }
1327        //         } else {
1328        return false;
1329
1330        //        }
1331    }
1332
1333    /** A map from node to local node name. */
1334    protected HashMap _nodeToLocalName;
1335
1336    /** The node number, used to create unique node names. */
1337    protected int _nodeNumber;
1338}