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}