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_CALC8_AST_HPP) 8 #define BOOST_SPIRIT_CALC8_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 expression; 32 33 struct variable : tagged 34 { variableclient::ast::variable35 variable(std::string const& name = "") : name(name) {} 36 std::string name; 37 }; 38 39 typedef boost::variant< 40 nil 41 , bool 42 , unsigned int 43 , variable 44 , boost::recursive_wrapper<unary> 45 , boost::recursive_wrapper<expression> 46 > 47 operand; 48 49 enum optoken 50 { 51 op_plus, 52 op_minus, 53 op_times, 54 op_divide, 55 op_positive, 56 op_negative, 57 op_not, 58 op_equal, 59 op_not_equal, 60 op_less, 61 op_less_equal, 62 op_greater, 63 op_greater_equal, 64 op_and, 65 op_or 66 }; 67 68 struct unary 69 { 70 optoken operator_; 71 operand operand_; 72 }; 73 74 struct operation 75 { 76 optoken operator_; 77 operand operand_; 78 }; 79 80 struct expression 81 { 82 operand first; 83 std::list<operation> rest; 84 }; 85 86 struct assignment 87 { 88 variable lhs; 89 expression rhs; 90 }; 91 92 struct variable_declaration 93 { 94 assignment assign; 95 }; 96 97 struct if_statement; 98 struct while_statement; 99 struct statement_list; 100 101 typedef boost::variant< 102 variable_declaration 103 , assignment 104 , boost::recursive_wrapper<if_statement> 105 , boost::recursive_wrapper<while_statement> 106 , boost::recursive_wrapper<statement_list> 107 > 108 statement; 109 110 struct statement_list : std::list<statement> {}; 111 112 struct if_statement 113 { 114 expression condition; 115 statement then; 116 boost::optional<statement> else_; 117 }; 118 119 struct while_statement 120 { 121 expression condition; 122 statement body; 123 }; 124 125 // print functions for debugging operator <<(std::ostream & out,nil)126 inline std::ostream& operator<<(std::ostream& out, nil) { out << "nil"; return out; } operator <<(std::ostream & out,variable const & var)127 inline std::ostream& operator<<(std::ostream& out, variable const& var) { out << var.name; return out; } 128 }} 129 130 BOOST_FUSION_ADAPT_STRUCT( 131 client::ast::unary, 132 (client::ast::optoken, operator_) 133 (client::ast::operand, operand_) 134 ) 135 136 BOOST_FUSION_ADAPT_STRUCT( 137 client::ast::operation, 138 (client::ast::optoken, operator_) 139 (client::ast::operand, operand_) 140 ) 141 142 BOOST_FUSION_ADAPT_STRUCT( 143 client::ast::expression, 144 (client::ast::operand, first) 145 (std::list<client::ast::operation>, rest) 146 ) 147 148 BOOST_FUSION_ADAPT_STRUCT( 149 client::ast::variable_declaration, 150 (client::ast::assignment, assign) 151 ) 152 153 BOOST_FUSION_ADAPT_STRUCT( 154 client::ast::assignment, 155 (client::ast::variable, lhs) 156 (client::ast::expression, rhs) 157 ) 158 159 BOOST_FUSION_ADAPT_STRUCT( 160 client::ast::if_statement, 161 (client::ast::expression, condition) 162 (client::ast::statement, then) 163 (boost::optional<client::ast::statement>, else_) 164 ) 165 166 BOOST_FUSION_ADAPT_STRUCT( 167 client::ast::while_statement, 168 (client::ast::expression, condition) 169 (client::ast::statement, body) 170 ) 171 172 #endif 173