• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*=============================================================================
2      Copyright (c) 2001-2011 Joel de Guzman
3  
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  
10  #include <boost/config/warning_disable.hpp>
11  #include <boost/variant/recursive_variant.hpp>
12  #include <boost/fusion/include/adapt_struct.hpp>
13  #include <boost/fusion/include/io.hpp>
14  #include <boost/optional.hpp>
15  #include <list>
16  
17  namespace client { namespace ast
18  {
19      ///////////////////////////////////////////////////////////////////////////
20      //  The AST
21      ///////////////////////////////////////////////////////////////////////////
22      struct tagged
23      {
24          int id; // Used to annotate the AST with the iterator position.
25                  // This id is used as a key to a map<int, Iterator>
26                  // (not really part of the AST.)
27      };
28  
29      struct nil {};
30      struct unary;
31      struct function_call;
32      struct expression;
33  
34      struct identifier : tagged
35      {
identifierclient::ast::identifier36          identifier(std::string const& name = "") : name(name) {}
37          std::string name;
38      };
39  
40      typedef boost::variant<
41              nil
42            , bool
43            , unsigned int
44            , identifier
45            , boost::recursive_wrapper<unary>
46            , boost::recursive_wrapper<function_call>
47            , boost::recursive_wrapper<expression>
48          >
49      operand;
50  
51      enum optoken
52      {
53          // precedence 1
54          op_comma,
55  
56          // precedence 2
57          op_assign,
58          op_plus_assign,
59          op_minus_assign,
60          op_times_assign,
61          op_divide_assign,
62          op_mod_assign,
63          op_bit_and_assign,
64          op_bit_xor_assign,
65          op_bitor_assign,
66          op_shift_left_assign,
67          op_shift_right_assign,
68  
69          // precedence 3
70          op_logical_or,
71  
72          // precedence 4
73          op_logical_and,
74  
75          // precedence 5
76          op_bit_or,
77  
78          // precedence 6
79          op_bit_xor,
80  
81          // precedence 7
82          op_bit_and,
83  
84          // precedence 8
85          op_equal,
86          op_not_equal,
87  
88          // precedence 9
89          op_less,
90          op_less_equal,
91          op_greater,
92          op_greater_equal,
93  
94          // precedence 10
95          op_shift_left,
96          op_shift_right,
97  
98          // precedence 11
99          op_plus,
100          op_minus,
101  
102          // precedence 12
103          op_times,
104          op_divide,
105          op_mod,
106  
107          // precedence 13
108          op_positive,
109          op_negative,
110          op_pre_incr,
111          op_pre_decr,
112          op_compl,
113          op_not,
114  
115          // precedence 14
116          op_post_incr,
117          op_post_decr,
118      };
119  
120      struct unary
121      {
122          optoken operator_;
123          operand operand_;
124      };
125  
126      struct operation
127      {
128          optoken operator_;
129          operand operand_;
130      };
131  
132      struct function_call
133      {
134          identifier function_name;
135          std::list<expression> args;
136      };
137  
138      struct expression
139      {
140          operand first;
141          std::list<operation> rest;
142      };
143  
144      struct assignment
145      {
146          identifier lhs;
147          expression rhs;
148      };
149  
150      struct variable_declaration
151      {
152          identifier lhs;
153          boost::optional<expression> rhs;
154      };
155  
156      struct if_statement;
157      struct while_statement;
158      struct statement_list;
159      struct return_statement;
160  
161      typedef boost::variant<
162              variable_declaration
163            , assignment
164            , boost::recursive_wrapper<if_statement>
165            , boost::recursive_wrapper<while_statement>
166            , boost::recursive_wrapper<return_statement>
167            , boost::recursive_wrapper<statement_list>
168          >
169      statement;
170  
171      struct statement_list : std::list<statement> {};
172  
173      struct if_statement
174      {
175          expression condition;
176          statement then;
177          boost::optional<statement> else_;
178      };
179  
180      struct while_statement
181      {
182          expression condition;
183          statement body;
184      };
185  
186      struct return_statement : tagged
187      {
188          boost::optional<expression> expr;
189      };
190  
191      struct function
192      {
193          std::string return_type;
194          identifier function_name;
195          std::list<identifier> args;
196          statement_list body;
197      };
198  
199      typedef std::list<function> function_list;
200  
201      // print functions for debugging
operator <<(std::ostream & out,nil)202      inline std::ostream& operator<<(std::ostream& out, nil)
203      {
204          out << "nil"; return out;
205      }
206  
operator <<(std::ostream & out,identifier const & id)207      inline std::ostream& operator<<(std::ostream& out, identifier const& id)
208      {
209          out << id.name; return out;
210      }
211  }}
212  
213  BOOST_FUSION_ADAPT_STRUCT(
214      client::ast::unary,
215      (client::ast::optoken, operator_)
216      (client::ast::operand, operand_)
217  )
218  
219  BOOST_FUSION_ADAPT_STRUCT(
220      client::ast::operation,
221      (client::ast::optoken, operator_)
222      (client::ast::operand, operand_)
223  )
224  
225  BOOST_FUSION_ADAPT_STRUCT(
226      client::ast::function_call,
227      (client::ast::identifier, function_name)
228      (std::list<client::ast::expression>, args)
229  )
230  
231  BOOST_FUSION_ADAPT_STRUCT(
232      client::ast::expression,
233      (client::ast::operand, first)
234      (std::list<client::ast::operation>, rest)
235  )
236  
237  BOOST_FUSION_ADAPT_STRUCT(
238      client::ast::variable_declaration,
239      (client::ast::identifier, lhs)
240      (boost::optional<client::ast::expression>, rhs)
241  )
242  
243  BOOST_FUSION_ADAPT_STRUCT(
244      client::ast::assignment,
245      (client::ast::identifier, lhs)
246      (client::ast::expression, rhs)
247  )
248  
249  BOOST_FUSION_ADAPT_STRUCT(
250      client::ast::if_statement,
251      (client::ast::expression, condition)
252      (client::ast::statement, then)
253      (boost::optional<client::ast::statement>, else_)
254  )
255  
256  BOOST_FUSION_ADAPT_STRUCT(
257      client::ast::while_statement,
258      (client::ast::expression, condition)
259      (client::ast::statement, body)
260  )
261  
262  BOOST_FUSION_ADAPT_STRUCT(
263      client::ast::return_statement,
264      (boost::optional<client::ast::expression>, expr)
265  )
266  
267  BOOST_FUSION_ADAPT_STRUCT(
268      client::ast::function,
269      (std::string, return_type)
270      (client::ast::identifier, function_name)
271      (std::list<client::ast::identifier>, args)
272      (client::ast::statement_list, body)
273  )
274  
275  #endif
276