|
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