$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66941 - in sandbox/SOC/2010/phoenix3: boost/phoenix/scope libs/phoenix/test/scope
From: thom.heller_at_[hidden]
Date: 2010-12-01 02:26:52
Author: theller
Date: 2010-12-01 02:26:48 EST (Wed, 01 Dec 2010)
New Revision: 66941
URL: http://svn.boost.org/trac/boost/changeset/66941
Log:
let almost working again
Text files modified: 
   sandbox/SOC/2010/phoenix3/boost/phoenix/scope/let.hpp                |    90 +++++++++++++++++--                     
   sandbox/SOC/2010/phoenix3/boost/phoenix/scope/local_variable.hpp     |   175 +++++++++++++++++++++++++++++++++------ 
   sandbox/SOC/2010/phoenix3/boost/phoenix/scope/scoped_environment.hpp |    18 +++                                     
   sandbox/SOC/2010/phoenix3/libs/phoenix/test/scope/let_tests.cpp      |    29 +++--                                   
   4 files changed, 257 insertions(+), 55 deletions(-)
Modified: sandbox/SOC/2010/phoenix3/boost/phoenix/scope/let.hpp
==============================================================================
--- sandbox/SOC/2010/phoenix3/boost/phoenix/scope/let.hpp	(original)
+++ sandbox/SOC/2010/phoenix3/boost/phoenix/scope/let.hpp	2010-12-01 02:26:48 EST (Wed, 01 Dec 2010)
@@ -23,23 +23,92 @@
 {
     PHOENIX_DEFINE_EXPRESSION(
         let
-      , (proto::_)//(rule::local_variables)
-        (proto::_)//(rule::let_grammar)
+      , (rule::local_var_def_list)
+        (meta_grammar)
     )
 
     struct let_eval
     {
-        typedef void result_type;
+        template <typename Sig>
+        struct result;
+
+        template <typename This, typename Env, typename Locals, typename Let>
+        struct result<This(Env, Locals const&, Let const&)>
+        {
+            typedef
+                typename boost::result_of<
+                    functional::args(Env)
+                >::type
+                args_type;
+
+            typedef
+                typename boost::result_of<
+                    functional::actions(Env)
+                >::type
+                actions_type;
+
+            typedef
+                typename boost::result_of<
+                    rule::local_var_def_list(
+                        Locals
+                      , args_type
+                      , actions_type
+                    )
+                >::type
+                locals_type;
+
+            typedef
+                typename boost::result_of<
+                    evaluator(
+                        Let const &
+                      , fusion::vector2<scoped_environment<args_type, args_type, locals_type> &, actions_type&>&
+                    )
+                >::type
+                type;
+        };
 
         template <typename Env, typename Locals, typename Let>
-        result_type
+        typename result<let_eval(Env&, Locals const&, Let const&)>::type
         operator()(Env & env, Locals const & locals, Let const & let) const
         {
-            std::cout << "yeha!\n";
-            std::cout << typeid(Locals).name() << "\n\n";
-            std::cout << typeid(rule::local_var_def_list()(locals, functional::args()(env), functional::actions()(env))).name() << "\n\n-------\n";
-            std::cout << typeid(find_local()(rule::local_var_def_list()(locals, functional::args()(env), functional::actions()(env)), _a)).name() << "\n\n-------\n";
-            scope_grammar()(let, functional::args()(env), functional::actions()(env));
+            typedef
+                typename boost::result_of<
+                    functional::args(Env &)
+                >::type
+                args_type;
+
+            typedef
+                typename boost::result_of<
+                    functional::actions(Env &)
+                >::type
+                actions_type;
+
+            typedef
+                typename boost::result_of<
+                    rule::local_var_def_list(
+                        Locals
+                      , args_type
+                      , actions_type
+                    )
+                >::type
+                locals_type;
+
+            args_type & old_env = functional::args()(env);
+            actions_type & actions = functional::actions()(env);
+
+            scoped_environment<args_type, args_type, locals_type>
+                scoped_env(
+                    old_env
+                  , old_env
+                  , rule::local_var_def_list()(
+                      locals
+                    , old_env
+                    , actions
+                    )
+                );
+
+            fusion::vector2<scoped_environment<args_type, args_type, locals_type> &, actions_type&> new_env(scoped_env, actions);
+            return eval(let, new_env);
         }
     };
 
@@ -166,7 +235,6 @@
         > const
         operator()(Expr0 const& expr0, Expr1 const& expr1) const
         {
-            std::cout << typeid(typename detail::make_locals<Expr0, Expr1>::type).name() << "\n\n";
             return detail::make_locals<Expr0, Expr1>::make(expr0, expr1);
         }
 
@@ -176,7 +244,6 @@
         > const
         operator()(Expr0 const& expr0, Expr1 const& expr1, Expr2 const& expr2) const
         {
-            std::cout << typeid(typename detail::make_locals<Expr0, Expr1, Expr2>::type).name() << "\n\n";
             return detail::make_locals<Expr0, Expr1, Expr2>::make(expr0, expr1, expr2);
         }
 
@@ -186,7 +253,6 @@
         > const
         operator()(Expr0 const& expr0, Expr1 const& expr1, Expr2 const& expr2, Expr3 const & expr3) const
         {
-            std::cout << typeid(typename detail::make_locals<Expr0, Expr1, Expr2, Expr3>::type).name() << "\n\n";
             return detail::make_locals<Expr0, Expr1, Expr2, Expr3>::make(expr0, expr1, expr2, expr3);
         }
     };
