home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 10 Scripting / 02 Berger / scc / PTNode.H < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-16  |  8.2 KB  |  314 lines

  1. #ifndef __PTNode_H__
  2. #define __PTNode_H__
  3.  
  4.  
  5. #include <string>
  6. #include <vector>
  7.  
  8. #include "SmartPtr.H"
  9.  
  10. // This file defines all the various parse tree (or PT) nodes that are used by
  11. // the compiler.  Every parse tree contains the same basic structure:  a type
  12. // and a set of children.  Because of this, the base parse tree class, PTNode,
  13. // has an enumeration which describes the type of parse tree node, and an
  14. // array of children.
  15. //
  16. // Since most parse tree nodes will have a very fixed number of children
  17. // (e.g., binary operators will always have two children), it is convient to
  18. // derive utility classes from this base parse tree node.  This also has the
  19. // advantage of hiding the parse tree enumeration from the parser, and
  20. // constructors can be used to full effect.
  21.  
  22.  
  23. // The parser tends to through around pointers a lot.  Instead of having to
  24. // keep track of when to delete memory, define a bunch of smart pointers.
  25. // Since these smart pointers are reference counted, they will delete the
  26. // memory automatically.
  27. typedef SmartPtr<class PTNode> PTNodePtr;
  28. typedef SmartPtr<class AddNode> AddNodePtr;
  29. typedef SmartPtr<class SubtractNode> SubtractNodePtr;
  30. typedef SmartPtr<class MultiplyNode> MultiplyNodePtr;
  31. typedef SmartPtr<class DivideNode> DivideNodePtr;
  32. typedef SmartPtr<class AssignmentNode> AssignmentNodePtr;
  33. typedef SmartPtr<class ConstantNode> ConstantNodePtr;
  34. typedef SmartPtr<class IdentifierNode> IdentifierNodePtr;
  35. typedef SmartPtr<class IfNode> IfNodePtr;
  36. typedef SmartPtr<class ForNode> ForNodePtr;
  37. typedef SmartPtr<class StatementNode> StatementNodePtr;
  38. typedef SmartPtr<class BlockNode> BlockNodePtr;
  39.  
  40.  
  41. // Define a typedef that will keep track of the set of children nodes that a
  42. // parse tree node can contain.
  43. using namespace std;
  44. typedef vector<PTNodePtr> NodeList;
  45.  
  46.  
  47. // Define the enumeration for the parse tree node types.  Every type of parse
  48. // tree requires a unique type in here.
  49. enum PTNodeType {
  50.   Undef_PTNodeType,
  51.  
  52.   Add_PTNodeType,
  53.   Subtract_PTNodeType,
  54.   Multiply_PTNodeType,
  55.   Divide_PTNodeType,
  56.   Assignment_PTNodeType,
  57.  
  58.   Constant_PTNodeType,
  59.   Identifier_PTNodeType,
  60.  
  61.   If_PTNodeType,
  62.   For_PTNodeType,
  63.   Statement_PTNodeType,
  64.   Block_PTNodeType
  65. };
  66.  
  67.  
  68.  
  69. // Below are the various parse tree nodes that are used by the compiler.  Only
  70. // the root node contains the type enumeration and the set of children.
  71. // Derived classes simply override the constructor to allow easy construction
  72. // of the specific nodes.  They also add any helpful utiltiy functions for the
  73. // code generator to use.
  74.  
  75. class PTNode : public RefCount {
  76. public:
  77.   PTNode( PTNodeType type )
  78.   {
  79.     m_type = type;
  80.   }
  81.  
  82.   virtual string GetName() const = 0;
  83.  
  84.   void Add( PTNodePtr node )
  85.   {
  86.     m_children.push_back( node );
  87.   }
  88.  
  89.   PTNodeType GetType() const
  90.   {
  91.     return m_type;
  92.   }
  93.  
  94.   // This dump function writes to stdout the enitre contents of this parse
  95.   // tree.
  96.   void Dump() const;
  97.  
  98.  
  99. protected:
  100.   // The code generator needs to be able to iterate over the children that are
  101.   // contains in this parse tree node.  Define a few accessors so it can get
  102.   // to the iterators.
  103.   friend class CodeGen;
  104.  
  105.   NodeList::const_iterator GetChildrenBegin() const
  106.   {
  107.     return m_children.begin();
  108.   }
  109.  
  110.   NodeList::const_iterator GetChildrenEnd() const
  111.   {
  112.     return m_children.end();
  113.   }
  114.  
  115.  
  116. protected:
  117.   // This function is called recursively by Dump() to dump the entire contents
  118.   // of the parse tree.  'indent' is the current indentation level.
  119.   void Dump_Internal( int indent ) const;
  120.  
  121.   // Define the two data members for the parse tree:  The type and the set of
  122.   // children for this node.
  123.   PTNodeType m_type;
  124.   NodeList m_children;
  125. };
  126.  
  127.  
  128.  
  129. // The binary operator node is not used directly by the parser.  This class
  130. // just defines some functions that are in common with all binary operators.
  131. class BinOpNode : public PTNode {
  132. public:
  133.   BinOpNode( PTNodeType type, PTNodePtr lhs, PTNodePtr rhs )
  134.     : PTNode( type )
  135.   {
  136.     Add( lhs );
  137.     Add( rhs );
  138.   }
  139.  
  140.   const PTNodePtr GetLHS() const                  { return m_children[0]; }
  141.   const PTNodePtr GetRHS() const                  { return m_children[1]; }
  142. };
  143.  
  144.  
  145. class AddNode : public BinOpNode {
  146. public:
  147.   AddNode( PTNodePtr lhs, PTNodePtr rhs )
  148.     : BinOpNode( Add_PTNodeType, lhs, rhs )
  149.   {
  150.   }
  151.  
  152.   virtual string GetName() const                  { return "Add"; }
  153. };
  154.  
  155.  
  156. class SubtractNode : public BinOpNode {
  157. public:
  158.   SubtractNode( PTNodePtr lhs, PTNodePtr rhs )
  159.     : BinOpNode( Subtract_PTNodeType, lhs, rhs )
  160.   {
  161.   }
  162.  
  163.   virtual string GetName() const                  { return "Subtract"; }
  164. };
  165.  
  166.  
  167. class MultiplyNode : public BinOpNode {
  168. public:
  169.   MultiplyNode( PTNodePtr lhs, PTNodePtr rhs )
  170.     : BinOpNode( Multiply_PTNodeType, lhs, rhs )
  171.   {
  172.   }
  173.  
  174.   virtual string GetName() const                  { return "Multiply"; }
  175. };
  176.  
  177.  
  178. class DivideNode : public BinOpNode {
  179. public:
  180.   DivideNode( PTNodePtr lhs, PTNodePtr rhs )
  181.     : BinOpNode( Divide_PTNodeType, lhs, rhs )
  182.   {
  183.   }
  184.  
  185.   virtual string GetName() const                  { return "Divide"; }
  186. };
  187.  
  188.  
  189. class AssignmentNode : public BinOpNode {
  190. public:
  191.   AssignmentNode( PTNodePtr lhs, PTNodePtr rhs )
  192.     : BinOpNode( Assignment_PTNodeType, lhs, rhs )
  193.   {
  194.   }
  195.  
  196.   virtual string GetName() const                  { return "Assignment"; }
  197. };
  198.  
  199.  
  200.  
  201. // The constant node needs to also keep track of the constant that was
  202. // specified in script.  This is done with the data member 'm_value'.
  203. class ConstantNode : public PTNode {
  204. public:
  205.   ConstantNode( int value )
  206.     : PTNode( Constant_PTNodeType ),
  207.       m_value( value )
  208.   {
  209.   }
  210.  
  211.   int GetValue() const                            { return m_value; }
  212.  
  213.   virtual string GetName() const;
  214.  
  215.  
  216. private:
  217.   int m_value;
  218. };
  219.  
  220.  
  221. // The identifier node is used to signify where a variable is used.  The
  222. // string name contained by this node isn't used anywhere except to print the
  223. // name when the parse tree is dumped.  An identifier's offset will be
  224. // initialized by the code generator.
  225. class IdentifierNode : public PTNode {
  226. public:
  227.   IdentifierNode( string name )
  228.     : PTNode( Identifier_PTNodeType ),
  229.       m_name( name ),
  230.       m_offset( 0 )
  231.   {
  232.   }
  233.  
  234.  
  235.   void SetOffset( unsigned int offset )           { m_offset = offset; }
  236.   unsigned int GetOffset() const                  { return m_offset;   }
  237.  
  238.   virtual string GetName() const;
  239.  
  240.  
  241. private:
  242.   unsigned int m_offset;
  243.   string m_name;
  244. };
  245.  
  246.  
  247. class IfNode : public PTNode {
  248. public:
  249.   IfNode( PTNodePtr expr,
  250.           PTNodePtr trueStmts,
  251.           PTNodePtr falseStmts = NULL )
  252.     : PTNode( If_PTNodeType )
  253.   {
  254.     Add( expr );
  255.     Add( trueStmts );
  256.     Add( falseStmts );
  257.   }
  258.  
  259.   const PTNodePtr GetConditional() const          { return m_children[0]; }
  260.   const PTNodePtr GetTrueStatements() const       { return m_children[1]; }
  261.   const PTNodePtr GetFalseStatements() const      { return m_children[2]; }
  262.  
  263.   virtual string GetName() const                  { return "If"; }
  264. };
  265.  
  266.  
  267. class ForNode : public PTNode {
  268. public:
  269.   ForNode( PTNodePtr pre, PTNodePtr expr, PTNodePtr post, PTNodePtr body )
  270.     : PTNode( For_PTNodeType )
  271.   {
  272.     Add( pre );
  273.     Add( expr );
  274.     Add( post );
  275.     Add( body );
  276.   }
  277.  
  278.   const PTNodePtr GetPreLoop() const              { return m_children[0]; }
  279.   const PTNodePtr GetConditional() const          { return m_children[1]; }
  280.   const PTNodePtr GetPostLoop() const             { return m_children[2]; }
  281.   const PTNodePtr GetLoopBody() const             { return m_children[3]; }
  282.  
  283.   virtual string GetName() const                  { return "For"; }
  284. };
  285.  
  286.  
  287. class StatementNode : public PTNode {
  288. public:
  289.   StatementNode( PTNodePtr expr )
  290.     : PTNode( Statement_PTNodeType )
  291.   {
  292.     Add( expr );
  293.   }
  294.  
  295.   const PTNodePtr GetExpression() const           { return m_children[0]; }
  296.  
  297.   virtual string GetName() const                  { return "Statement"; }
  298. };
  299.  
  300.  
  301. class BlockNode : public PTNode {
  302. public:
  303.   BlockNode( PTNodePtr stmt )
  304.     : PTNode( Block_PTNodeType )
  305.   {
  306.     Add( stmt );
  307.   }
  308.  
  309.   virtual string GetName() const                  { return "Block"; }
  310. };
  311.  
  312.  
  313. #endif // __PTNode_H__
  314.