1 /*=============================================================================
2     Copyright (c) 2001-2014 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_X3_CALC9_AST_HPP)
8 #define BOOST_SPIRIT_X3_CALC9_AST_HPP
9 
10 #include <boost/spirit/home/x3/support/ast/variant.hpp>
11 #include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
12 #include <boost/fusion/include/io.hpp>
13 #include <boost/optional.hpp>
14 #include <list>
15 
16 namespace client { namespace ast
17 {
18     ///////////////////////////////////////////////////////////////////////////
19     //  The AST
20     ///////////////////////////////////////////////////////////////////////////
21     namespace x3 = boost::spirit::x3;
22 
23     struct nil {};
24     struct unary;
25     struct expression;
26 
27     struct variable : x3::position_tagged
28     {
variableclient::ast::variable29         variable(std::string const& name = "") : name(name) {}
30         std::string name;
31     };
32 
33     struct operand :
34         x3::variant<
35             nil
36           , unsigned int
37           , variable
38           , x3::forward_ast<unary>
39           , x3::forward_ast<expression>
40         >
41     {
42         using base_type::base_type;
43         using base_type::operator=;
44     };
45 
46     enum optoken
47     {
48         op_plus,
49         op_minus,
50         op_times,
51         op_divide,
52         op_positive,
53         op_negative,
54         op_not,
55         op_equal,
56         op_not_equal,
57         op_less,
58         op_less_equal,
59         op_greater,
60         op_greater_equal,
61         op_and,
62         op_or
63     };
64 
65     struct unary
66     {
67         optoken operator_;
68         operand operand_;
69     };
70 
71     struct operation : x3::position_tagged
72     {
73         optoken operator_;
74         operand operand_;
75     };
76 
77     struct expression : x3::position_tagged
78     {
79         operand first;
80         std::list<operation> rest;
81     };
82 
83     struct assignment : x3::position_tagged
84     {
85         variable lhs;
86         expression rhs;
87     };
88 
89     struct variable_declaration
90     {
91         assignment assign;
92     };
93 
94     struct if_statement;
95     struct while_statement;
96     struct statement_list;
97 
98     struct statement :
99         x3::variant<
100             variable_declaration
101           , assignment
102           , boost::recursive_wrapper<if_statement>
103           , boost::recursive_wrapper<while_statement>
104           , boost::recursive_wrapper<statement_list>
105         >
106     {
107         using base_type::base_type;
108         using base_type::operator=;
109     };
110 
111     struct statement_list : std::list<statement> {};
112 
113     struct if_statement
114     {
115         expression condition;
116         statement then;
117         boost::optional<statement> else_;
118     };
119 
120     struct while_statement
121     {
122         expression condition;
123         statement body;
124     };
125 
126     // print functions for debugging
operator <<(std::ostream & out,nil)127     inline std::ostream& operator<<(std::ostream& out, nil)
128     {
129         out << "nil";
130         return out;
131     }
132 
operator <<(std::ostream & out,variable const & var)133     inline std::ostream& operator<<(std::ostream& out, variable const& var)
134     {
135         out << var.name; return out;
136     }
137 }}
138 
139 #endif
140