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