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