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_ANNOTATION_HPP) 8 #define BOOST_SPIRIT_CONJURE_ANNOTATION_HPP 9 10 #include <map> 11 #include <boost/variant/apply_visitor.hpp> 12 #include <boost/type_traits/is_base_of.hpp> 13 #include <boost/mpl/bool.hpp> 14 #include "ast.hpp" 15 16 namespace client 17 { 18 /////////////////////////////////////////////////////////////////////////////// 19 // The annotation handler links the AST to a map of iterator positions 20 // for the purpose of subsequent semantic error handling when the 21 // program is being compiled. 22 /////////////////////////////////////////////////////////////////////////////// 23 struct set_annotation_id 24 { 25 typedef void result_type; 26 27 int id; set_annotation_idclient::set_annotation_id28 set_annotation_id(int id) : id(id) {} 29 operator ()client::set_annotation_id30 void operator()(ast::function_call& x) const 31 { 32 x.function_name.id = id; 33 } 34 35 template <typename T> dispatchclient::set_annotation_id36 void dispatch(T& x, boost::mpl::true_) const 37 { 38 x.id = id; 39 } 40 41 template <typename T> dispatchclient::set_annotation_id42 void dispatch(T& x, boost::mpl::false_) const 43 { 44 // no-op 45 } 46 47 template <typename T> operator ()client::set_annotation_id48 void operator()(T& x) const 49 { 50 typename boost::is_base_of<ast::tagged, T> is_tagged; 51 dispatch(x, is_tagged); 52 } 53 }; 54 55 struct get_annotation_id 56 { 57 typedef int result_type; 58 operator ()client::get_annotation_id59 int operator()(ast::function_call& x) const 60 { 61 return x.function_name.id; 62 } 63 64 template <typename T> dispatchclient::get_annotation_id65 int dispatch(T& x, boost::mpl::true_) const 66 { 67 return x.id; 68 } 69 70 template <typename T> dispatchclient::get_annotation_id71 int dispatch(T& x, boost::mpl::false_) const 72 { 73 return -1; 74 } 75 76 template <typename T> operator ()client::get_annotation_id77 int operator()(T& x) const 78 { 79 typename boost::is_base_of<ast::tagged, T> is_tagged; 80 return dispatch(x, is_tagged); 81 } 82 }; 83 84 template <typename Iterator> 85 struct annotation 86 { 87 template <typename, typename> 88 struct result { typedef void type; }; 89 90 std::vector<Iterator>& iters; annotationclient::annotation91 annotation(std::vector<Iterator>& iters) 92 : iters(iters) {} 93 operator ()client::annotation94 void operator()(ast::operand& ast, Iterator pos) const 95 { 96 int id = iters.size(); 97 iters.push_back(pos); 98 boost::apply_visitor(set_annotation_id(id), ast); 99 ast.id = id; 100 } 101 operator ()client::annotation102 void operator()(ast::primary_expr& ast, Iterator pos) const 103 { 104 int id = iters.size(); 105 iters.push_back(pos); 106 boost::apply_visitor(set_annotation_id(id), ast); 107 ast.id = id; 108 } 109 operator ()client::annotation110 void operator()(ast::variable_declaration& ast, Iterator pos) const 111 { 112 int id = iters.size(); 113 iters.push_back(pos); 114 ast.lhs.id = id; 115 } 116 operator ()client::annotation117 void operator()(ast::assignment& ast, Iterator pos) const 118 { 119 int id = iters.size(); 120 iters.push_back(pos); 121 ast.lhs.id = id; 122 } 123 operator ()client::annotation124 void operator()(ast::return_statement& ast, Iterator pos) const 125 { 126 int id = iters.size(); 127 iters.push_back(pos); 128 ast.id = id; 129 } 130 operator ()client::annotation131 void operator()(ast::identifier& ast, Iterator pos) const 132 { 133 int id = iters.size(); 134 iters.push_back(pos); 135 ast.id = id; 136 } 137 }; 138 } 139 140 #endif 141 142