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.

2087 lines
40 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. expr.hxx
  5. Abstract:
  6. This file contains the expression class definitions.
  7. Notes:
  8. Author:
  9. VibhasC Jun-06-1993 Created
  10. Notes:
  11. This expression evaluator is used by the front and the code generator of
  12. the midl compiler. It therefore must support the complete gamut of c
  13. expressions.
  14. ----------------------------------------------------------------------------*/
  15. #ifndef __EXPR_HXX__
  16. #define __EXPR_HXX__
  17. /****************************************************************************
  18. * include files
  19. ***************************************************************************/
  20. #include "nulldefs.h"
  21. #include "common.hxx"
  22. #include "listhndl.hxx"
  23. #include "midlnode.hxx"
  24. extern "C"
  25. {
  26. #include <stdio.h>
  27. }
  28. #include "stream.hxx"
  29. #include "ndrtypes.h"
  30. #define _STRDUP( x, y ) ( (y) ? ((x) = new char[strlen(y)+1] ), strcpy( x, y ) : x = 0)
  31. class node_skl;
  32. class EXPR_CTXT;
  33. typedef char * PNAME;
  34. typedef __int64 EXPR_VALUE;
  35. /****************************************************************************
  36. * extern references
  37. ***************************************************************************/
  38. /****************************************************************************
  39. * the meat of the definitions
  40. ***************************************************************************/
  41. #if 0
  42. //
  43. // the class heirarchy for the expression evaluator. The class heirarchy for
  44. // the expression does not reflect the operator or evaluation precedence. The
  45. // class heirarchy instead reflects the organisation based on the structure of
  46. // an object of the expression class. It is upto the generator of the expression
  47. // to ensure proper precedence. In case the expression is generated by a parser
  48. // the precedence is automatically ensured. The back end which generates new
  49. // expressions must therefore ensure that the precedence is properly set up. We
  50. // will NOT check this.
  51. //
  52. expr_node
  53. expr_variable
  54. expr_resource
  55. expr_constant
  56. expr_operator
  57. expr_op_unary
  58. expr_u_arithmetic // + -
  59. expr_u_not // !
  60. expr_u_complement // ~
  61. expr_deref // *
  62. expr_u_address // &
  63. expr_cast // (type)
  64. expr_sizeof // sizeof( type )
  65. expr_alignof // __alignof( type )
  66. expr_post_incr // foo++
  67. expr_pre_incr // ++foo
  68. expr_post_decr // foo--
  69. expr_pre_decr // --foo
  70. expr_op_binary
  71. expr_b_arith // * / + - %
  72. expr_b_logical // || &&
  73. expr_relational // > >= == != < <=
  74. expr_shift // << >>
  75. expr_bitwise // |, &, ^
  76. expr_dot // a.b
  77. expr_pointsto // a->b
  78. expr_index // []
  79. expr_comma // ,
  80. expr_assign // =
  81. expr_proc // ()
  82. expr_statement // ;
  83. expr_ternary // ?:
  84. #endif // 0
  85. //
  86. // The basic expression class. This class is an abstract base class. It only
  87. // provides the interface to a general expression node.
  88. //
  89. #define _expr_node expr_node
  90. #define _expr_variable expr_variable
  91. #define _expr_constant expr_constant
  92. #define _expr_named_constant expr_named_constant
  93. #define _expr_operator expr_operator
  94. #define _expr_op_unary expr_op_unary
  95. #define _expr_op_binary expr_op_binary
  96. #define _expr_u_arithmetic expr_u_arithmetic
  97. #define _expr_u_not expr_u_not
  98. #define _expr_u_complement expr_u_complement
  99. #define _expr_u_deref expr_u_deref
  100. #define _expr_u_address expr_u_address
  101. #define _expr_cast expr_cast
  102. #define _expr_sizeof expr_sizeof
  103. #define _expr_alignof expr_alignof
  104. #define _expr_pre_incr expr_pre_incr
  105. #define _expr_pre_decr expr_pre_decr
  106. #define _expr_post_incr expr_post_incr
  107. #define _expr_post_decr expr_post_decr
  108. #define _expr_b_arithmetic expr_b_arithmetic
  109. #define _expr_b_logical expr_b_logical
  110. #define _expr_relational expr_relational
  111. #define _expr_shift expr_shift
  112. #define _expr_bitwise expr_bitwise
  113. #define _expr_dot expr_dot
  114. #define _expr_pointsto expr_pointsto
  115. #define _expr_index expr_index
  116. #define _expr_comma expr_comma
  117. #define _expr_assign expr_assign
  118. #define _expr_proc_call expr_proc_call
  119. #define _expr_param expr_param
  120. //
  121. // This is the constant expression class. For now this only has simple integral
  122. // constants. We would need to have this class to be more explicit in that it
  123. // needs to know the exact type of the constant according to the language
  124. // rules and know the exact format to be able to print this out. This is
  125. // necessary so that the generated constant looks the same as the original
  126. // for the user's convenience.
  127. //
  128. typedef enum _pformat {
  129. VALUE_TYPE_STRING,
  130. VALUE_TYPE_WSTRING,
  131. VALUE_TYPE_CHAR,
  132. VALUE_TYPE_WCHAR,
  133. VALUE_TYPE_NUMERIC,
  134. VALUE_TYPE_NUMERIC_U,
  135. VALUE_TYPE_NUMERIC_LONG,
  136. VALUE_TYPE_NUMERIC_ULONG,
  137. VALUE_TYPE_HEX,
  138. VALUE_TYPE_HEX_U,
  139. VALUE_TYPE_HEX_LONG,
  140. VALUE_TYPE_HEX_ULONG,
  141. VALUE_TYPE_OCTAL,
  142. VALUE_TYPE_OCTAL_U,
  143. VALUE_TYPE_OCTAL_LONG,
  144. VALUE_TYPE_OCTAL_ULONG,
  145. VALUE_TYPE_BOOL,
  146. VALUE_TYPE_FLOAT,
  147. VALUE_TYPE_DOUBLE,
  148. // RKK64
  149. // value types for int64
  150. VALUE_TYPE_UNDEFINED,
  151. } PFORMAT;
  152. struct SExprValue
  153. {
  154. PFORMAT format;
  155. union
  156. {
  157. signed char ch;
  158. signed short sh;
  159. signed int n;
  160. signed long l;
  161. unsigned char uch;
  162. unsigned short ush;
  163. unsigned int un;
  164. unsigned long ul;
  165. __int64 hy;
  166. float f;
  167. double d;
  168. BOOL b;
  169. wchar_t wch;
  170. } ;
  171. };
  172. typedef node_skl * ETYPE;
  173. class expr_node
  174. {
  175. protected:
  176. //
  177. // the type of the expression. All expression nodes need to have a type
  178. // since a variable / constant will have a type and so will an operation
  179. // on those variables / constants.
  180. node_skl * pType;
  181. BOOL fConstant : 1;
  182. BOOL fFloatExpr : 1;
  183. //
  184. // The constructor. Each expression node is instantiated using a type
  185. // If the type is unknown at the time of instantiation, then an error type
  186. // is the type of the expression. Therefore we provide a overloaded
  187. // constructor for both these situations.
  188. //
  189. public:
  190. expr_node()
  191. {
  192. SetType( (node_skl *)0 );
  193. fConstant = TRUE;
  194. fFloatExpr = FALSE;
  195. };
  196. expr_node( node_skl * pT )
  197. {
  198. SetType( pT );
  199. fConstant = TRUE;
  200. fFloatExpr = FALSE;
  201. };
  202. virtual void CopyTo( expr_node* lhs );
  203. virtual expr_node* Clone() { return new expr_node; };
  204. //
  205. // set the type of the expression.
  206. //
  207. void SetType( node_skl * pT )
  208. {
  209. pType = pT;
  210. }
  211. //
  212. // get the type of the expression.
  213. //
  214. virtual
  215. node_skl * GetType( void )
  216. {
  217. return pType;
  218. }
  219. //
  220. // get the type of the expression. Force it to be determined
  221. // if it is unknown
  222. //
  223. node_skl * AlwaysGetType( void )
  224. {
  225. node_skl * pType = GetType();
  226. if ( !pType )
  227. {
  228. DetermineType();
  229. pType = GetType();
  230. }
  231. return pType;
  232. }
  233. //
  234. // determine the type of the expression
  235. //
  236. virtual
  237. void DetermineType()
  238. {
  239. }
  240. //
  241. // set the "constness" of the expression.
  242. //
  243. void SetConstant( BOOL fCon = TRUE )
  244. {
  245. fConstant = fCon;
  246. }
  247. void SetFloatExpr( BOOL f = TRUE )
  248. {
  249. fFloatExpr = f;
  250. }
  251. //
  252. // queries.
  253. //
  254. virtual
  255. BOOL IsAVariable()
  256. {
  257. return FALSE;
  258. }
  259. virtual
  260. BOOL IsResource()
  261. {
  262. return FALSE;
  263. }
  264. virtual
  265. BOOL IsConstant()
  266. {
  267. return fConstant;
  268. }
  269. virtual
  270. BOOL IsOperator()
  271. {
  272. return FALSE;
  273. }
  274. virtual
  275. BOOL IsUnaryOperator()
  276. {
  277. return FALSE;
  278. }
  279. virtual
  280. BOOL IsBinaryOperator()
  281. {
  282. return FALSE;
  283. }
  284. virtual
  285. BOOL IsArithmeticOperator()
  286. {
  287. return FALSE;
  288. }
  289. virtual
  290. BOOL IsLogicalOperator()
  291. {
  292. return FALSE;
  293. }
  294. virtual
  295. BOOL IsBitwiseOperator()
  296. {
  297. return FALSE;
  298. }
  299. virtual
  300. BOOL IsRelationalOperator()
  301. {
  302. return FALSE;
  303. }
  304. virtual
  305. BOOL IsShiftOperator()
  306. {
  307. return FALSE;
  308. }
  309. //
  310. // test if the expression is a string constant
  311. //
  312. virtual
  313. BOOL IsStringConstant (void)
  314. {
  315. return FALSE;
  316. }
  317. BOOL IsFloatExpr( void )
  318. {
  319. return fFloatExpr;
  320. }
  321. //
  322. // others.
  323. //
  324. virtual
  325. expr_node * GetLeft()
  326. {
  327. return 0;
  328. }
  329. virtual
  330. expr_node * GetRight()
  331. {
  332. return 0;
  333. }
  334. virtual
  335. OPERATOR GetOperator()
  336. {
  337. return OP_ILLEGAL;
  338. }
  339. virtual
  340. EXPR_VALUE GetValue()
  341. {
  342. return 0;
  343. }
  344. virtual
  345. BOOL GetExprValue( SExprValue& v )
  346. {
  347. v.format = VALUE_TYPE_UNDEFINED;
  348. return TRUE;
  349. }
  350. //
  351. // Make (or add to) a list of var nodes of an expr
  352. //
  353. virtual
  354. short MakeListOfVars( ITERATOR & pList );
  355. virtual
  356. short MakeListOfDerefedVars( ITERATOR& )
  357. {
  358. return 0;
  359. }
  360. // gaj - this is a dummy routine
  361. virtual
  362. EXPR_VALUE Evaluate()
  363. {
  364. return GetValue();
  365. }
  366. // gaj - end of dummy routines
  367. //
  368. // Given an output steam, output the expression.
  369. //
  370. virtual
  371. void Print( ISTREAM * )
  372. {
  373. }
  374. void PrintWithPrefix( ISTREAM * pS, char * Prefix );
  375. void DecorateWithPrefix( char * Prefix = NULL );
  376. //
  377. // This is an overloaded virtual only for the proc_call node.
  378. //
  379. virtual
  380. void PrintCall( ISTREAM * pS,
  381. short ,
  382. BOOL )
  383. {
  384. Print( pS );
  385. }
  386. virtual
  387. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  388. // private allocator
  389. void * operator new ( size_t size )
  390. {
  391. return AllocateOnceNew( size );
  392. }
  393. void operator delete( void * ptr )
  394. {
  395. AllocateOnceDelete( ptr );
  396. }
  397. };
  398. //
  399. // This class represents a variable in an expression.
  400. // This expression node is instantiated for variables specified as fields of
  401. // a struct/union or as parameters. Contrast this to the resource class which
  402. // is VERY similar but only corresponds to the internally generated and used
  403. // variables in the stub routines.
  404. //
  405. class expr_variable : public expr_node
  406. {
  407. private:
  408. //
  409. // the name of the variable.
  410. //
  411. PNAME pIDName;
  412. char * pPrefix;
  413. public:
  414. //
  415. // the constructor expects the object to be instantiated using a name.
  416. // Sometimes one needs to instantiate a variable using the type too.
  417. //
  418. expr_variable( PNAME p )
  419. {
  420. SetName( p );
  421. SetType( (node_skl *)0 );
  422. SetConstant( FALSE );
  423. SetPrefix( NULL );
  424. }
  425. expr_variable( PNAME p, node_skl * pT );
  426. virtual void CopyTo( expr_node* lhs );
  427. virtual expr_node* Clone() { return new expr_variable(0); };
  428. // get the type
  429. virtual
  430. node_skl * GetType();
  431. //
  432. // set methods.
  433. //
  434. void SetName( PNAME p )
  435. {
  436. pIDName = p;
  437. }
  438. void SetPrefix( char * p )
  439. {
  440. pPrefix = p;
  441. }
  442. //
  443. // get methods
  444. //
  445. PNAME GetName()
  446. {
  447. return pIDName;
  448. }
  449. char * GetPrefix()
  450. {
  451. return pPrefix;
  452. }
  453. //
  454. // is this a variable expression.
  455. //
  456. virtual
  457. BOOL IsAVariable()
  458. {
  459. return TRUE;
  460. }
  461. //
  462. // Given an output steam, output the expression.
  463. //
  464. virtual
  465. void Print( ISTREAM * pS );
  466. //
  467. // Make (or add to) a list of var nodes of an expr
  468. //
  469. virtual
  470. short MakeListOfVars( ITERATOR & pList );
  471. //
  472. // determine the type of the expression
  473. //
  474. virtual
  475. void DetermineType();
  476. //
  477. // analyze the expression
  478. //
  479. virtual
  480. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  481. };
  482. //
  483. // This class represents a variable in an expression.
  484. // This expression node is instantiated for variables specified as fields of
  485. // a struct/union or as parameters. Contrast this to the resource class which
  486. // is VERY similar but only corresponds to the internally generated and used
  487. // variables in the stub routines.
  488. //
  489. class expr_named_constant : public expr_variable
  490. {
  491. public:
  492. //
  493. // the constructor expects the object to be instantiated using a name.
  494. // Sometimes one needs to instantiate a variable using the type too.
  495. //
  496. expr_named_constant( PNAME p = 0)
  497. : expr_variable( p )
  498. {
  499. SetConstant( TRUE );
  500. }
  501. expr_named_constant( PNAME p, node_skl * pT )
  502. : expr_variable( p, pT )
  503. {
  504. SetConstant( TRUE );
  505. }
  506. virtual expr_node* Clone() { return new expr_named_constant; };
  507. BOOL IsAVariable()
  508. {
  509. return FALSE;
  510. }
  511. //
  512. // if it is a constant id or label, we can return the value
  513. //
  514. virtual
  515. EXPR_VALUE GetValue();
  516. // similarly for expression
  517. expr_node * GetExpr();
  518. //
  519. // Make (or add to) a list of var nodes of an expr
  520. //
  521. virtual
  522. short MakeListOfVars( ITERATOR & pList );
  523. //
  524. // determine the type of the expression
  525. //
  526. virtual
  527. void DetermineType();
  528. //
  529. // analyze the expression
  530. //
  531. virtual
  532. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  533. };
  534. //
  535. // value type masks indicate the value type set by the user / determined from
  536. // the value of the constant.
  537. //
  538. #define VALUE_T_MASK_CLEAR (0x00)
  539. #define VALUE_T_MASK_CHAR (0x01)
  540. #define VALUE_T_MASK_SHORT (0x02)
  541. #define VALUE_T_MASK_LONG (0x04)
  542. #define VALUE_T_MASK_UCHAR (0x10)
  543. #define VALUE_T_MASK_USHORT (0x20)
  544. #define VALUE_T_MASK_ULONG (0x40)
  545. class expr_constant : public expr_node
  546. {
  547. private:
  548. //
  549. // store the original format. If the original format is a null then
  550. // the expression is printed out in the manner suitable for the type of
  551. // the expression. If the original format is present, then the user
  552. // declared this expression in this format and she wants it back in the
  553. // header/stub file also in the same format.
  554. PFORMAT Format;
  555. union
  556. {
  557. char C;
  558. short S;
  559. long L;
  560. __int64 I64;
  561. float F;
  562. double D;
  563. unsigned char UC;
  564. unsigned short US;
  565. unsigned long UL;
  566. unsigned __int64 UI64;
  567. unsigned char* pC;
  568. wchar_t* pWC;
  569. } Value;
  570. //
  571. // get and set the format of the constant.
  572. //
  573. void SetFormat( PFORMAT p )
  574. {
  575. Format = p;
  576. }
  577. public:
  578. virtual void CopyTo( expr_node* lhs );
  579. virtual expr_node* Clone() { return new expr_constant(this); }
  580. PFORMAT GetFormat() const
  581. {
  582. return Format;
  583. }
  584. //
  585. // Different constructors are available for the different kind of constants
  586. // that are possible.
  587. //
  588. expr_constant( char C,
  589. PFORMAT pF = VALUE_TYPE_CHAR )
  590. {
  591. SetFormat( pF );
  592. Value.I64 = C;
  593. }
  594. expr_constant( short S,
  595. PFORMAT pF = VALUE_TYPE_NUMERIC )
  596. {
  597. SetFormat( pF );
  598. Value.I64 = S;
  599. }
  600. expr_constant( long L,
  601. PFORMAT pF = VALUE_TYPE_NUMERIC )
  602. {
  603. SetFormat( pF );
  604. Value.I64 = L;
  605. }
  606. expr_constant( __int64 I64,
  607. PFORMAT pF = VALUE_TYPE_NUMERIC )
  608. {
  609. SetFormat( pF );
  610. Value.I64 = I64;
  611. }
  612. expr_constant( float F,
  613. PFORMAT pF = VALUE_TYPE_FLOAT )
  614. {
  615. SetFormat( pF );
  616. Value.F = F;
  617. }
  618. expr_constant( double D,
  619. PFORMAT pF = VALUE_TYPE_DOUBLE )
  620. {
  621. SetFormat( pF );
  622. Value.D = D;
  623. }
  624. expr_constant( unsigned char UC,
  625. PFORMAT pF = VALUE_TYPE_NUMERIC_U )
  626. {
  627. SetFormat( pF );
  628. Value.I64 = UC;
  629. }
  630. expr_constant( unsigned short US,
  631. PFORMAT pF = VALUE_TYPE_NUMERIC_U )
  632. {
  633. SetFormat( pF );
  634. Value.I64 = US;
  635. }
  636. expr_constant( unsigned long UL,
  637. PFORMAT pF = VALUE_TYPE_NUMERIC )
  638. {
  639. SetFormat( pF );
  640. Value.I64 = UL;
  641. }
  642. expr_constant( unsigned __int64 UI64,
  643. PFORMAT pF = VALUE_TYPE_NUMERIC )
  644. {
  645. SetFormat( pF );
  646. Value.I64 = (__int64)UI64;
  647. }
  648. expr_constant( char *pC,
  649. PFORMAT pF = VALUE_TYPE_STRING )
  650. {
  651. SetFormat( pF );
  652. Value.UI64 = (unsigned __int64)pC;
  653. }
  654. expr_constant( wchar_t *pWC,
  655. PFORMAT pF = VALUE_TYPE_WSTRING )
  656. {
  657. SetFormat( pF );
  658. Value.UI64 = (unsigned __int64)pWC;
  659. }
  660. expr_constant( const expr_constant *p)
  661. {
  662. SetFormat( p->GetFormat() );
  663. Value = p->Value;
  664. }
  665. //
  666. // queries.
  667. //
  668. // gaj - return constant value assuming it is long for now...
  669. virtual
  670. EXPR_VALUE GetValue();
  671. BOOL GetExprValue( SExprValue& v )
  672. {
  673. // currently only floats and double use this code path
  674. // fix this when expr evaluator is revamped
  675. v.format = VALUE_TYPE_UNDEFINED;
  676. if (Format == VALUE_TYPE_FLOAT)
  677. {
  678. v.format = Format;
  679. v.f = Value.F;
  680. }
  681. else if (Format == VALUE_TYPE_DOUBLE)
  682. {
  683. v.format = Format;
  684. v.d = Value.D;
  685. }
  686. return TRUE;
  687. }
  688. //
  689. // Given an output steam, output the expression.
  690. //
  691. virtual
  692. void Print( ISTREAM * pS );
  693. //
  694. // determine the type of the expression
  695. //
  696. virtual
  697. void DetermineType();
  698. //
  699. // analyze the expression
  700. //
  701. virtual
  702. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  703. //
  704. // test if the expression is a string constant
  705. //
  706. virtual
  707. BOOL IsStringConstant (void)
  708. {
  709. return (Format == VALUE_TYPE_STRING || Format == VALUE_TYPE_WSTRING);
  710. }
  711. };
  712. //
  713. // some convenient helper functions to get vanilla constant 0 and constant 1
  714. //
  715. extern expr_constant * GetConstant0();
  716. extern expr_constant * GetConstant1();
  717. //
  718. // the operator classes. These classes are group into unary binary and
  719. // ternary expression classes.
  720. //
  721. class expr_operator : public expr_node
  722. {
  723. private:
  724. OPERATOR Operator;
  725. public:
  726. //
  727. // the constructor of an abstract base class does nothing.
  728. //
  729. expr_operator( OPERATOR Op )
  730. {
  731. SetOperator( Op );
  732. }
  733. virtual void CopyTo( expr_node* lhs );
  734. virtual expr_node* Clone() { return new expr_operator( OP_ILLEGAL ); };
  735. //
  736. // get and set functions.
  737. //
  738. void SetOperator( OPERATOR Op )
  739. {
  740. Operator = Op;
  741. }
  742. OPERATOR GetOperator()
  743. {
  744. return Operator;
  745. }
  746. //
  747. // queries.
  748. //
  749. virtual
  750. BOOL IsOperator()
  751. {
  752. return TRUE;
  753. }
  754. void PrintSubExpr( expr_node *, ISTREAM * pS );
  755. };
  756. //
  757. // unary operator classes.
  758. //
  759. class expr_op_unary : public expr_operator
  760. {
  761. private:
  762. expr_node * pLeft;
  763. public:
  764. //
  765. // the constructor. This class is instantiated by supplying operator and
  766. // the left had side expression values.
  767. //
  768. expr_op_unary( OPERATOR Op, expr_node *pL) :
  769. expr_operator(Op)
  770. {
  771. SetLeft( pL );
  772. if ( pL ) SetConstant( pL->IsConstant() );
  773. }
  774. virtual void CopyTo( expr_node* lhs );
  775. virtual expr_node* Clone() { return new expr_op_unary( OP_ILLEGAL, 0 ); };
  776. //
  777. // get and set routines.
  778. //
  779. expr_node * SetLeft( expr_node * pL )
  780. {
  781. return ( pLeft = pL );
  782. }
  783. virtual
  784. expr_node * GetLeft()
  785. {
  786. return pLeft;
  787. }
  788. //
  789. // queries.
  790. //
  791. virtual
  792. BOOL IsUnaryOperator()
  793. {
  794. return TRUE;
  795. }
  796. //
  797. // Given an output steam, output the expression.
  798. //
  799. virtual
  800. void Print( ISTREAM * pS );
  801. //
  802. // Make (or add to) a list of var nodes of an expr
  803. //
  804. virtual
  805. short MakeListOfVars( ITERATOR & pList );
  806. //
  807. // determine the type of the expression
  808. //
  809. virtual
  810. void DetermineType();
  811. //
  812. // analyze the expression
  813. //
  814. virtual
  815. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  816. virtual
  817. short MakeListOfDerefedVars( ITERATOR& List )
  818. {
  819. if( GetLeft() )
  820. return GetLeft()->MakeListOfDerefedVars( List );
  821. return 0;
  822. }
  823. };
  824. //
  825. // binary operator class. Each binary operator node takes a left and right
  826. // expression connected by the binary operator.
  827. //
  828. class expr_op_binary : public expr_operator
  829. {
  830. private:
  831. expr_node * pLeft;
  832. expr_node * pRight;
  833. public:
  834. //
  835. // this class is instantiated by specifying the left/right and the
  836. // operator.
  837. //
  838. expr_op_binary( OPERATOR Op,
  839. expr_node * pL,
  840. expr_node * pR ) :
  841. expr_operator( Op )
  842. {
  843. SetLeft( pL );
  844. SetRight( pR );
  845. SetConstant( ( (pL) ? pL->IsConstant() : TRUE ) &&
  846. ( (pR) ? pR->IsConstant() : TRUE ) );
  847. }
  848. virtual void CopyTo( expr_node* lhs );
  849. virtual expr_node* Clone() { return new expr_op_binary( OP_ILLEGAL, 0, 0 ); };
  850. //
  851. // get and set.
  852. //
  853. virtual
  854. expr_node * SetLeft( expr_node *p )
  855. {
  856. return (pLeft = p);
  857. }
  858. virtual
  859. expr_node * SetRight( expr_node *p )
  860. {
  861. return (pRight = p);
  862. }
  863. virtual
  864. expr_node * GetLeft()
  865. {
  866. return pLeft;
  867. }
  868. virtual
  869. expr_node * GetRight()
  870. {
  871. return pRight;
  872. }
  873. //
  874. // queries.
  875. //
  876. virtual
  877. BOOL IsBinaryOperator()
  878. {
  879. return TRUE;
  880. }
  881. //
  882. // Given an output steam, output the expression.
  883. //
  884. virtual
  885. void Print( ISTREAM * pS );
  886. virtual
  887. void PrintCall( ISTREAM * pS,
  888. short LeftMargin,
  889. BOOL fInProc );
  890. //
  891. // Make (or add to) a list of var nodes of an expr
  892. //
  893. virtual
  894. short MakeListOfVars( ITERATOR & pList );
  895. virtual
  896. short MakeListOfDerefedVars( ITERATOR& List );
  897. //
  898. // determine the type of the expression
  899. //
  900. virtual
  901. void DetermineType();
  902. //
  903. // analyze the expression
  904. //
  905. virtual
  906. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  907. };
  908. //
  909. // this is the unary arithmetic class. Corresponding to the unary arithmetic
  910. // operators + and -.
  911. //
  912. class expr_u_arithmetic : public expr_op_unary
  913. {
  914. public:
  915. expr_u_arithmetic( OPERATOR Op,
  916. expr_node * pL ) :
  917. expr_op_unary(Op, pL)
  918. {
  919. }
  920. virtual expr_node* Clone() { return new expr_u_arithmetic( OP_ILLEGAL, 0 ); };
  921. //
  922. // queries.
  923. //
  924. virtual
  925. BOOL IsArithmeticOperator()
  926. {
  927. return TRUE;
  928. }
  929. //
  930. // test if the expression is a string constant
  931. //
  932. virtual
  933. BOOL IsStringConstant (void)
  934. {
  935. return GetLeft()->IsStringConstant();
  936. }
  937. virtual
  938. EXPR_VALUE GetValue();
  939. BOOL GetExprValue( SExprValue& v );
  940. };
  941. //
  942. // this is the unary not operator class.
  943. //
  944. class expr_u_not : public expr_op_unary
  945. {
  946. public:
  947. expr_u_not( expr_node * pL ) :
  948. expr_op_unary(OP_UNARY_NOT, pL )
  949. {
  950. }
  951. virtual expr_node* Clone() { return new expr_u_not( 0 ); };
  952. //
  953. // queries.
  954. //
  955. virtual
  956. BOOL IsLogicalOperator()
  957. {
  958. return TRUE;
  959. }
  960. virtual
  961. EXPR_VALUE GetValue();
  962. };
  963. //
  964. // the unary complement class.
  965. //
  966. class expr_u_complement : public expr_op_unary
  967. {
  968. public:
  969. expr_u_complement( expr_node *pL ) :
  970. expr_op_unary(OP_UNARY_COMPLEMENT, pL)
  971. {
  972. }
  973. virtual expr_node* Clone() { return new expr_u_complement( 0 ); };
  974. //
  975. // queries.
  976. //
  977. virtual
  978. BOOL IsBitwiseOperator()
  979. {
  980. return TRUE;
  981. }
  982. virtual
  983. EXPR_VALUE GetValue();
  984. };
  985. //
  986. // unary derefence operator
  987. //
  988. class expr_u_deref : public expr_op_unary
  989. {
  990. public:
  991. expr_u_deref( expr_node *pL ) :
  992. expr_op_unary(OP_UNARY_INDIRECTION, pL)
  993. {
  994. SetConstant( FALSE );
  995. }
  996. expr_u_deref( OPERATOR op, expr_node *pL ) :
  997. expr_op_unary(op, pL)
  998. {
  999. SetConstant( FALSE );
  1000. }
  1001. virtual expr_node* Clone() { return new expr_u_deref( 0 ); };
  1002. virtual
  1003. short MakeListOfDerefedVars( ITERATOR& List );
  1004. };
  1005. //
  1006. //
  1007. class expr_u_address : public expr_op_unary
  1008. {
  1009. public:
  1010. expr_u_address( expr_node *pL ) :
  1011. expr_op_unary(OP_UNARY_AND, pL)
  1012. {
  1013. SetConstant( FALSE );
  1014. }
  1015. virtual expr_node* Clone() { return new expr_u_address( 0 ); };
  1016. };
  1017. //
  1018. // the unary cast operator
  1019. //
  1020. class expr_cast : public expr_op_unary
  1021. {
  1022. node_skl* pCastType;
  1023. bool fEmitModifiers;
  1024. public:
  1025. expr_cast( node_skl * pT, expr_node *pL ) :
  1026. expr_op_unary(OP_UNARY_CAST, pL),
  1027. fEmitModifiers( true )
  1028. {
  1029. pCastType = pT;
  1030. }
  1031. virtual void CopyTo( expr_node* lhs );
  1032. virtual expr_node* Clone() { return new expr_cast( 0, 0 ); };
  1033. //
  1034. // Given an output steam, output the expression.
  1035. //
  1036. virtual
  1037. void SetEmitModifiers(bool fModifier = true) { fEmitModifiers = fModifier; }
  1038. virtual
  1039. bool GetEmitModifiers() { return fEmitModifiers; }
  1040. virtual
  1041. void Print( ISTREAM * pS );
  1042. virtual
  1043. node_skl * GetType()
  1044. {
  1045. return pCastType;
  1046. }
  1047. virtual
  1048. EXPR_VALUE GetValue();
  1049. };
  1050. //
  1051. // the unary sizeof operator.
  1052. //
  1053. class expr_sizeof : public expr_op_unary
  1054. {
  1055. node_skl * pType;
  1056. public:
  1057. expr_sizeof( node_skl *pT) :
  1058. expr_op_unary( OP_UNARY_SIZEOF,NULL )
  1059. {
  1060. pType = pT;
  1061. }
  1062. expr_sizeof( expr_node *pL ) :
  1063. expr_op_unary( OP_UNARY_SIZEOF,pL )
  1064. {
  1065. pType = pL->GetType();
  1066. }
  1067. virtual void CopyTo( expr_node* lhs );
  1068. virtual expr_node* Clone() { return new expr_sizeof( (node_skl*)0 ); };
  1069. //
  1070. // Given an output steam, output the expression.
  1071. //
  1072. virtual
  1073. void Print( ISTREAM * pS );
  1074. virtual
  1075. short MakeListOfVars( ITERATOR & pList );
  1076. virtual
  1077. EXPR_VALUE GetValue();
  1078. };
  1079. //
  1080. // the unary __alignof operator.
  1081. //
  1082. class expr_alignof : public expr_op_unary
  1083. {
  1084. node_skl * pType;
  1085. public:
  1086. expr_alignof( node_skl *pT) :
  1087. expr_op_unary( OP_UNARY_ALIGNOF, NULL )
  1088. {
  1089. pType = pT;
  1090. }
  1091. expr_alignof( expr_node *pL ) :
  1092. expr_op_unary( OP_UNARY_ALIGNOF, pL )
  1093. {
  1094. pType = pL->GetType();
  1095. }
  1096. virtual void CopyTo( expr_node* lhs );
  1097. virtual expr_node* Clone() { return new expr_alignof( (node_skl*)0 ); };
  1098. //
  1099. // Given an output steam, output the expression.
  1100. //
  1101. virtual
  1102. void Print( ISTREAM * pS );
  1103. virtual
  1104. short MakeListOfVars( ITERATOR & pList );
  1105. virtual
  1106. EXPR_VALUE GetValue();
  1107. };
  1108. //
  1109. // unary pre-increment operator.
  1110. //
  1111. class expr_pre_incr : public expr_op_unary
  1112. {
  1113. public:
  1114. expr_pre_incr( expr_node *pL ) :
  1115. expr_op_unary(OP_PRE_INCR, pL)
  1116. {
  1117. SetType( pL->GetType());
  1118. }
  1119. virtual expr_node* Clone() { return new expr_pre_incr(0); };
  1120. //
  1121. // Given an output steam, output the expression.
  1122. //
  1123. virtual
  1124. void Print( ISTREAM * pS );
  1125. };
  1126. //
  1127. // unary pre-decrement operator.
  1128. //
  1129. class expr_pre_decr : public expr_op_unary
  1130. {
  1131. public:
  1132. expr_pre_decr( expr_node *pL ):
  1133. expr_op_unary(OP_PRE_DECR, pL)
  1134. {
  1135. SetType( pL->GetType());
  1136. }
  1137. virtual expr_node* Clone() { return new expr_pre_decr(0); };
  1138. //
  1139. // Given an output steam, output the expression.
  1140. //
  1141. virtual
  1142. void Print( ISTREAM * pS );
  1143. };
  1144. //
  1145. // unary post-increment operator.
  1146. //
  1147. class expr_post_incr : public expr_op_unary
  1148. {
  1149. public:
  1150. expr_post_incr( expr_node *pL ):
  1151. expr_op_unary(OP_POST_INCR, pL)
  1152. {
  1153. SetType( pL->GetType());
  1154. }
  1155. virtual expr_node* Clone() { return new expr_post_incr(0); };
  1156. //
  1157. // Given an output steam, output the expression.
  1158. //
  1159. virtual
  1160. void Print( ISTREAM * pS );
  1161. };
  1162. //
  1163. // unary post-decrement operator.
  1164. //
  1165. class expr_post_decr : public expr_op_unary
  1166. {
  1167. public:
  1168. expr_post_decr( expr_node *pL ):
  1169. expr_op_unary(OP_POST_DECR, pL)
  1170. {
  1171. SetType( pL->GetType());
  1172. }
  1173. virtual expr_node* Clone() { return new expr_post_decr(0); };
  1174. //
  1175. // Given an output steam, output the expression.
  1176. //
  1177. virtual
  1178. void Print( ISTREAM * pS );
  1179. };
  1180. //
  1181. // binary arithmetic operators.
  1182. //
  1183. class expr_b_arithmetic : public expr_op_binary
  1184. {
  1185. public:
  1186. expr_b_arithmetic( OPERATOR Op,
  1187. expr_node *pL,
  1188. expr_node *pR ):
  1189. expr_op_binary( Op, pL, pR )
  1190. {
  1191. }
  1192. virtual expr_node* Clone() { return new expr_b_arithmetic(OP_ILLEGAL,0,0); };
  1193. //
  1194. // queries.
  1195. //
  1196. virtual
  1197. BOOL IsArithmeticOperator()
  1198. {
  1199. return TRUE;
  1200. }
  1201. virtual
  1202. EXPR_VALUE GetValue();
  1203. BOOL GetExprValue( SExprValue& v );
  1204. };
  1205. //
  1206. // binary logical operators.
  1207. //
  1208. class expr_b_logical : public expr_op_binary
  1209. {
  1210. public:
  1211. expr_b_logical( OPERATOR Op,
  1212. expr_node *pL,
  1213. expr_node *pR ):
  1214. expr_op_binary( Op, pL, pR )
  1215. {
  1216. }
  1217. virtual expr_node* Clone() { return new expr_b_logical(OP_ILLEGAL,0,0); };
  1218. //
  1219. // queries.
  1220. //
  1221. virtual
  1222. BOOL IsLogicalOperator()
  1223. {
  1224. return TRUE;
  1225. }
  1226. virtual
  1227. EXPR_VALUE GetValue();
  1228. };
  1229. //
  1230. // relational operators.
  1231. //
  1232. class expr_relational : public expr_op_binary
  1233. {
  1234. public:
  1235. expr_relational( OPERATOR Op,
  1236. expr_node *pL,
  1237. expr_node *pR ):
  1238. expr_op_binary( Op, pL, pR )
  1239. {
  1240. }
  1241. virtual expr_node* Clone() { return new expr_relational(OP_ILLEGAL,0,0); };
  1242. //
  1243. // queries.
  1244. //
  1245. virtual
  1246. BOOL IsRelationalOperator()
  1247. {
  1248. return TRUE;
  1249. }
  1250. virtual
  1251. EXPR_VALUE GetValue();
  1252. };
  1253. //
  1254. // shift operators.
  1255. //
  1256. class expr_shift : public expr_op_binary
  1257. {
  1258. public:
  1259. expr_shift( OPERATOR Op,
  1260. expr_node *pL,
  1261. expr_node *pR ):
  1262. expr_op_binary( Op, pL, pR )
  1263. {
  1264. }
  1265. virtual expr_node* Clone() { return new expr_shift(OP_ILLEGAL,0,0); };
  1266. //
  1267. // queries.
  1268. //
  1269. virtual
  1270. BOOL IsShiftOperator()
  1271. {
  1272. return TRUE;
  1273. }
  1274. virtual
  1275. EXPR_VALUE GetValue();
  1276. };
  1277. //
  1278. // bitwise operators.
  1279. //
  1280. class expr_bitwise : public expr_op_binary
  1281. {
  1282. public:
  1283. expr_bitwise( OPERATOR Op,
  1284. expr_node *pL,
  1285. expr_node *pR ):
  1286. expr_op_binary( Op, pL, pR )
  1287. {
  1288. }
  1289. virtual expr_node* Clone() { return new expr_bitwise(OP_ILLEGAL,0,0); };
  1290. //
  1291. // queries.
  1292. //
  1293. virtual
  1294. BOOL IsBitwiseOperator()
  1295. {
  1296. return TRUE;
  1297. }
  1298. virtual
  1299. EXPR_VALUE GetValue();
  1300. };
  1301. //
  1302. // dot operator.
  1303. //
  1304. class expr_dot : public expr_op_binary
  1305. {
  1306. public:
  1307. expr_dot( expr_node *pL, expr_node *pR ):
  1308. expr_op_binary( OP_DOT, pL, pR )
  1309. {
  1310. }
  1311. virtual expr_node* Clone() { return new expr_dot(0,0); };
  1312. };
  1313. //
  1314. // pointsto operator.
  1315. //
  1316. class expr_pointsto : public expr_op_binary
  1317. {
  1318. public:
  1319. expr_pointsto( expr_node *pL, expr_node *pR ):
  1320. expr_op_binary( OP_POINTSTO, pL, pR )
  1321. {
  1322. }
  1323. virtual expr_node* Clone() { return new expr_pointsto(0,0); };
  1324. };
  1325. //
  1326. // array element operator.
  1327. //
  1328. class expr_index : public expr_op_binary
  1329. {
  1330. public:
  1331. expr_index( expr_node *pL, expr_node *pR );
  1332. virtual expr_node* Clone() { return new expr_index(0,0); };
  1333. //
  1334. // Given an output steam, output the expression.
  1335. //
  1336. virtual
  1337. void Print( ISTREAM * pS );
  1338. virtual
  1339. void PrintCall( ISTREAM * pS,
  1340. short LeftMargin,
  1341. BOOL fInProc );
  1342. };
  1343. //
  1344. // comma operator.
  1345. //
  1346. class expr_comma : public expr_op_binary
  1347. {
  1348. public:
  1349. expr_comma( expr_node *pL, expr_node *pR ):
  1350. expr_op_binary( OP_COMMA, pL, pR )
  1351. {
  1352. }
  1353. virtual expr_node* Clone() { return new expr_comma(0,0); };
  1354. };
  1355. //
  1356. // assign operator.
  1357. //
  1358. class expr_assign : public expr_op_binary
  1359. {
  1360. public:
  1361. expr_assign( expr_node *pL, expr_node *pR ):
  1362. expr_op_binary( OP_ASSIGN, pL, pR )
  1363. {
  1364. }
  1365. virtual expr_node* Clone() { return new expr_assign(0,0); };
  1366. virtual
  1367. void PrintCall( ISTREAM * pS,
  1368. short LeftMargin,
  1369. BOOL fInProc );
  1370. };
  1371. //
  1372. // proc operator.
  1373. //
  1374. class expr_proc_call : public expr_op_unary
  1375. {
  1376. private:
  1377. PNAME pName;
  1378. short NoOfParams;
  1379. //
  1380. // Set the first parameter of the function. This is a private method
  1381. // because the world should use the SetParam function which will take care
  1382. // of inserting the new param expression in the correct (last) place in the
  1383. // parameter list.
  1384. //
  1385. class expr_param * SetFirstParam( class expr_param * p )
  1386. {
  1387. return (class expr_param *)SetLeft(
  1388. (class expr_node *) p );
  1389. }
  1390. public:
  1391. expr_proc_call(PNAME pN,
  1392. expr_node *pParamList):
  1393. expr_op_unary(OP_FUNCTION,pParamList)
  1394. {
  1395. SetName( pN );
  1396. SetNoOfParams( 0 );
  1397. }
  1398. expr_proc_call( PNAME pN ) :
  1399. expr_op_unary(OP_FUNCTION, 0)
  1400. {
  1401. SetName( pN );
  1402. SetNoOfParams( 0 );
  1403. }
  1404. virtual void CopyTo( expr_node* lhs );
  1405. virtual expr_node* Clone() { return new expr_proc_call(0); };
  1406. //
  1407. // get and set functions.
  1408. //
  1409. void SetName( PNAME pN )
  1410. {
  1411. pName = pN;
  1412. }
  1413. PNAME GetName()
  1414. {
  1415. return pName;
  1416. }
  1417. unsigned short SetNoOfParams( unsigned short N )
  1418. {
  1419. return (NoOfParams = N);
  1420. }
  1421. unsigned short GetNoOfParams()
  1422. {
  1423. return NoOfParams;
  1424. }
  1425. unsigned short IncrNoOfParams()
  1426. {
  1427. return (++NoOfParams);
  1428. }
  1429. //
  1430. // This method is used to get at the first param of a function. After
  1431. // that GetNextParam calls are made on the param node itself. This will
  1432. // be our most frequent usage, eg in the printing of the expression.
  1433. //
  1434. class expr_param * GetFirstParam()
  1435. {
  1436. return (class expr_param *)GetLeft();
  1437. }
  1438. //
  1439. // This method will insert the parameter expression at the end of the
  1440. // parameter list. This is done so that an procedure call expression
  1441. // can be created in the natural (left to right) order.
  1442. //
  1443. class expr_param * SetParam( class expr_param * pParam );
  1444. class expr_param * SetParam( expr_node * pExpr );
  1445. //
  1446. // Given an output steam, output the expression. This does not
  1447. // generate a semi-colon.
  1448. //
  1449. virtual
  1450. void Print( ISTREAM * pS );
  1451. //
  1452. // This call generates a call with a semi-colon
  1453. //
  1454. virtual
  1455. void PrintCall( ISTREAM * pS, short InitMargin, BOOL fInProc );
  1456. };
  1457. class expr_param : public expr_op_binary
  1458. {
  1459. private:
  1460. PNAME pName;
  1461. public:
  1462. expr_param(expr_node *pParamExpr ):
  1463. expr_op_binary(OP_PARAM,pParamExpr, 0)
  1464. {
  1465. pName = NULL;
  1466. }
  1467. virtual void CopyTo( expr_node* lhs );
  1468. virtual expr_node* Clone() { return new expr_param(0); };
  1469. //
  1470. // queries.
  1471. //
  1472. //
  1473. // This method gets the next parameter in the parameter list. To emit the
  1474. // parameter expressions for a procedure, get the first parameter on the
  1475. // expr_proc_call node and then make GetNextParam calls on the parameter
  1476. // till the call returns a null.
  1477. //
  1478. expr_param * GetNextParam()
  1479. {
  1480. return (expr_param *)GetRight();
  1481. }
  1482. //
  1483. // This method sets the next param expression to be the one specified. This
  1484. // method does not traverse the list of params and insert at the end !!.
  1485. //
  1486. expr_param * SetNextParam( expr_param * p )
  1487. {
  1488. return (expr_param *)SetRight( p );
  1489. }
  1490. //
  1491. // This method traverses to the end of the parameter list and inserts a new
  1492. // param expression at the end .Use this method when a procedure call
  1493. // expression is being generated. The way to do this is to create a
  1494. // expr_proc_call node and make as many SetParam calls to it as there are
  1495. // parameter expressions. They will all get inserted into the parameter list
  1496. // in the left to right (natural) order, with each new param expression
  1497. // going to the end of the list.
  1498. //
  1499. expr_param * SetLastPeerParam( expr_param * pN );
  1500. // Given an output steam, output the expression.
  1501. //
  1502. virtual
  1503. void Print( ISTREAM * pS );
  1504. virtual
  1505. void PrintCall( ISTREAM * pS,
  1506. short LeftMargin,
  1507. BOOL fInProc );
  1508. };
  1509. //
  1510. // ternary operator class. Each ternary operator node takes a relational, left and right
  1511. // expression connected by the ternary operator.
  1512. //
  1513. class expr_ternary : public expr_operator
  1514. {
  1515. private:
  1516. expr_node * pLeft;
  1517. expr_node * pRight;
  1518. expr_node * pRelational;
  1519. public:
  1520. //
  1521. // this class is instantiated by specifying the left/right and the
  1522. // operator.
  1523. //
  1524. expr_ternary( OPERATOR Op,
  1525. expr_node * pRel,
  1526. expr_node * pL,
  1527. expr_node * pR ) :
  1528. expr_operator( Op )
  1529. {
  1530. SetRelational( pRel );
  1531. SetLeft( pL );
  1532. SetRight( pR );
  1533. SetConstant( ( (pL) ? pL->IsConstant() : TRUE ) &&
  1534. ( (pR) ? pR->IsConstant() : TRUE ) &&
  1535. ( (pRel) ? pRel->IsConstant() : TRUE ) );
  1536. }
  1537. virtual void CopyTo( expr_node* lhs );
  1538. virtual expr_node* Clone();
  1539. //
  1540. // get and set.
  1541. //
  1542. virtual
  1543. expr_node * SetRelational( expr_node *p )
  1544. {
  1545. return (pRelational = p);
  1546. }
  1547. virtual
  1548. expr_node * SetLeft( expr_node *p )
  1549. {
  1550. return (pLeft = p);
  1551. }
  1552. virtual
  1553. expr_node * SetRight( expr_node *p )
  1554. {
  1555. return (pRight = p);
  1556. }
  1557. virtual
  1558. expr_node * GetRelational()
  1559. {
  1560. return pRelational;
  1561. }
  1562. virtual
  1563. expr_node * GetLeft()
  1564. {
  1565. return pLeft;
  1566. }
  1567. virtual
  1568. expr_node * GetRight()
  1569. {
  1570. return pRight;
  1571. }
  1572. //
  1573. // queries.
  1574. //
  1575. virtual
  1576. BOOL IsBinaryOperator()
  1577. {
  1578. return TRUE;
  1579. }
  1580. //
  1581. // Given an output steam, output the expression.
  1582. //
  1583. void Print( ISTREAM * pS );
  1584. virtual
  1585. EXPR_VALUE GetValue();
  1586. //
  1587. // determine the type of the expression
  1588. //
  1589. virtual
  1590. void DetermineType();
  1591. //
  1592. // analyze the expression
  1593. //
  1594. virtual
  1595. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  1596. virtual
  1597. short MakeListOfVars( ITERATOR & pList );
  1598. };
  1599. // gaj - these are added for now to satisfy the grammar
  1600. class expr_init_list: public expr_node
  1601. {
  1602. private:
  1603. class expr_init_list * pSibling;
  1604. class expr_node * pExpr;
  1605. public:
  1606. expr_init_list( expr_node * pE )
  1607. {
  1608. pExpr = pE;
  1609. SetConstant( pE->IsConstant() );
  1610. };
  1611. virtual void CopyTo( expr_node* lhs );
  1612. virtual expr_node* Clone() { return new expr_init_list(0); };
  1613. virtual
  1614. void LinkSibling( class expr_init_list * pIL )
  1615. {
  1616. pSibling = pIL;
  1617. }
  1618. // assume only the first value here...
  1619. virtual
  1620. EXPR_VALUE GetValue()
  1621. {
  1622. return pExpr->GetValue();
  1623. }
  1624. //
  1625. // Given an output steam, output the expression.
  1626. //
  1627. virtual
  1628. void Print( ISTREAM * pS )
  1629. {
  1630. pExpr->Print( pS );
  1631. }
  1632. //
  1633. // determine the type of the expression
  1634. //
  1635. virtual
  1636. void DetermineType();
  1637. //
  1638. // analyze the expression
  1639. //
  1640. virtual
  1641. void ExprAnalyze( EXPR_CTXT * pExprCtxt );
  1642. };
  1643. class expr_error: public expr_node
  1644. {
  1645. public:
  1646. virtual expr_node* Clone() { return new expr_error; };
  1647. };
  1648. #endif // __EXPR_HXX__