Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61460 - in trunk/libs/spirit/example/scheme: example/scheme scheme
From: joel_at_[hidden]
Date: 2010-04-21 10:02:08


Author: djowel
Date: 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
New Revision: 61460
URL: http://svn.boost.org/trac/boost/changeset/61460

Log:
working lambda function application
Added:
   trunk/libs/spirit/example/scheme/example/scheme/scheme_test.cpp
      - copied, changed from r61451, /trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp
   trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm (contents, props changed)
Removed:
   trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp
Text files modified:
   trunk/libs/spirit/example/scheme/example/scheme/scheme_test.cpp | 4 +
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 84 ++++++++++++++++++++++++---------------
   trunk/libs/spirit/example/scheme/scheme/interpreter.hpp | 10 ++++
   trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp | 18 ++++++++
   4 files changed, 81 insertions(+), 35 deletions(-)

Deleted: trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
+++ (empty file)
@@ -1,47 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#include <boost/config/warning_disable.hpp>
-
-#include <input/sexpr.hpp>
-#include <input/parse_sexpr_impl.hpp>
-#include <scheme/compiler.hpp>
-#include <utree/io.hpp>
-#include <fstream>
-
-///////////////////////////////////////////////////////////////////////////////
-// Main program
-///////////////////////////////////////////////////////////////////////////////
-int main(int argc, char **argv)
-{
- char const* filename = filename = argv[1];
- std::ifstream in(filename, std::ios_base::in);
-
- if (!in)
- {
- std::cerr << filename << " not found" << std::endl;
- return -1;
- }
-
- // Ignore the BOM marking the beginning of a UTF-8 file in Windows
- char c = in.peek();
- if (c == '\xef')
- {
- char s[3];
- in >> s[0] >> s[1] >> s[2];
- s[3] = '\0';
- if (s != std::string("\xef\xbb\xbf"))
- {
- std::cerr << "unexpected characters in file" << std::endl;
- return -1;
- }
- }
-
- scheme::interpreter factorial(in, filename);
- return 0;
-}
-
-

Copied: trunk/libs/spirit/example/scheme/example/scheme/scheme_test.cpp (from r61451, /trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp)
==============================================================================
--- /trunk/libs/spirit/example/scheme/example/scheme/scheme_error_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/scheme/scheme_test.cpp 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
@@ -40,7 +40,9 @@
         }
     }
 
- scheme::interpreter factorial(in, filename);
+ scheme::interpreter f(in, filename);
+ if (!f.empty())
+ f();
     return 0;
 }
 

Added: trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
@@ -0,0 +1,3 @@
+(define (apply x f) (display (f x)))
+
+(apply 123 (lambda (x) (+ x 1)))
\ No newline at end of file

Modified: trunk/libs/spirit/example/scheme/scheme/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/compiler.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/compiler.hpp 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
@@ -10,8 +10,10 @@
 #include <vector>
 #include <map>
 #include <exception>
+#include <cstdlib>
 
 #include <boost/bind.hpp>
+#include <boost/tuple/tuple.hpp>
 #include <scheme/intrinsics.hpp>
 #include <scheme/interpreter.hpp>
 #include <input/parse_sexpr.hpp>
@@ -27,7 +29,7 @@
     {
         virtual const char* what() const throw()
         {
- return "scheme: Compilation error";
+ return "scheme: Compilation error.";
         }
     };
 
@@ -35,7 +37,7 @@
     {
         virtual const char* what() const throw()
         {
- return "scheme: Identifier expected";
+ return "scheme: Identifier expected.";
         }
     };
 
