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

source code of boost/libs/spirit/example/qi/compiler_tutorial/conjure2/ast.hpp