Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61350 - in trunk/libs/spirit/example/scheme: scheme test/scheme
From: joel_at_[hidden]
Date: 2010-04-18 06:32:36


Author: djowel
Date: 2010-04-18 06:32:35 EDT (Sun, 18 Apr 2010)
New Revision: 61350
URL: http://svn.boost.org/trac/boost/changeset/61350

Log:
arity checking
Text files modified:
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 56 ++++++++++++++++++++++++++-------------
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp | 1
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.scm | 4 ++
   3 files changed, 41 insertions(+), 20 deletions(-)

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-18 06:32:35 EDT (Sun, 18 Apr 2010)
@@ -47,6 +47,14 @@
         }
     };
 
+ struct incorrect_arity : scheme_exception
+ {
+ virtual const char* what() const throw()
+ {
+ return "scheme: Invalid number of parameters to function call";
+ }
+ };
+
 ///////////////////////////////////////////////////////////////////////////////
 // The environment
 ///////////////////////////////////////////////////////////////////////////////
@@ -60,30 +68,33 @@
           : outer(parent) {}
 
         template <typename Function>
- void define(std::string const& name, Function const& f)
+ void define(std::string const& name, Function const& f, int arity)
         {
             if (definitions.find(name) != definitions.end())
                 throw duplicate_identifier();
- definitions[name] = compiled_function(f);
+ definitions[name] = std::make_pair(compiled_function(f), arity);
         }
 
- compiled_function* find(std::string const& name)
+ std::pair<compiled_function*, int>
+ find(std::string const& name)
         {
- std::map<std::string, compiled_function>::iterator
+ std::map<std::string, map_element>::iterator
                 i = definitions.find(name);
             if (i != definitions.end())
- return &i->second;
+ return std::make_pair(&i->second.first, i->second.second);
             else if (outer != 0)
                 return outer->find(name);
- return 0;
+ return std::make_pair((compiled_function*)0, 0);
         }
 
         environment* parent() const { return outer; }
 
     private:
 
+ typedef std::pair<compiled_function, int> map_element;
+
         environment* outer;
- std::map<std::string, compiled_function> definitions;
+ std::map<std::string, map_element> definitions;
     };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -143,10 +154,11 @@
         function operator()(utf8_symbol_range const& str) const
         {
             std::string name(str.begin(), str.end());
- if (compiled_function* mf = env.find(name))
+ std::pair<compiled_function*, int> r = env.find(name);
+ if (r.first)
             {
                 actor_list flist;
- return (*mf)(flist);
+ return (*r.first)(flist);
             }
             throw identifier_not_found();
             return function();
@@ -158,7 +170,7 @@
         {
             environment local_env(&this->env);
             for (std::size_t i = 0; i < args.size(); ++i)
- local_env.define(args[i], boost::bind(arg, i));
+ local_env.define(args[i], boost::bind(arg, i), args.size());
             return compile(body, local_env, fragments, line, source_file);
         }
 
@@ -169,7 +181,7 @@
         {
             fragments.push_back(function());
             function& f = fragments.back();
- env.define(name, external_function(f));
+ env.define(name, external_function(f), 0);
             f = make_lambda(args, body);
             return f;
         }
@@ -217,14 +229,20 @@
                     return make_lambda(args, *i);
                 }
 
- if (compiled_function* mf = env.find(name))
+ // (f x)
+ std::pair<compiled_function*, int> r = env.find(name);
+ if (r.first)
                 {
                     actor_list flist;
                     Iterator i = range.begin(); ++i;
                     for (; i != range.end(); ++i)
                         flist.push_back(
                             compile(*i, env, fragments, line, source_file));
- return (*mf)(flist);
+
+ // Arity check
+ if (r.second != -1 && int(flist.size()) < r.second)
+ throw incorrect_arity();
+ return (*r.first)(flist);
                 }
 
                 throw unknown_expression();
@@ -283,12 +301,12 @@
 
     void build_basic_environment(environment& env)
     {
- env.define("if", if_);
- env.define("<", less_than);
- env.define("<=", less_than_equal);
- env.define("+", plus);
- env.define("-", minus);
- env.define("*", times);
+ env.define("if", if_, 3);
+ env.define("<", less_than, 2);
+ env.define("<=", less_than_equal, 2);
+ env.define("+", plus, -1);
+ env.define("-", minus, -1);
+ env.define("*", times, -1);
     }
 
     ///////////////////////////////////////////////////////////////////////////

Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp 2010-04-18 06:32:35 EDT (Sun, 18 Apr 2010)
@@ -76,6 +76,7 @@
     BOOST_TEST((*i++)() == 3628800);
     BOOST_TEST((*i++)(5) == 5);
     BOOST_TEST((*i++)() == 55);
+ BOOST_TEST((*i++)() == 21);
 
     return boost::report_errors();
 }

Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.scm
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.scm (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.scm 2010-04-18 06:32:35 EDT (Sun, 18 Apr 2010)
@@ -21,4 +21,6 @@
         n
         (+ (fib (- n 1)) (fib (- n 2))))))
 
-(fib 10) ; 55
\ No newline at end of file
+(fib 10) ; 55
+
+(+ 1 2 3 4 5 6) ; 21 varargs
\ No newline at end of file


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