Modified: sandbox/SOC/2010/phoenix3/boost/phoenix/scope/local_variable.hpp
==============================================================================
--- sandbox/SOC/2010/phoenix3/boost/phoenix/scope/local_variable.hpp	(original)
+++ sandbox/SOC/2010/phoenix3/boost/phoenix/scope/local_variable.hpp	2010-12-01 02:26:48 EST (Wed, 01 Dec 2010)
@@ -82,35 +82,129 @@
     namespace detail
     {
         struct local_var_not_found {};
-    }
 
-    struct find_local
-        : proto::or_<
-            proto::when<
-                proto::comma<find_local, rule::local_var_def>
-              , proto::if_<
-                    proto::matches<proto::_right, proto::_state>()
-                  , proto::_value(proto::_right(proto::_right))
-                  , find_local(proto::_left, proto::_state)
+        struct find_local
+            : proto::or_<
+                proto::when<
+                    proto::comma<find_local, rule::local_var_def>
+                  , proto::if_<
+                        proto::matches<proto::_left(proto::_right), proto::_state>()
+                      , proto::_value(proto::_right(proto::_right))
+                      , find_local(proto::_left, proto::_state)
+                    >
                 >
-          , proto::when<
-                rule::local_var_def
-              , proto::if_<
-                    proto::matches<proto::_right, proto::_state>()
-                  , proto::_value(proto::_right(proto::_right))
-                  , detail::local_var_not_found()
+              , proto::when<
+                    rule::local_var_def
+                  , proto::if_<
+                        proto::matches<proto::_left, proto::_state>()
+                      , proto::_value(proto::_right)
+                      , detail::local_var_not_found()
+                    >
                 >
             >
-        >
-    {};
-                
+        {};
+
+        template<typename This, typename Env, typename Key>
+        struct get_local_result_impl
+            : mpl::if_<
+                is_same<
+                    typename boost::result_of<
+                        detail::find_local(typename Env::locals_type, Key)
+                    >::type
+                  , detail::local_var_not_found
+                >
+              , typename boost::result_of<
+                    This(typename Env::outer_env_type&)
+                >::type
+              , typename boost::result_of<
+                    detail::find_local(typename Env::locals_type, Key)
+              >::type
+            >
+        {};
+    }
 