@@ -43,7 +45,7 @@
     {
         std::string msg;
         identifier_not_found(std::string const& id)
- : msg("scheme: Identifier (" + id + ") not found") {}
+ : msg("scheme: Identifier (" + id + ") not found.") {}
 
         virtual const char* what() const throw()
         {
@@ -59,16 +61,25 @@
 
         virtual const char* what() const throw()
         {
- return "scheme: Duplicate identifier";
+ return "scheme: Duplicate identifier.";
         }
     };
 
     struct incorrect_arity : scheme_exception
     {
         std::string msg;
- incorrect_arity(std::string const& id)
+ incorrect_arity(std::string const& id, int arity, bool fixed)
           : msg("scheme: Invalid number of parameters to function call ("
- + id + ')') {}
+ + id + ").")
+ {
+ if (!fixed)
+ msg += std::string(" Expecting at least ");
+ else
+ msg += std::string(" Expecting ");
+
+ char buff[std::numeric_limits<int>::digits10];
+ msg += std::string(ltoa(arity, buff, 10)) + " arguments.";
+ }
 
         virtual const char* what() const throw()
         {
@@ -89,23 +100,27 @@
           : outer(parent) {}
 
         template <typename Function>
- void define(std::string const& name, Function const& f, int arity)
+ void define(std::string const& name, Function const& f, int arity, bool fixed)
         {
             if (definitions.find(name) != definitions.end())
                 throw duplicate_identifier(name);
- definitions[name] = std::make_pair(compiled_function(f), arity);
+ definitions[name] = boost::make_tuple(compiled_function(f), arity, fixed);
         }
 
- std::pair<compiled_function*, int>
+ boost::tuple<compiled_function*, int, bool>
         find(std::string const& name)
         {
             std::map<std::string, map_element>::iterator
                 i = definitions.find(name);
             if (i != definitions.end())
- return std::make_pair(&i->second.first, i->second.second);
+ return boost::make_tuple(
+ &boost::get<0>(i->second),
+ boost::get<1>(i->second),
+ boost::get<2>(i->second)
+ );
             else if (outer != 0)
                 return outer->find(name);
- return std::make_pair((compiled_function*)0, 0);
+ return boost::make_tuple((compiled_function*)0, 0, false);
         }
 
         void undefine(std::string const& name)
@@ -122,7 +137,7 @@
 
     private:
 
- typedef std::pair<compiled_function, int> map_element;
+ typedef boost::tuple<compiled_function, int, bool> map_element;
 
         environment* outer;
         std::map<std::string, map_element> definitions;
@@ -185,11 +200,11 @@
         function operator()(utf8_symbol_range const& str) const
         {
             std::string name(str.begin(), str.end());
- std::pair<compiled_function*, int> r = env.find(name);
- if (r.first)
+ boost::tuple<compiled_function*, int, bool> r = env.find(name);
+ if (boost::get<0>(r))
             {
                 actor_list flist;
- return (*r.first)(flist);
+ return (*boost::get<0>(r))(flist);
             }
             throw identifier_not_found(name);
             return function();
@@ -201,8 +216,8 @@
         {
             environment local_env(&this->env);
             for (std::size_t i = 0; i < args.size(); ++i)
- local_env.define(args[i], boost::bind(arg, i), args.size());
- return compile(body, local_env, fragments, line, source_file);
+ local_env.define(args[i], boost::bind(arg, i), 0, false);
+ return protect(compile(body, local_env, fragments, line, source_file));
         }
 
         function define_function(
@@ -216,8 +231,8 @@
                     throw duplicate_identifier(name);
                 fragments.push_back(function());
                 function& f = fragments.back();
- env.define(name, external_function(f), args.size());
- f = make_lambda(args, body);
+ env.define(name, external_function(f), args.size(), true); // $$$ fixed arity for now $$$
+ f = make_lambda(args, body)(); // unprotect (evaluate returns a function)
                 return f;
             }
             catch (compilation_error const&)
@@ -266,6 +281,8 @@
                         Iterator ai = arg_names.begin();
                         while (ai != arg_names.end())
                             args.push_back(get_symbol(*ai++));
+
+ return define_function(fname, args, (*i)[2]);
                     }
                 }
 
@@ -285,8 +302,8 @@
             }
 
             // (f x)
- std::pair<compiled_function*, int> r = env.find(name);
- if (r.first)
+ boost::tuple<compiled_function*, int, bool> r = env.find(name);
+ if (boost::get<0>(r))
             {
                 actor_list flist;
                 Iterator i = range.begin(); ++i;
@@ -295,17 +312,17 @@
                         compile(*i, env, fragments, line, source_file));
 
                 // Arity check
- if (r.second < 0) // non-fixed arity
+ if (!boost::get<2>(r)) // non-fixed arity
                 {
- if (int(flist.size()) < -r.second)
- throw incorrect_arity(name);
+ if (int(flist.size()) < boost::get<1>(r))
+ throw incorrect_arity(name, boost::get<1>(r), false);
                 }
                 else // fixed arity
                 {
- if (int(flist.size()) != r.second)
- throw incorrect_arity(name);
+ if (int(flist.size()) != boost::get<1>(r))
+ throw incorrect_arity(name, boost::get<1>(r), true);
                 }
- return (*r.first)(flist);
+ return (*boost::get<0>(r))(flist);
             }
             else
             {
@@ -382,12 +399,13 @@
 
     void build_basic_environment(environment& env)
     {
- env.define("if", if_, 3);
- env.define("<", less_than, 2);
- env.define("<=", less_than_equal, 2);
- env.define("+", plus, -2);
- env.define("-", minus, -2);
- env.define("*", times, -2);
+ env.define("if", if_, 3, true);
+ env.define("display", display, 1, true);
+ env.define("<", less_than, 2, true);
+ env.define("<=", less_than_equal, 2, true);
+ env.define("+", plus, 2, false);
+ env.define("-", minus, 2, false);
+ env.define("*", times, 2, false);
     }
 
     ///////////////////////////////////////////////////////////////////////////

Modified: trunk/libs/spirit/example/scheme/scheme/interpreter.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/interpreter.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/interpreter.hpp 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
@@ -138,6 +138,11 @@
 
     value const val = {};
 
+ inline function protect(function const& f)
+ {
+ return val(f.f);
+ }
+
     ///////////////////////////////////////////////////////////////////////////
     // arguments
     ///////////////////////////////////////////////////////////////////////////
@@ -148,7 +153,10 @@
 
         utree eval(args_type args) const
         {
- return utree(boost::ref(args[n]));
+ if (args[n].which() != utree_type::function_type)
+ return utree(boost::ref(args[n]));
+ else
+ return args[n].eval(args);
         }
     };
 

Modified: trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp 2010-04-21 10:02:07 EDT (Wed, 21 Apr 2010)
@@ -149,6 +149,24 @@
 
     struct times_composite : nary_composite<times_function> {};
     times_composite const times = times_composite();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // display
+ ///////////////////////////////////////////////////////////////////////////
+ struct display_function : unary_function<display_function>
+ {
+ display_function(function const& a)
+ : base_type(a) {}
+
+ utree eval(utree const& element) const
+ {
+ std::cout << element;
+ return utree();
+ }
+ };
+
+ struct display_composite : unary_composite<display_function> {};
+ display_composite const display = display_composite();
 }
 
 #endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk