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/optional.hpp>
16 #include <list>
17 
18 #include "ids.hpp"
19 
20 namespace client { namespace ast
21 {
22     ///////////////////////////////////////////////////////////////////////////
23     //  The AST
24     ///////////////////////////////////////////////////////////////////////////
25     struct tagged
26     {
27         int id; // Used to annotate the AST with the iterator position.
28                 // This id is used as a key to a map<int, Iterator>
29                 // (not really part of the AST.)
30     };
31 
32     struct nil {};
33     struct unary;
34     struct function_call;
35     struct expression;
36 
37     struct identifier : tagged
38     {
identifierclient::ast::identifier39         identifier(std::string const& name = "") : name(name) {}
40         std::string name;
41     };
42 
43     typedef boost::variant<
44             nil
45           , bool
46           , unsigned int
47           , identifier
48           , boost::recursive_wrapper<unary>
49           , boost::recursive_wrapper<function_call>
50           , boost::recursive_wrapper<expression>
51         >
52     operand;
53 
54     struct unary
55     {
56         token_ids::type operator_;
57         operand operand_;
58     };
59 
60     struct operation
61     {
62         token_ids::type operator_;
63         operand operand_;
64     };
65 
66     struct function_call
67     {
68         identifier function_name;
69         std::list<expression> args;
70     };
71 
72     struct expression
73     {
74         operand first;
75         std::list<operation> rest;
76     };
77 
78     struct assignment
79     {
80         identifier lhs;
81         expression rhs;
82     };
83 
84     struct variable_declaration
85     {
86         identifier lhs;
87         boost::optional<expression> rhs;
88     };
89 
90     struct if_statement;
91     struct while_statement;
92     struct statement_list;
93     struct return_statement;
94 
95     typedef boost::variant<
96             variable_declaration
97           , assignment
98           , boost::recursive_wrapper<if_statement>
99           , boost::recursive_wrapper<while_statement>
100           , boost::recursive_wrapper<return_statement>
101           , boost::recursive_wrapper<statement_list>
102         >
103     statement;
104 
105     struct statement_list : std::list<statement> {};
106 
107     struct if_statement
108     {
109         expression condition;
110         statement then;
111         boost::optional<statement> else_;
112     };
113 
114     struct while_statement
115     {
116         expression condition;
117         statement body;
118     };
119 
120     struct return_statement : tagged
121     {
122         boost::optional<expression> expr;
123     };
124 
125     struct function
126     {
127         std::string return_type;
128         identifier function_name;
129         std::list<identifier> args;
130         statement_list body;
131     };
132 
133     typedef std::list<function> function_list;
134 
135     // print functions for debugging
operator <<(std::ostream & out,nil)136     inline std::ostream& operator<<(std::ostream& out, nil)
137     {
138         out << "nil"; return out;
139     }
140 
operator <<(std::ostream & out,identifier const & id)141     inline std::ostream& operator<<(std::ostream& out, identifier const& id)
142     {
143         out << id.name; return out;
144     }
145 }}
146 
147 BOOST_FUSION_ADAPT_STRUCT(
148     client::ast::unary,
149     (client::token_ids::type, operator_)
150     (client::ast::operand, operand_)
151 )
152 
153 BOOST_FUSION_ADAPT_STRUCT(
154     client::ast::operation,
155     (client::token_ids::type, operator_)
156     (client::ast::operand, operand_)
157 )
158 
159 BOOST_FUSION_ADAPT_STRUCT(
160     client::ast::function_call,
161     (client::ast::identifier, function_name)
162     (std::list<client::ast::expression>, args)
163 )
164 
165 BOOST_FUSION_ADAPT_STRUCT(
166     client::ast::expression,
167     (client::ast::operand, first)
168     (std::list<client::ast::operation>, rest)
169 )
170 
171 BOOST_FUSION_ADAPT_STRUCT(
172     client::ast::variable_declaration,
173     (client::ast::identifier, lhs)
174     (boost::optional<client::ast::expression>, rhs)
175 )
176 
177 BOOST_FUSION_ADAPT_STRUCT(
178     client::ast::assignment,
179     (client::ast::identifier, lhs)
180     (client::ast::expression, rhs)
181 )
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 
190 BOOST_FUSION_ADAPT_STRUCT(
191     client::ast::while_statement,
192     (client::ast::expression, condition)
193     (client::ast::statement, body)
194 )
195 
196 BOOST_FUSION_ADAPT_STRUCT(
197     client::ast::return_statement,
198     (boost::optional<client::ast::expression>, expr)
199 )
200 
201 BOOST_FUSION_ADAPT_STRUCT(
202     client::ast::function,
203     (std::string, return_type)
204     (client::ast::identifier, function_name)
205     (std::list<client::ast::identifier>, args)
206     (client::ast::statement_list, body)
207 )
208 
209 #endif
210