+    template <typename Key>
+    struct get_local
+    {
+        template <typename Sig>
+        struct result;
+
+        template <typename This, typename Env>
+        struct result<This(Env &)>
+            : mpl::eval_if<
+                is_scoped_environment<Env>
+              , detail::get_local_result_impl<This, Env, Key>
+              , mpl::identity<detail::local_var_not_found>
+            >
+        {};
+
+        template <typename Env>
+        typename result<get_local<Key>(Env&)>::type
+        operator()(Env &env) const
+        {
+            typedef typename result<get_local<Key>(Env&)>::type result_type;
+
+            return this->evaluate(
+                env
+              , typename is_scoped_environment<Env>::type()
+            );
+        }
+
+        private:
+            
+            // is a scoped environment
+            template <typename Env>
+            typename result<get_local<Key>(Env&)>::type
+            evaluate(Env & env, mpl::true_) const
+            {
+                return
+                    this->evaluate_scoped(
+                        env
+                      , typename is_same<
+                            typename boost::result_of<detail::find_local(typename Env::locals_type, Key)>::type
+                          , detail::local_var_not_found
+                        >::type()
+                    );
+            }
+
+            // is a scoped environment, and we have the local in our environment
+            template <typename Env>
+            typename result<get_local<Key>(Env&)>::type
+            evaluate_scoped(Env & env, mpl::false_) const
+            {
+                return detail::find_local()(env.locals, Key());
+            }
+            
+            // is a scoped environment, and we need to look in the outer environment
+            template <typename Env>
+            typename result<get_local<Key>(Env&)>::type
+            evaluate_scoped(Env & env, mpl::true_) const
+            {
+                return get_local<Key>()(env.outer_env);
+            }
+            
+            template <typename Env>
+            typename result<get_local<Key>(Env&)>::type
+            evaluate(Env & env, mpl::false_) const
+            {
+                return detail::local_var_not_found();
+            }
+
+    };
+
+    /*
     struct scope_grammar
         : proto::or_<
             proto::when<rule::local_variable, proto::external_transform>
           , meta_grammar
         >
     {};
+    */
+    
+    template<typename T>
+    struct is_custom_terminal<local_variable<T> >
+      : mpl::true_
+    {};
 
     struct local_var_eval
         : proto::callable
@@ -118,22 +212,47 @@
         template <typename Sig>
         struct result;
 
-        template <typename This, typename Env, typename Local>
-        struct result<This(Env&, Local)>
+        template <typename This, typename Local, typename Env>
+        struct result<This(Local const &, Env)>
         {
-            typedef int type;
+            typedef
+                proto::terminal< local_variable<typename Local::type> >
+                lookup_grammar;
+            typedef
+                typename boost::result_of<
+                    functional::args(Env)
+                >::type
+                args_type;
+            typedef
+                typename boost::result_of<get_local<lookup_grammar>(args_type&)>::type
+                type;
         };
 
-        typedef int result_type;
-
-        template <typename Env, typename Local>
-        typename result<local_var_eval(Env&, Local)>::type
-        operator()(Env & env, Local local)
+        template <typename Local, typename Env>
+        typename result<local_var_eval(Local const &, Env&)>::type
+        operator()(Local const& local, Env & env)
         {
-            std::cout << "blubb\n";
-            return 5;
+            typedef
+                proto::terminal< local_variable<typename Local::type> >
+                lookup_grammar;
+            typedef
+                typename boost::result_of<
+                    functional::args(Env)
+                >::type
+                args_type;
+
+            std::cout << typeid(Env).name() << "\n";
+            std::cout << typeid(Local).name() << "\n";
+            //std::cout << typeid(typename boost::result_of<get_local<lookup_grammar>(args_type&)>::type).name() << "\n";
+            //std::cout << detail::find_local()(functional::args()(env).locals, lookup_grammar()) << "\n";
+            return get_local<lookup_grammar>()(functional::args()(env));
         }
     };
+    
+    template<typename T>
+    struct custom_terminal<local_variable<T> >
+        : local_var_eval
+    {};
 
     template <typename Dummy>
     struct default_actions::when<rule::local_variable, Dummy>
Modified: sandbox/SOC/2010/phoenix3/boost/phoenix/scope/scoped_environment.hpp
==============================================================================
--- sandbox/SOC/2010/phoenix3/boost/phoenix/scope/scoped_environment.hpp	(original)
+++ sandbox/SOC/2010/phoenix3/boost/phoenix/scope/scoped_environment.hpp	2010-12-01 02:26:48 EST (Wed, 01 Dec 2010)
@@ -44,7 +44,11 @@
         template <typename Seq>                                                 \
         struct INTRINSIC                                                        \
         {                                                                       \
-            typedef typename Seq::env_type env_type;                            \
+            typedef                                                             \
+                typename boost::remove_reference<                               \
+                    typename Seq::env_type                                      \
+                >::type                                                         \
+                env_type;                                                       \
             typedef typename fusion::result_of::INTRINSIC<env_type>::type type; \
                                                                                 \
             static type call(Seq & seq)                                         \
@@ -61,14 +65,22 @@
         template <typename Seq, typename N>
         struct value_at
         {
-            typedef typename Seq::env_type env_type;
+            typedef
+                typename boost::remove_reference<
+                    typename Seq::env_type
+                >::type
+                env_type;
             typedef typename fusion::result_of::value_at<env_type, N>::type type;
         };
         
         template <typename Seq, typename N>
         struct at
         {
-            typedef typename Seq::env_type env_type;
+            typedef
+                typename boost::remove_reference<
+                    typename Seq::env_type
+                >::type
+                env_type;
             typedef typename fusion::result_of::at<env_type, N>::type type;
 
             static type call(Seq & seq)
Modified: sandbox/SOC/2010/phoenix3/libs/phoenix/test/scope/let_tests.cpp
==============================================================================
--- sandbox/SOC/2010/phoenix3/libs/phoenix/test/scope/let_tests.cpp	(original)
+++ sandbox/SOC/2010/phoenix3/libs/phoenix/test/scope/let_tests.cpp	2010-12-01 02:26:48 EST (Wed, 01 Dec 2010)
@@ -16,6 +16,7 @@
 #include <boost/phoenix/function.hpp>
 //#include <boost/phoenix/fusion.hpp>
 #include <boost/phoenix/scope.hpp>
+#include <boost/fusion/container/vector.hpp>
 
 #include <typeinfo>
 
@@ -41,15 +42,6 @@
     using boost::phoenix::placeholders::arg1;
 
     {
-        BOOST_TEST(let()[val(1)]() == 1);
-
-        //_a();
-        let(_a = val(9)+ 10, _b = val(9) + 3.0)[_a]();
-    }
-
-#if 0
-/*
-    {
         int x = 1;
         BOOST_TEST(
             let(_a = _1)
@@ -100,6 +92,7 @@
         );
     }
 
+    /*
     {
         int x = 999;
         BOOST_TEST(
@@ -112,7 +105,9 @@
         
         BOOST_TEST(x == 888 + 999);    
     }
+    */
 
+    /*
     {
         int x = 999;
         BOOST_TEST(
@@ -126,6 +121,8 @@
         BOOST_TEST(x == 999);
     }
     */
+
+    /*
     {
         // FIXME do not require a argument to return int
         BOOST_TEST(
@@ -150,7 +147,8 @@
             (0)
         ).name() << "\n";
     }
-  /*  
+    */
+
 #ifdef PHOENIX_SHOULD_NOT_COMPILE_TEST
     {
         // disallow this:
@@ -167,20 +165,25 @@
         BOOST_TEST(x == 1);
     }
 
+    /*
     {
         // show that this code returns an lvalue
         int i = 1;
         let(_a = arg1)[ _a ](i)++;
         BOOST_TEST(i == 2);
     }
+    */
 
+    /*
     {
         // show that what you put in is what you get out
         int i = 1;
         int& j = let(_a = arg1)[_a](i);
         BOOST_TEST(&i == &j);
     }
+    */
 
+    /*
     {
         using boost::phoenix::at_c;
 
@@ -189,14 +192,16 @@
 
         BOOST_TEST( i == 0 );
     }
+    */
 
+    /*
     {
         int i = 0;
         let(_a = _1)[_a = _2](i, 2);
         BOOST_TEST(i == 2);
     }
-*/
-#endif
+    */
+
     return boost::report_errors();
 }