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