|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61240 - in trunk/libs/spirit/example/scheme: . test
From: joel_at_[hidden]
Date: 2010-04-13 08:53:07
Author: djowel
Date: 2010-04-13 08:53:06 EDT (Tue, 13 Apr 2010)
New Revision: 61240
URL: http://svn.boost.org/trac/boost/changeset/61240
Log:
updates
Text files modified:
trunk/libs/spirit/example/scheme/scheme_compiler.hpp | 47 +++++++++++++--------
trunk/libs/spirit/example/scheme/scheme_interpreter.hpp | 11 ++--
trunk/libs/spirit/example/scheme/scheme_intinsics.hpp | 38 ++++++++++++++--
trunk/libs/spirit/example/scheme/test/utree_test.cpp | 87 ++++++++++++++++++++-------------------
4 files changed, 111 insertions(+), 72 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-13 08:53:06 EDT (Tue, 13 Apr 2010)
@@ -55,11 +55,12 @@
std::map<std::string, compiled_function> definitions;
};
- actor compile(utree const& ast, environment& env, actor_list& fragments);
-
///////////////////////////////////////////////////////////////////////////////
// The compiler
///////////////////////////////////////////////////////////////////////////////
+ actor compile(
+ utree const& ast, environment& env, actor_list& fragments);
+
struct external_function : composite<external_function>
{
// we must hold f by reference because functions can be recursive
@@ -78,9 +79,9 @@
struct compiler
{
typedef actor result_type;
-
environment& env;
actor_list& fragments;
+
compiler(environment& env, actor_list& fragments)
: env(env), fragments(fragments)
{
@@ -109,60 +110,69 @@
return actor();
}
- void define_function(
- std::string const& name,
+ actor make_lambda(
std::vector<std::string> const& args,
utree const& body) const
{
environment local_env(&this->env);
for (std::size_t i = 0; i < args.size(); ++i)
local_env.define(args[i], boost::bind(arg, i));
-
- fragments.push_back(actor());
- actor& f = fragments.back();
- env.define(name, external_function(f));
- f = compile(body, local_env, fragments);
+ return compile(body, local_env, fragments);
}
- void define_nullary_function(
+ void define_function(
std::string const& name,
+ std::vector<std::string> const& args,
utree const& body) const
{
fragments.push_back(actor());
actor& f = fragments.back();
env.define(name, external_function(f));
- f = compile(body, env, fragments);
+ f = make_lambda(args, body);
}
template <typename Iterator>
actor operator()(boost::iterator_range<Iterator> const& range) const
{
std::string name(get_symbol(*range.begin()));
- std::string fname;
if (name == "define")
{
+ std::string fname;
+ std::vector<std::string> args;
+
Iterator i = range.begin(); ++i;
if (i->which() == utree_type::list_type)
{
- // a function
+ // (define (f x) ...body...)
utree const& decl = *i++;
Iterator di = decl.begin();
fname = get_symbol(*di++);
- std::vector<std::string> args;
while (di != decl.end())
args.push_back(get_symbol(*di++));
- define_function(fname, args, *i);
}
else
{
- // constants (nullary functions)
+ // (define f ...body...)
fname = get_symbol(*i++);
- define_nullary_function(fname, *i);
}
+
+ define_function(fname, args, *i);
return actor(val(utf8_symbol("<define " + fname + ">")));
}
+ if (name == "lambda")
+ {
+ // (lambda (x) ...body...)
+ Iterator i = range.begin(); ++i;
+ utree const& arg_names = *i++;
+ Iterator ai = arg_names.begin();
+ std::vector<std::string> args;
+ while (ai != arg_names.end())
+ args.push_back(get_symbol(*ai++));
+ return make_lambda(args, *i);
+ }
+
if (compiled_function* mf = env.find(name))
{
actor_list flist;
@@ -204,6 +214,7 @@
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);
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-13 08:53:06 EDT (Tue, 13 Apr 2010)
@@ -272,14 +272,14 @@
};
///////////////////////////////////////////////////////////////////////////
- // vararg_function
+ // nary_function
///////////////////////////////////////////////////////////////////////////
template <typename Derived>
- struct vararg_function : composite<Derived>
+ struct nary_function : composite<Derived>
{
- typedef vararg_function<Derived> base_type;
+ typedef nary_function<Derived> base_type;
actor_list elements;
- vararg_function(actor_list const& elements)
+ nary_function(actor_list const& elements)
: elements(elements) {}
using composite<Derived>::operator();
@@ -291,7 +291,8 @@
rest(i++, elements.end());
BOOST_FOREACH(actor const& element, rest)
{
- derived().eval(result, element(args));
+ if (!derived().eval(result, element(args)))
+ break; // allow short-circuit evaluation
}
return result;
}
Modified: trunk/libs/spirit/example/scheme/scheme_intinsics.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_intinsics.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme_intinsics.hpp 2010-04-13 08:53:06 EDT (Tue, 13 Apr 2010)
@@ -46,6 +46,29 @@
if_composite const if_ = if_composite();
///////////////////////////////////////////////////////////////////////////
+ // less_than
+ ///////////////////////////////////////////////////////////////////////////
+ struct less_than_function
+ : binary_function<less_than_function>
+ {
+ less_than_function(actor const& a, actor const& b)
+ : base_type(a, b) {}
+
+ typedef utree result_type;
+ utree eval(utree const& a, utree const& b) const
+ {
+ return a < b;
+ }
+ };
+
+ struct less_than_composite
+ : binary_composite<less_than_function> {};
+
+ less_than_composite const less_than
+ = less_than_composite();
+ less_than_composite const lt = less_than; // synonym
+
+ ///////////////////////////////////////////////////////////////////////////
// less_than_equal
///////////////////////////////////////////////////////////////////////////
struct less_than_equal_function
@@ -71,14 +94,15 @@
///////////////////////////////////////////////////////////////////////////
// plus
///////////////////////////////////////////////////////////////////////////
- struct plus_function : vararg_function<plus_function>
+ struct plus_function : nary_function<plus_function>
{
plus_function(actor_list const& elements)
: base_type(elements) {}
- void eval(utree& result, utree const& element) const
+ bool eval(utree& result, utree const& element) const
{
result = result + element;
+ return true;
}
};
@@ -88,14 +112,15 @@
///////////////////////////////////////////////////////////////////////////
// minus
///////////////////////////////////////////////////////////////////////////
- struct minus_function : vararg_function<minus_function>
+ struct minus_function : nary_function<minus_function>
{
minus_function(actor_list const& elements)
: base_type(elements) {}
- void eval(utree& result, utree const& element) const
+ bool eval(utree& result, utree const& element) const
{
result = result - element;
+ return true;
}
};
@@ -105,14 +130,15 @@
///////////////////////////////////////////////////////////////////////////
// times
///////////////////////////////////////////////////////////////////////////
- struct times_function : vararg_function<times_function>
+ struct times_function : nary_function<times_function>
{
times_function(actor_list const& elements)
: base_type(elements) {}
- void eval(utree& result, utree const& element) const
+ bool eval(utree& result, utree const& element) const
{
result = result * element;
+ return true;
}
};
Modified: trunk/libs/spirit/example/scheme/test/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/utree_test.cpp 2010-04-13 08:53:06 EDT (Tue, 13 Apr 2010)
@@ -9,6 +9,7 @@
#include "../utree.hpp"
#include "../utree_operators.hpp"
+#include "../utree_io.hpp"
#include <iostream>
inline std::ostream& println(std::ostream& out, scheme::utree const& val)
@@ -23,49 +24,49 @@
{
using scheme::utree;
- //~ {
- //~ // test the size
- //~ std::cout << "size of utree is: "
- //~ << sizeof(scheme::utree) << " bytes" << std::endl;
- //~ }
-
- //~ {
- //~ utree val;
- //~ println(std::cout, val);
- //~ }
-
- //~ {
- //~ utree val(true);
- //~ println(std::cout, val);
- //~ }
-
- //~ {
- //~ utree val(123);
- //~ println(std::cout, val);
- //~ }
-
- //~ {
- //~ utree val(123.456);
- //~ println(std::cout, val);
- //~ }
-
- //~ {
- //~ utree val("Hello, World");
- //~ println(std::cout, val);
- //~ utree val2;
- //~ val2 = val;
- //~ println(std::cout, val2);
- //~ utree val3("Hello, World. Chuckie is back!!!");
- //~ val = val3;
- //~ println(std::cout, val);
-
- //~ utree val4("Apple");
- //~ utree val5("Apple");
- //~ BOOST_ASSERT(val4 == val5);
-
- //~ utree val6("ApplePie");
- //~ BOOST_ASSERT(val4 < val6);
- //~ }
+ {
+ // test the size
+ std::cout << "size of utree is: "
+ << sizeof(scheme::utree) << " bytes" << std::endl;
+ }
+
+ {
+ utree val;
+ println(std::cout, val);
+ }
+
+ {
+ utree val(true);
+ println(std::cout, val);
+ }
+
+ {
+ utree val(123);
+ println(std::cout, val);
+ }
+
+ {
+ utree val(123.456);
+ println(std::cout, val);
+ }
+
+ {
+ utree val("Hello, World");
+ println(std::cout, val);
+ utree val2;
+ val2 = val;
+ println(std::cout, val2);
+ utree val3("Hello, World. Chuckie is back!!!");
+ val = val3;
+ println(std::cout, val);
+
+ utree val4("Apple");
+ utree val5("Apple");
+ BOOST_ASSERT(val4 == val5);
+
+ utree val6("ApplePie");
+ BOOST_ASSERT(val4 < val6);
+ }
{
utree val;
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