ast.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #if !defined(BOOST_SPIRIT_CONJURE_AST_HPP)
  8. #define BOOST_SPIRIT_CONJURE_AST_HPP
  9. #include <boost/config/warning_disable.hpp>
  10. #include <boost/variant/recursive_variant.hpp>
  11. #include <boost/fusion/include/adapt_struct.hpp>
  12. #include <boost/fusion/include/io.hpp>
  13. #include <boost/spirit/include/support_extended_variant.hpp>
  14. #include <boost/spirit/include/support_attributes.hpp>
  15. #include <boost/optional.hpp>
  16. #include <list>
  17. #include "ids.hpp"
  18. namespace client { namespace ast
  19. {
  20. ///////////////////////////////////////////////////////////////////////////
  21. // The AST
  22. ///////////////////////////////////////////////////////////////////////////
  23. struct tagged
  24. {
  25. int id; // Used to annotate the AST with the iterator position.
  26. // This id is used as a key to a map<int, Iterator>
  27. // (not really part of the AST.)
  28. };
  29. struct nil {};
  30. struct unary_expr;
  31. struct function_call;
  32. struct expression;
  33. struct identifier : tagged
  34. {
  35. identifier(std::string const& name = "") : name(name) {}
  36. std::string name;
  37. };
  38. struct primary_expr :
  39. tagged,
  40. boost::spirit::extended_variant<
  41. nil
  42. , bool
  43. , unsigned int
  44. , identifier
  45. , boost::recursive_wrapper<expression>
  46. >
  47. {
  48. primary_expr() : base_type() {}
  49. primary_expr(bool val) : base_type(val) {}
  50. primary_expr(unsigned int val) : base_type(val) {}
  51. primary_expr(identifier const& val) : base_type(val) {}
  52. primary_expr(expression const& val) : base_type(val) {}
  53. primary_expr(primary_expr const& rhs)
  54. : base_type(rhs.get()) {}
  55. };
  56. struct operand :
  57. tagged,
  58. boost::spirit::extended_variant<
  59. nil
  60. , primary_expr
  61. , boost::recursive_wrapper<unary_expr>
  62. , boost::recursive_wrapper<function_call>
  63. >
  64. {
  65. operand() : base_type() {}
  66. operand(primary_expr const& val) : base_type(val) {}
  67. operand(unary_expr const& val) : base_type(val) {}
  68. operand(function_call const& val) : base_type(val) {}
  69. operand(operand const& rhs)
  70. : base_type(rhs.get()) {}
  71. };
  72. struct unary_expr : tagged
  73. {
  74. token_ids::type operator_;
  75. operand operand_;
  76. };
  77. struct operation
  78. {
  79. token_ids::type operator_;
  80. operand operand_;
  81. };
  82. struct function_call
  83. {
  84. identifier function_name;
  85. std::list<expression> args;
  86. };
  87. struct expression
  88. {
  89. operand first;
  90. std::list<operation> rest;
  91. };
  92. struct assignment
  93. {
  94. identifier lhs;
  95. token_ids::type operator_;
  96. expression rhs;
  97. };
  98. struct variable_declaration
  99. {
  100. identifier lhs;
  101. boost::optional<expression> rhs;
  102. };
  103. struct if_statement;
  104. struct while_statement;
  105. struct statement_list;
  106. struct return_statement;
  107. typedef boost::variant<
  108. nil
  109. , variable_declaration
  110. , assignment
  111. , boost::recursive_wrapper<if_statement>
  112. , boost::recursive_wrapper<while_statement>
  113. , boost::recursive_wrapper<return_statement>
  114. , boost::recursive_wrapper<statement_list>
  115. , boost::recursive_wrapper<expression>
  116. >
  117. statement;
  118. struct statement_list : std::list<statement> {};
  119. struct if_statement
  120. {
  121. expression condition;
  122. statement then;
  123. boost::optional<statement> else_;
  124. };
  125. struct while_statement
  126. {
  127. expression condition;
  128. statement body;
  129. };
  130. struct return_statement : tagged
  131. {
  132. boost::optional<expression> expr;
  133. };
  134. struct function
  135. {
  136. std::string return_type;
  137. identifier function_name;
  138. std::list<identifier> args;
  139. boost::optional<statement_list> body;
  140. };
  141. typedef std::list<function> function_list;
  142. // print functions for debugging
  143. inline std::ostream& operator<<(std::ostream& out, nil)
  144. {
  145. out << "nil"; return out;
  146. }
  147. inline std::ostream& operator<<(std::ostream& out, identifier const& id)
  148. {
  149. out << id.name; return out;
  150. }
  151. }}
  152. BOOST_FUSION_ADAPT_STRUCT(
  153. client::ast::unary_expr,
  154. (client::token_ids::type, operator_)
  155. (client::ast::operand, operand_)
  156. )
  157. BOOST_FUSION_ADAPT_STRUCT(
  158. client::ast::operation,
  159. (client::token_ids::type, operator_)
  160. (client::ast::operand, operand_)
  161. )
  162. BOOST_FUSION_ADAPT_STRUCT(
  163. client::ast::function_call,
  164. (client::ast::identifier, function_name)
  165. (std::list<client::ast::expression>, args)
  166. )
  167. BOOST_FUSION_ADAPT_STRUCT(
  168. client::ast::expression,
  169. (client::ast::operand, first)
  170. (std::list<client::ast::operation>, rest)
  171. )
  172. BOOST_FUSION_ADAPT_STRUCT(
  173. client::ast::variable_declaration,
  174. (client::ast::identifier, lhs)
  175. (boost::optional<client::ast::expression>, rhs)
  176. )
  177. BOOST_FUSION_ADAPT_STRUCT(
  178. client::ast::assignment,
  179. (client::ast::identifier, lhs)
  180. (client::token_ids::type, operator_)
  181. (client::ast::expression, rhs)
  182. )
  183. BOOST_FUSION_ADAPT_STRUCT(
  184. client::ast::if_statement,
  185. (client::ast::expression, condition)
  186. (client::ast::statement, then)
  187. (boost::optional<client::ast::statement>, else_)
  188. )
  189. BOOST_FUSION_ADAPT_STRUCT(
  190. client::ast::while_statement,
  191. (client::ast::expression, condition)
  192. (client::ast::statement, body)
  193. )
  194. BOOST_FUSION_ADAPT_STRUCT(
  195. client::ast::return_statement,
  196. (boost::optional<client::ast::expression>, expr)
  197. )
  198. BOOST_FUSION_ADAPT_STRUCT(
  199. client::ast::function,
  200. (std::string, return_type)
  201. (client::ast::identifier, function_name)
  202. (std::list<client::ast::identifier>, args)
  203. (boost::optional<client::ast::statement_list>, body)
  204. )
  205. #endif