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_CALC7_ANNOTATION_HPP) 8 #define BOOST_SPIRIT_CALC7_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 template <typename Iterator> 24 struct annotation 25 { 26 template <typename, typename> 27 struct result { typedef void type; }; 28 29 std::vector<Iterator>& iters; annotationclient::annotation30 annotation(std::vector<Iterator>& iters) 31 : iters(iters) {} 32 33 struct set_id 34 { 35 typedef void result_type; 36 37 int id; set_idclient::annotation::set_id38 set_id(int id) : id(id) {} 39 40 template <typename T> operator ()client::annotation::set_id41 void operator()(T& x) const 42 { 43 this->dispatch(x, boost::is_base_of<ast::tagged, T>()); 44 } 45 46 // This will catch all nodes except those inheriting from ast::tagged 47 template <typename T> dispatchclient::annotation::set_id48 void dispatch(T& x, boost::mpl::false_) const 49 { 50 // (no-op) no need for tags 51 } 52 53 // This will catch all nodes inheriting from ast::tagged 54 template <typename T> dispatchclient::annotation::set_id55 void dispatch(T& x, boost::mpl::true_) const 56 { 57 x.id = id; 58 } 59 }; 60 operator ()client::annotation61 void operator()(ast::operand& ast, Iterator pos) const 62 { 63 int id = iters.size(); 64 iters.push_back(pos); 65 boost::apply_visitor(set_id(id), ast); 66 } 67 operator ()client::annotation68 void operator()(ast::assignment& ast, Iterator pos) const 69 { 70 int id = iters.size(); 71 iters.push_back(pos); 72 ast.lhs.id = id; 73 } 74 }; 75 } 76 77 #endif 78 79