Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1130 lines
23 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. exprpr.cxx
  5. Abstract:
  6. expression evaluator print routines implementation.
  7. Notes:
  8. History:
  9. VibhasC Aug-05-1993 Created
  10. ----------------------------------------------------------------------------*/
  11. #pragma warning ( disable : 4514 )
  12. /****************************************************************************
  13. * include files
  14. ***************************************************************************/
  15. #include "nulldefs.h"
  16. extern "C"
  17. {
  18. #include <stdio.h>
  19. #include <string.h>
  20. }
  21. #include "expr.hxx"
  22. #include "nodeskl.hxx"
  23. /****************************************************************************
  24. * extern definitions
  25. ***************************************************************************/
  26. extern char * OperatorToString( OPERATOR Op );
  27. /***************************************************************************/
  28. void
  29. expr_node::PrintWithPrefix(
  30. ISTREAM * pStream,
  31. char * pPrefix )
  32. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  33. Routine Description:
  34. This routine prints an expression adding a prefix to each of the varaibles
  35. within the expression.
  36. Arguments:
  37. pStream - A pointer to the stream to output to.
  38. pPrefix - the prefix to be prepended to each variable
  39. Return Value:
  40. Notes:
  41. ----------------------------------------------------------------------------*/
  42. {
  43. ITERATOR VarList;
  44. expr_variable * pVarNode = 0;
  45. short VarCount = MakeListOfVars( VarList );
  46. if ( VarCount )
  47. {
  48. VarList.Init();
  49. while ( ITERATOR_GETNEXT( VarList, pVarNode ) )
  50. pVarNode->SetPrefix( pPrefix );
  51. }
  52. Print( pStream );
  53. if ( VarCount )
  54. {
  55. VarList.Init();
  56. while ( ITERATOR_GETNEXT( VarList, pVarNode ) )
  57. pVarNode->SetPrefix( NULL );
  58. }
  59. }
  60. /*
  61. // table of precedences ( lower number => lower precedence )
  62. 200 [] () . -> ()++ ()--
  63. 190 ++() --() sizeof() & *(deref) +() -() ~() !()
  64. 180 (cast)
  65. 170 * / %
  66. 160 + -
  67. 150 << >>
  68. 140 < > <= >=
  69. 130 == !=
  70. 120 & (bitwise)
  71. 110 ^
  72. 100 |
  73. 90 &&
  74. 80 ||
  75. 70 ?:
  76. 60 = *= /= %= += -= <<= >>= &= |= ^=
  77. 50 , (seqential eval)
  78. 0 all other operators (should be none)
  79. */
  80. const short Prec[] =
  81. {
  82. 0 // OP_ILLEGAL = OP_START
  83. // OP_UNARY_START
  84. // OP_UNARY_ARITHMETIC_START = OP_UNARY_START
  85. ,190 // OP_UNARY_PLUS = OP_UNARY_ARITHMETIC_START
  86. ,190 // OP_UNARY_MINUS
  87. // OP_UNARY_ARITHMETIC_END
  88. // OP_UNARY_LOGICAL_START = OP_UNARY_ARITHMETIC_END
  89. ,190 // OP_UNARY_NOT = OP_UNARY_LOGICAL_START
  90. ,190 // OP_UNARY_COMPLEMENT
  91. // OP_UNARY_LOGICAL_END
  92. ,190 // OP_UNARY_INDIRECTION = OP_UNARY_LOGICAL_END
  93. ,180 // OP_UNARY_CAST
  94. ,190 // OP_UNARY_AND
  95. ,190 // OP_UNARY_SIZEOF
  96. ,190 // OP_UNARY_ALIGNOF
  97. ,190 // OP_PRE_INCR
  98. ,190 // OP_PRE_DECR
  99. ,200 // OP_POST_INCR
  100. ,200 // OP_POST_DECR
  101. // OP_UNARY_END
  102. // OP_BINARY_START = OP_UNARY_END
  103. // OP_BINARY_ARITHMETIC_START = OP_BINARY_START
  104. ,160 // OP_PLUS = OP_BINARY_ARITHMETIC_START
  105. ,160 // OP_MINUS
  106. ,170 // OP_STAR
  107. ,170 // OP_SLASH
  108. ,170 // OP_MOD
  109. // OP_BINARY_ARITHMETIC_END
  110. // OP_BINARY_SHIFT_START = OP_BINARY_ARITHMETIC_END
  111. ,150 // OP_LEFT_SHIFT = OP_BINARY_SHIFT_START
  112. ,150 // OP_RIGHT_SHIFT
  113. // OP_BINARY_SHIFT_END
  114. // OP_BINARY_RELATIONAL_START = OP_BINARY_SHIFT_END
  115. ,140 // OP_LESS = OP_BINARY_RELATIONAL_START
  116. ,140 // OP_LESS_EQUAL
  117. ,140 // OP_GREATER_EQUAL
  118. ,140 // OP_GREATER
  119. ,130 // OP_EQUAL
  120. ,130 // OP_NOT_EQUAL
  121. // OP_BINARY_RELATIONAL_END
  122. // OP_BINARY_BITWISE_START = OP_BINARY_RELATIONAL_END
  123. ,120 // OP_AND = OP_BINARY_BITWISE_START
  124. ,100 // OP_OR
  125. ,110 // OP_XOR
  126. // OP_BINARY_BITWISE_END
  127. // OP_BINARY_LOGICAL_START = OP_BINARY_BITWISE_END
  128. ,90 // OP_LOGICAL_AND = OP_BINARY_LOGICAL_START
  129. ,80 // OP_LOGICAL_OR
  130. // OP_BINARY_LOGICAL_END
  131. // OP_BINARY_TERNARY_START = OP_BINARY_LOGICAL_END
  132. ,70 // OP_QM = OP_BINARY_TERNARY_START
  133. ,70 // OP_COLON
  134. // OP_BINARY_TERNARY_END
  135. // OP_BINARY_END = OP_BINARY_TERNARY_END
  136. ,0 // OP_INTERNAL_START = OP_BINARY_END
  137. ,200 // OP_FUNCTION
  138. ,0 // OP_PARAM
  139. ,200 // OP_POINTSTO
  140. ,200 // OP_DOT
  141. ,200 // OP_INDEX
  142. ,50 // OP_COMMA
  143. ,0 // OP_STMT
  144. ,60 // OP_ASSIGN
  145. ,0 // OP_END
  146. };
  147. /*
  148. // table of associativity ( -1 => L to R, 1 => R to L )
  149. -1 [] () . -> ()++ ()--
  150. 1 ++() --() sizeof() & *(deref) +() -() ~() !()
  151. 1 (cast)
  152. -1 * / %
  153. -1 + -
  154. -1 << >>
  155. -1 < > <= >=
  156. -1 == !=
  157. -1 & (bitwise)
  158. -1 ^
  159. -1 |
  160. -1 &&
  161. -1 ||
  162. 1 ?:
  163. 1 = *= /= %= += -= <<= >>= &= |= ^=
  164. -1 , (seqential eval)
  165. 0 all other operators (should be none)
  166. */
  167. const short AssocTbl[] =
  168. {
  169. 0 // OP_ILLEGAL = OP_START
  170. // OP_UNARY_START
  171. // OP_UNARY_ARITHMETIC_START = OP_UNARY_START
  172. ,-1 // OP_UNARY_PLUS = OP_UNARY_ARITHMETIC_START
  173. ,-1 // OP_UNARY_MINUS
  174. // OP_UNARY_ARITHMETIC_END
  175. // OP_UNARY_LOGICAL_START = OP_UNARY_ARITHMETIC_END
  176. ,1 // OP_UNARY_NOT = OP_UNARY_LOGICAL_START
  177. ,1 // OP_UNARY_COMPLEMENT
  178. // OP_UNARY_LOGICAL_END
  179. ,1 // OP_UNARY_INDIRECTION = OP_UNARY_LOGICAL_END
  180. ,1 // OP_UNARY_CAST
  181. ,1 // OP_UNARY_AND
  182. ,1 // OP_UNARY_SIZEOF
  183. ,1 // OP_UNARY_ALIGNOF
  184. ,1 // OP_PRE_INCR
  185. ,1 // OP_PRE_DECR
  186. ,-1 // OP_POST_INCR
  187. ,-1 // OP_POST_DECR
  188. // OP_UNARY_END
  189. // OP_BINARY_START = OP_UNARY_END
  190. // OP_BINARY_ARITHMETIC_START = OP_BINARY_START
  191. ,-1 // OP_PLUS = OP_BINARY_ARITHMETIC_START
  192. ,-1 // OP_MINUS
  193. ,-1 // OP_STAR
  194. ,-1 // OP_SLASH
  195. ,-1 // OP_MOD
  196. // OP_BINARY_ARITHMETIC_END
  197. // OP_BINARY_SHIFT_START = OP_BINARY_ARITHMETIC_END
  198. ,-1 // OP_LEFT_SHIFT = OP_BINARY_SHIFT_START
  199. ,-1 // OP_RIGHT_SHIFT
  200. // OP_BINARY_SHIFT_END
  201. // OP_BINARY_RELATIONAL_START = OP_BINARY_SHIFT_END
  202. ,-1 // OP_LESS = OP_BINARY_RELATIONAL_START
  203. ,-1 // OP_LESS_EQUAL
  204. ,-1 // OP_GREATER_EQUAL
  205. ,-1 // OP_GREATER
  206. ,-1 // OP_EQUAL
  207. ,-1 // OP_NOT_EQUAL
  208. // OP_BINARY_RELATIONAL_END
  209. // OP_BINARY_BITWISE_START = OP_BINARY_RELATIONAL_END
  210. ,-1 // OP_AND = OP_BINARY_BITWISE_START
  211. ,-1 // OP_OR
  212. ,-1 // OP_XOR
  213. // OP_BINARY_BITWISE_END
  214. // OP_BINARY_LOGICAL_START = OP_BINARY_BITWISE_END
  215. ,-1 // OP_LOGICAL_AND = OP_BINARY_LOGICAL_START
  216. ,-1 // OP_LOGICAL_OR
  217. // OP_BINARY_LOGICAL_END
  218. // OP_BINARY_TERNARY_START = OP_BINARY_LOGICAL_END
  219. ,1 // OP_QM = OP_BINARY_TERNARY_START
  220. ,1 // OP_COLON
  221. // OP_BINARY_TERNARY_END
  222. // OP_BINARY_END = OP_BINARY_TERNARY_END
  223. ,0 // OP_INTERNAL_START = OP_BINARY_END
  224. ,0 // OP_FUNCTION
  225. ,0 // OP_PARAM
  226. ,-1 // OP_POINTSTO
  227. ,-1 // OP_DOT
  228. ,-1 // OP_INDEX
  229. ,-1 // OP_COMMA
  230. ,0 // OP_STMT
  231. ,1 // OP_ASSIGN
  232. ,0 // OP_END
  233. };
  234. void
  235. expr_operator::PrintSubExpr(
  236. expr_node * pExpr,
  237. ISTREAM * pStream )
  238. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  239. Routine Description:
  240. Print a subexpression, optionally adding parens.
  241. Arguments:
  242. pExpr - the expression to print
  243. pStream - A pointer to the stream to output to.
  244. Return Value:
  245. Notes:
  246. ----------------------------------------------------------------------------*/
  247. {
  248. short PrecMe = Prec[ GetOperator() ];
  249. short PrecChild;
  250. BOOL fAddParens = FALSE;
  251. if ( pExpr->IsOperator() )
  252. {
  253. PrecChild = Prec[ pExpr->GetOperator() ];
  254. // account for associativity
  255. if ( pExpr != GetLeft() )
  256. PrecChild = short( PrecChild + AssocTbl[ pExpr->GetOperator() ] );
  257. fAddParens = PrecChild < PrecMe;
  258. }
  259. if ( fAddParens )
  260. pStream->Write('(');
  261. pExpr->Print( pStream );
  262. if ( fAddParens )
  263. pStream->Write(')');
  264. }
  265. void
  266. expr_variable::Print(
  267. ISTREAM * pStream )
  268. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  269. Routine Description:
  270. Print a variable name expression.
  271. Arguments:
  272. pStream - A pointer to the stream to output to.
  273. Return Value:
  274. Notes:
  275. ----------------------------------------------------------------------------*/
  276. {
  277. if ( GetPrefix() )
  278. pStream->Write( GetPrefix() );
  279. pStream->Write( GetName() );
  280. }
  281. char * ConstFormats[] =
  282. {
  283. "\"%s\"", // string
  284. "L\"%Ls\"", // wstring
  285. "0x%x", // char
  286. "L'%Lc'", // wchar
  287. "%d", // numeric
  288. "%uU", // numeric unsigned
  289. "%ldL", // numeric long
  290. "%luUL", // numeric unsigned long
  291. "%#x", // hex
  292. "%#xU", // hex unsigned
  293. "%#lxL", // hex long
  294. "%#lxUL", // hex unsigned long
  295. "%#o", // octal
  296. "%#oU", // octal unsigned
  297. "%#loL", // octal long
  298. "%#loUL", // octal unsigned long
  299. "%s", // BOOL ( not used )
  300. "%g", // float
  301. "%lg", // double
  302. // RKK64
  303. // value types for int64
  304. };
  305. void
  306. expr_constant::Print(
  307. ISTREAM * pStream )
  308. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  309. Routine Description:
  310. Emit a constant expression to the stream.
  311. Arguments:
  312. pStream - A pointer to the stream.
  313. Return Value:
  314. Notes:
  315. ----------------------------------------------------------------------------*/
  316. {
  317. char Array[ 256 ];
  318. Array[0] = 0;
  319. if (Format == VALUE_TYPE_BOOL)
  320. {
  321. sprintf( Array, "%s", (Value.L) ? "TRUE" : "FALSE" );
  322. }
  323. else if ( Format == VALUE_TYPE_FLOAT )
  324. {
  325. sprintf( Array, ConstFormats[ Format] , Value.F );
  326. }
  327. else if ( Format == VALUE_TYPE_DOUBLE )
  328. {
  329. sprintf( Array, ConstFormats[ Format] , Value.D );
  330. }
  331. else if ( Format == VALUE_TYPE_CHAR )
  332. {
  333. if ( Value.C )
  334. {
  335. Array[0] = '0';
  336. Array[1] = 'x';
  337. char ch = ( char ) ( ( Value.C >> 4 ) & 0xF );
  338. Array[2] = ( char ) ( ( ch >= 0 && ch <= 9 ) ? ch + '0' : ch + 'A' - 0xA );
  339. ch = ( char ) ( Value.C & 0xF );
  340. Array[3] = ( char ) ( ( ch >= 0 && ch <= 9 ) ? ch + '0' : ch + 'A' - 0xA );
  341. Array[4] = 0;
  342. }
  343. else
  344. {
  345. Array[0] = '0';
  346. Array[1] = 0;
  347. }
  348. }
  349. else if ( Format == VALUE_TYPE_STRING )
  350. {
  351. if (Value.pC)
  352. {
  353. pStream->Write( "\"" );
  354. pStream->Write( ( char* ) Value.pC );
  355. pStream->Write( "\"" );
  356. }
  357. else
  358. {
  359. pStream->Write( "0" );
  360. }
  361. }
  362. else if ( Format == VALUE_TYPE_WSTRING )
  363. {
  364. if (Value.pWC)
  365. {
  366. pStream->Write( "L\"" );
  367. pStream->Write( ( char* ) Value.pWC );
  368. pStream->Write( "\"" );
  369. }
  370. else
  371. {
  372. pStream->Write( "0" );
  373. }
  374. }
  375. else
  376. {
  377. sprintf( Array, ConstFormats[ Format] , Value.I64 );
  378. }
  379. pStream->Write( (char *)Array );
  380. }
  381. void
  382. expr_op_unary::Print(
  383. ISTREAM * pStream )
  384. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  385. Routine Description:
  386. Emit a unary expression to the stream.
  387. Arguments:
  388. pStream - A pointer to the stream.
  389. Return Value:
  390. Notes:
  391. ----------------------------------------------------------------------------*/
  392. {
  393. OPERATOR Op = GetOperator();
  394. char ch;
  395. switch( Op )
  396. {
  397. case OP_UNARY_PLUS: ch = '+'; break;
  398. case OP_UNARY_MINUS: ch = '-'; break;
  399. case OP_UNARY_NOT: ch = '!'; break;
  400. case OP_UNARY_COMPLEMENT: ch = '~'; break;
  401. case OP_UNARY_INDIRECTION: ch = '*'; break;
  402. case OP_UNARY_AND: ch = '&'; break;
  403. default: ch = 'X'; break;
  404. }
  405. pStream->Write( ch );
  406. PrintSubExpr( GetLeft(), pStream );
  407. }
  408. void
  409. expr_cast::Print(
  410. ISTREAM * pStream )
  411. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  412. Routine Description:
  413. Emit a cast expression.
  414. Arguments:
  415. pStream - A pointer to the stream.
  416. Return Value:
  417. None.
  418. Notes:
  419. Not implemented for now.
  420. ----------------------------------------------------------------------------*/
  421. {
  422. if ( GetEmitModifiers() == true )
  423. {
  424. GetType()->PrintType( (PRT_CAST),
  425. pStream,
  426. (node_skl *)0
  427. );
  428. }
  429. else
  430. {
  431. GetType()->PrintType( (PRT_CAST) | PRT_SUPPRESS_MODIFIERS,
  432. pStream,
  433. (node_skl *)0
  434. );
  435. }
  436. PrintSubExpr( GetLeft(), pStream );
  437. }
  438. void
  439. expr_sizeof::Print(
  440. ISTREAM * pStream )
  441. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  442. Routine Description:
  443. Emit a sizeof expression.
  444. Arguments:
  445. pStream - A pointer to the stream.
  446. Return Value:
  447. None.
  448. Notes:
  449. Not implemented for now.
  450. ----------------------------------------------------------------------------*/
  451. {
  452. pStream->Write( "sizeof" );
  453. pType->PrintType( (PRT_CAST | PRT_ARRAY_SIZE_ONE),
  454. pStream,
  455. (node_skl *)0
  456. );
  457. }
  458. void
  459. expr_alignof::Print(
  460. ISTREAM * pStream )
  461. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  462. Routine Description:
  463. Emit a sizeof expression.
  464. Arguments:
  465. pStream - A pointer to the stream.
  466. Return Value:
  467. None.
  468. Notes:
  469. Not implemented for now.
  470. ----------------------------------------------------------------------------*/
  471. {
  472. pStream->Write( "__alignof" );
  473. pType->PrintType( (PRT_CAST | PRT_ARRAY_SIZE_ONE),
  474. pStream,
  475. (node_skl *)0
  476. );
  477. }
  478. void
  479. expr_pre_incr::Print(
  480. ISTREAM * pStream )
  481. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  482. Routine Description:
  483. Emit a pre-incr expression.
  484. Arguments:
  485. pStream - A pointer to the stream.
  486. Return Value:
  487. None.
  488. Notes:
  489. Not implemented for now.
  490. ----------------------------------------------------------------------------*/
  491. {
  492. pStream->Write("++");
  493. PrintSubExpr( GetLeft(), pStream );
  494. }
  495. void
  496. expr_pre_decr::Print(
  497. ISTREAM * pStream )
  498. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  499. Routine Description:
  500. Emit a pre-decrement expression.
  501. Arguments:
  502. pStream - A pointer to the stream.
  503. Return Value:
  504. None.
  505. Notes:
  506. Not implemented for now.
  507. ----------------------------------------------------------------------------*/
  508. {
  509. pStream->Write("--");
  510. PrintSubExpr( GetLeft(), pStream );
  511. }
  512. void
  513. expr_post_incr::Print(
  514. ISTREAM * pStream )
  515. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  516. Routine Description:
  517. Emit a post-increment expression.
  518. Arguments:
  519. pStream - A pointer to the stream.
  520. Return Value:
  521. None.
  522. Notes:
  523. Not implemented for now.
  524. ----------------------------------------------------------------------------*/
  525. {
  526. PrintSubExpr( GetLeft(), pStream );
  527. pStream->Write("++");
  528. }
  529. void
  530. expr_post_decr::Print(
  531. ISTREAM * pStream )
  532. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  533. Routine Description:
  534. Emit a post-decrement expression.
  535. Arguments:
  536. pStream - A pointer to the stream.
  537. Return Value:
  538. None.
  539. Notes:
  540. Not implemented for now.
  541. ----------------------------------------------------------------------------*/
  542. {
  543. PrintSubExpr( GetLeft(), pStream );
  544. pStream->Write("--");
  545. }
  546. void
  547. expr_op_binary::Print(
  548. ISTREAM * pStream )
  549. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  550. Routine Description:
  551. Emit a binary arithmetic expression.
  552. Arguments:
  553. pStream - A pointer to the stream.
  554. Return Value:
  555. None.
  556. Notes:
  557. Not implemented for now.
  558. ----------------------------------------------------------------------------*/
  559. {
  560. PrintSubExpr( GetLeft(), pStream );
  561. pStream->Write( OperatorToString( GetOperator() ) );
  562. PrintSubExpr( GetRight(), pStream );
  563. }
  564. void
  565. expr_op_binary::PrintCall(
  566. ISTREAM * pStream,
  567. short LeftMargin,
  568. BOOL fInProc )
  569. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  570. Routine Description:
  571. Emit expression as part of a procedure call.
  572. Arguments:
  573. pStream - A pointer to the stream.
  574. LeftMargin - The start margin for the procedure call.
  575. fInProc - Is it in a proc context already ?
  576. Return Value:
  577. None.
  578. Notes:
  579. The left margin is 0 if the call is the only thing on the line. If the
  580. call is in an assignment, the start of param indent must take that into
  581. account.
  582. ----------------------------------------------------------------------------*/
  583. {
  584. expr_node * pN;
  585. if ( ( pN = GetLeft() ) != 0 )
  586. pN->PrintCall( pStream, LeftMargin, fInProc );
  587. pStream->Write( OperatorToString( GetOperator() ) );
  588. if ( ( pN = GetRight() ) != 0 )
  589. pN->PrintCall( pStream, LeftMargin, fInProc );
  590. }
  591. void
  592. expr_assign::PrintCall(
  593. ISTREAM * pStream,
  594. short LeftMargin,
  595. BOOL fInProc )
  596. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  597. Routine Description:
  598. Emit expression as part of a procedure call.
  599. Arguments:
  600. pStream - A pointer to the stream.
  601. LeftMargin - The start margin for the procedure call.
  602. fInProc - Is it in a proc context already ?
  603. Return Value:
  604. None.
  605. Notes:
  606. The left margin is 0 if the call is the only thing on the line. If the
  607. call is in an assignment, the start of param indent must take that into
  608. account.
  609. ----------------------------------------------------------------------------*/
  610. {
  611. expr_node * pN;
  612. if ( ( pN = GetLeft() ) != 0 )
  613. pN->PrintCall( pStream, LeftMargin, fInProc );
  614. pStream->Write( " = " );
  615. if ( ( pN = GetRight() ) != 0 )
  616. pN->PrintCall( pStream, LeftMargin, fInProc );
  617. }
  618. void
  619. expr_index::Print(
  620. ISTREAM * pStream )
  621. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  622. Routine Description:
  623. Emit expression for the array index operator.
  624. Arguments:
  625. pStream - A pointer to the stream.
  626. Return Value:
  627. None.
  628. Notes:
  629. ----------------------------------------------------------------------------*/
  630. {
  631. PrintSubExpr( GetLeft(), pStream );
  632. pStream->Write( '[' );
  633. GetRight()->Print( pStream );
  634. pStream->Write( ']' );
  635. }
  636. void
  637. expr_index::PrintCall(
  638. ISTREAM * pStream,
  639. short LeftMargin,
  640. BOOL fInProc )
  641. {
  642. GetLeft()->PrintCall( pStream, LeftMargin, fInProc );
  643. pStream->Write( '[' );
  644. GetRight()->PrintCall( pStream, LeftMargin, fInProc );
  645. pStream->Write( ']' );
  646. }
  647. void
  648. expr_proc_call::PrintCall(
  649. ISTREAM * pStream,
  650. short LeftMargin,
  651. BOOL fInProc )
  652. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  653. Routine Description:
  654. Emit expression for a procedure call.
  655. Arguments:
  656. pStream - A pointer to the stream.
  657. LeftMargin - The start margin for the procedure call.
  658. fInProc - Is it in a proc context already ?
  659. Return Value:
  660. None.
  661. Notes:
  662. The left margin is 0 if the call is the only thing on the line. If the
  663. call is in an assignment, the start of param indent must take that into
  664. account.
  665. ----------------------------------------------------------------------------*/
  666. {
  667. PNAME pName = GetName();
  668. unsigned short CurPref = pStream->GetPreferredIndent();
  669. unsigned short CurIndent= pStream->GetIndent();
  670. //
  671. // Print fancy only if more than 2 params.
  672. //
  673. if( GetNoOfParams() < 3 )
  674. {
  675. Print( pStream );
  676. if( !fInProc )
  677. pStream->Write(';');
  678. return;
  679. }
  680. pStream->Write( GetName() );
  681. pStream->Write( '(' );
  682. pStream->SetPreferredIndent( short( LeftMargin + CurPref + strlen( pName ) - CurIndent ) );
  683. pStream->IndentInc();
  684. pStream->NewLine();
  685. if( GetFirstParam())
  686. {
  687. GetFirstParam()->PrintCall( pStream,
  688. LeftMargin,
  689. TRUE // now in proc context
  690. );
  691. }
  692. pStream->Write( ')' );
  693. if( !fInProc )
  694. pStream->Write( ';' );
  695. pStream->IndentDec();
  696. pStream->SetPreferredIndent( CurPref );
  697. }
  698. void
  699. expr_proc_call::Print(
  700. ISTREAM * pStream )
  701. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  702. Routine Description:
  703. Emit expression for a procedure call.
  704. Arguments:
  705. pStream - A pointer to the stream.
  706. Return Value:
  707. None.
  708. Notes:
  709. ----------------------------------------------------------------------------*/
  710. {
  711. pStream->Write( GetName() );
  712. pStream->Write( '(' );
  713. if( GetFirstParam())
  714. GetFirstParam()->Print( pStream );
  715. pStream->Write( ')' );
  716. }
  717. void
  718. expr_param::Print(
  719. ISTREAM * pStream )
  720. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  721. Routine Description:
  722. Emit expression for a parameter.
  723. Arguments:
  724. pStream - A pointer to the stream.
  725. Return Value:
  726. None.
  727. Notes:
  728. ----------------------------------------------------------------------------*/
  729. {
  730. expr_node * pNextParam;
  731. GetLeft()->Print( pStream );
  732. if ( ( pNextParam = GetNextParam() ) != 0 )
  733. {
  734. pStream->Write( ',' );
  735. // pStream->NewLine();
  736. pNextParam->Print( pStream );
  737. }
  738. }
  739. void
  740. expr_param::PrintCall(
  741. ISTREAM * pStream,
  742. short LeftMargin,
  743. BOOL fInProc )
  744. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  745. Routine Description:
  746. Emit expression as part of a procedure call.
  747. Arguments:
  748. pStream - A pointer to the stream.
  749. LeftMargin - The start margin for the procedure call.
  750. fInProc - Is it in a proc context already ?
  751. pStream - A pointer to the stream.
  752. Return Value:
  753. None.
  754. Notes:
  755. ----------------------------------------------------------------------------*/
  756. {
  757. expr_node * pNextParam;
  758. GetLeft()->PrintCall( pStream, LeftMargin, fInProc );
  759. if ( ( pNextParam = GetNextParam() ) != 0 )
  760. {
  761. pStream->Write( ',' );
  762. pStream->NewLine();
  763. pNextParam->PrintCall( pStream, LeftMargin, fInProc );
  764. }
  765. }
  766. void
  767. expr_ternary::Print(
  768. ISTREAM * pStream )
  769. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  770. Routine Description:
  771. Emit a ternary expression.
  772. Arguments:
  773. pStream - A pointer to the stream.
  774. Return Value:
  775. None.
  776. Notes:
  777. Not implemented for now.
  778. ----------------------------------------------------------------------------*/
  779. {
  780. PrintSubExpr( GetRelational(), pStream );
  781. pStream->Write( " ? " );
  782. PrintSubExpr( GetLeft(), pStream );
  783. pStream->Write( " : " );
  784. PrintSubExpr( GetRight(), pStream );
  785. }
  786. /****************************************************************************
  787. utilities
  788. ****************************************************************************/
  789. char *
  790. OperatorToString(
  791. OPERATOR Op )
  792. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  793. Routine Description:
  794. Translate the operator to its string.
  795. Arguments:
  796. Op - The operator value.
  797. Return Value:
  798. Notes:
  799. ----------------------------------------------------------------------------*/
  800. {
  801. char *p;
  802. switch( Op )
  803. {
  804. case OP_PLUS: p = " + "; break;
  805. case OP_MINUS: p = " - "; break;
  806. case OP_STAR: p = " * "; break;
  807. case OP_SLASH: p = " / "; break;
  808. case OP_MOD: p = " % "; break;
  809. case OP_LEFT_SHIFT: p = " << "; break;
  810. case OP_RIGHT_SHIFT: p = " >> "; break;
  811. case OP_LESS: p = " < "; break;
  812. case OP_LESS_EQUAL: p = " <= "; break;
  813. case OP_GREATER_EQUAL: p = " >= "; break;
  814. case OP_GREATER: p = " > "; break;
  815. case OP_EQUAL: p = " == "; break;
  816. case OP_NOT_EQUAL: p = " != "; break;
  817. case OP_AND: p = " & "; break;
  818. case OP_OR: p = " | "; break;
  819. case OP_XOR: p = " ^ "; break;
  820. case OP_LOGICAL_AND: p = " && "; break;
  821. case OP_LOGICAL_OR: p = " || "; break;
  822. case OP_QM: p = " ? "; break;
  823. case OP_COLON: p = " : "; break;
  824. case OP_ASSIGN: p = " = "; break;
  825. case OP_DOT: p = " . "; break;
  826. case OP_POINTSTO: p = " -> "; break;
  827. case OP_COMMA: p = " , "; break;
  828. case OP_UNARY_NOT: p = " ! "; break;
  829. default: p = " X "; break;
  830. }
  831. return p;
  832. }