|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61151 - in trunk/libs/spirit/example/scheme: detail test
From: joel_at_[hidden]
Date: 2010-04-09 03:34:56
Author: djowel
Date: 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
New Revision: 61151
URL: http://svn.boost.org/trac/boost/changeset/61151
Log:
+ bug fixes
+ working define function
Text files modified:
trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp | 33 +++++--
trunk/libs/spirit/example/scheme/test/scheme.cpp | 155 ++++++++++++++++++++++++++++++++++++---
trunk/libs/spirit/example/scheme/test/utree_test.cpp | 96 +++++++++++++-----------
3 files changed, 216 insertions(+), 68 deletions(-)
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -127,8 +127,11 @@
node_iterator()
: node(0) {}
- explicit node_iterator(list::node* p)
- : node(p) {}
+ explicit node_iterator(list::node* node)
+ : node(node), prev(node->prev) {}
+
+ node_iterator(list::node* node, list::node* prev)
+ : node(node), prev(prev) {}
private:
@@ -137,12 +140,20 @@
void increment()
{
- node = node->next;
+ if (node != 0) // not at end
+ {
+ prev = node;
+ node = node->next;
+ }
}
void decrement()
{
- node = node->prev;
+ if (prev != 0) // not at begin
+ {
+ node = prev;
+ prev = prev->prev;
+ }
}
bool equal(node_iterator const& other) const
@@ -156,6 +167,7 @@
}
list::node* node;
+ list::node* prev;
};
inline void list::free()
@@ -350,7 +362,7 @@
return f(x.d);
case type::list_type:
- return f(list_range(iterator(x.l.first), iterator(0)));
+ return f(list_range(iterator(x.l.first), iterator(0, x.l.last)));
case type::string_type:
return f(utf8_string_range(x.s.str(), x.s.size()));
@@ -403,7 +415,7 @@
case type::list_type:
return visit_impl::apply(
y, detail::bind<F, list_range>(f,
- list_range(iterator(x.l.first), iterator(0))));
+ list_range(iterator(x.l.first), iterator(0, x.l.last))));
case type::string_type:
return visit_impl::apply(y, detail::bind(
@@ -683,7 +695,7 @@
if (get_type() == type::reference_type)
return p->insert(pos, val);
ensure_list_type();
- if (pos.node == l.last)
+ if (pos == end())
{
push_back(val);
return begin();
@@ -756,7 +768,8 @@
if (get_type() == type::reference_type)
return p->erase(pos);
BOOST_ASSERT(get_type() == type::list_type);
- return iterator(l.erase(pos.node));
+ detail::list::node* np = l.erase(pos.node);
+ return iterator(np, np?np->prev:l.last);
}
inline utree::iterator utree::erase(iterator first, iterator last)
@@ -781,7 +794,7 @@
if (get_type() == type::reference_type)
return p->end();
ensure_list_type();
- return iterator(l.last);
+ return iterator(0, l.last);
}
inline utree::const_iterator utree::begin() const
@@ -797,7 +810,7 @@
if (get_type() == type::reference_type)
return ((utree const*)p)->end();
BOOST_ASSERT(get_type() == type::list_type);
- return const_iterator(l.last);
+ return const_iterator(0, l.last);
}
inline bool utree::empty() const
Modified: trunk/libs/spirit/example/scheme/test/scheme.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme.cpp 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -26,6 +26,15 @@
namespace scheme
{
///////////////////////////////////////////////////////////////////////////////
+// Utilities
+///////////////////////////////////////////////////////////////////////////////
+ inline std::string get_symbol(utree const& s)
+ {
+ utf8_symbol_range symbol = s.as<utf8_symbol_range>();
+ return std::string(symbol.begin(), symbol.end());
+ }
+
+///////////////////////////////////////////////////////////////////////////////
// The runtime interpreter
///////////////////////////////////////////////////////////////////////////////
@@ -72,6 +81,19 @@
return function(argument_impl(n));
}
+ struct make_arg
+ {
+ int n;
+ make_arg(int n) : n(n) {}
+
+ typedef function result_type;
+ function operator()(function_list& operands)
+ {
+ // check arity here!
+ return function(argument_impl(n));
+ }
+ };
+
///////////////////////////////////////////////////////////////////////////
// reference
///////////////////////////////////////////////////////////////////////////
@@ -129,6 +151,49 @@
make_plus const plus = {};
+ ///////////////////////////////////////////////////////////////////////////
+ // fcall
+ ///////////////////////////////////////////////////////////////////////////
+ struct fcall_impl
+ {
+ function f;
+ function_list operands;
+
+ fcall_impl(function const& f, function_list& operands_)
+ : f(f)
+ {
+ // we take ownership of the operands
+ operands_.swap(operands);
+ }
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ utree fargs;
+ BOOST_FOREACH(function const& operand, operands)
+ {
+ fargs.push_back(operand(args));
+ }
+ return f(fargs);
+ }
+ };
+
+ struct make_fcall
+ {
+ function f;
+ int arity;
+ make_fcall(function const& f, int arity)
+ : f(f), arity(arity) {}
+
+ typedef function result_type;
+ function operator()(function_list& operands)
+ {
+ // $$$ use throw $$$
+ BOOST_ASSERT(operands.size() == arity);
+ return function(fcall_impl(f, operands));
+ }
+ };
+
///////////////////////////////////////////////////////////////////////////////
// The compiler
///////////////////////////////////////////////////////////////////////////////
@@ -136,7 +201,8 @@
struct compiler_environment
{
- compiler_environment() {}
+ compiler_environment(compiler_environment* parent = 0)
+ : parent(parent) {}
void define(std::string const& name, make_function const& def)
{
@@ -151,9 +217,12 @@
i = definitions.find(name);
if (i != definitions.end())
return &i->second;
+ else if (parent != 0)
+ return parent->find(name);
return 0;
}
+ compiler_environment* parent;
std::map<std::string, make_function> definitions;
};
@@ -163,9 +232,12 @@
{
typedef function result_type;
- compiler_environment& env;
- compiler(compiler_environment& env)
- : env(env) {}
+ mutable compiler_environment* env;
+ compiler(compiler_environment* env)
+ : env(env)
+ {
+ BOOST_ASSERT(env != 0);
+ }
function operator()(nil) const
{
@@ -180,20 +252,71 @@
function operator()(utf8_symbol_range const& str) const
{
- return function(); // $$$ implement me $$$
+ std::string name(str.begin(), str.end());
+
+ if (make_function* mf = env->find(name))
+ {
+ function_list flist;
+ return (*mf)(flist);
+ }
+ // $$$ throw? $$$
+ return function();
+ }
+
+ void define_function(
+ std::string const& name,
+ std::vector<std::string> const& args,
+ utree const& body) const
+ {
+ compiler_environment local_env(env);
+ for (std::size_t i = 0; i < args.size(); ++i)
+ local_env.define(args[i], make_arg(i));
+ make_fcall mf(compile(body, local_env), args.size());
+ env->define(name, make_function(mf));
}
template <typename Iterator>
function operator()(boost::iterator_range<Iterator> const& range) const
{
- utf8_symbol_range symbol = range.begin()->as<utf8_symbol_range>();
- std::string fname(symbol.begin(), symbol.end());
- if (make_function* mf = env.find(fname))
+ //~ if (range.begin()->which() == utree_type::list_type)
+ //~ BOOST_FOREACH(utree const& x, range)
+ //~ {
+ //~ compile()
+ //~ }
+
+ std::string name(get_symbol(*range.begin()));
+
+ if (name == "define")
+ {
+ Iterator i = range.begin(); ++i;
+ if (i->which() == utree_type::list_type)
+ {
+ // a function
+ utree const& decl = *i++;
+
+
+ Iterator di = decl.begin();
+ std::string fname(get_symbol(*di++));
+ std::vector<std::string> args;
+ while (di != decl.end())
+ args.push_back(get_symbol(*di++));
+ std::cout << "decl: " << decl << " arity:" << args.size() << std::endl;
+
+ define_function(fname, args, *i);
+ return function();
+ }
+ else
+ {
+ // constants
+ }
+ }
+
+ if (make_function* mf = env->find(name))
{
function_list flist;
Iterator i = range.begin(); ++i;
for (; i != range.end(); ++i)
- flist.push_back(compile(*i, env));
+ flist.push_back(compile(*i, *env));
return (*mf)(flist);
}
@@ -203,7 +326,7 @@
function compile(utree const& ast, compiler_environment& env)
{
- return utree::visit(ast, compiler(env));
+ return utree::visit(ast, compiler(&env));
}
void build_basic_environment(compiler_environment& env)
@@ -218,6 +341,9 @@
int main()
{
std::string in;
+ scheme::compiler_environment env;
+ scheme::build_basic_environment(env);
+
while (std::getline(std::cin, in))
{
if (in.empty() || in[0] == 'q' || in[0] == 'Q')
@@ -232,11 +358,12 @@
iterator_type last = in.end();
if (phrase_parse(first, last, p, ws, result))
{
- std::cout << "success: ";
- scheme::compiler_environment env;
- scheme::build_basic_environment(env);
+ std::cout << "success: expr =" << result;
scheme::function f = compile(result, env);
- std::cout << "result: " << f(scheme::utree()) << std::endl;
+ if (f)
+ std::cout << " result: " << f(scheme::utree()) << std::endl;
+ else
+ std::cout << std::endl;
}
else
{
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-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -13,6 +13,8 @@
inline std::ostream& println(std::ostream& out, scheme::utree const& val)
{
+ if (val.which() == scheme::utree_type::list_type)
+ out << "size:" << val.size() << " ";
out << val << std::endl;
return out;
}
@@ -21,67 +23,71 @@
{
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;
val.push_back(123);
val.push_back("Chuckie");
+ BOOST_ASSERT(val.size() == 2);
utree val2;
val2.push_back(123.456);
val2.push_back("Mah Doggie");
val.push_back(val2);
+ BOOST_ASSERT(val.size() == 3);
println(std::cout, val);
println(std::cout, val.front());
utree val3;
val3.swap(val);
+ BOOST_ASSERT(val3.size() == 3);
println(std::cout, val);
val3.swap(val);
println(std::cout, val);
val.push_back("another string");
+ BOOST_ASSERT(val.size() == 4);
println(std::cout, val);
val.pop_front();
println(std::cout, val);
@@ -93,12 +99,14 @@
val.pop_back();
println(std::cout, val);
BOOST_ASSERT(val.size() == 3);
- val.erase(val.end());
+ utree::iterator it = val.end(); --it;
+ val.erase(it);
println(std::cout, val);
BOOST_ASSERT(val.size() == 2);
val.insert(val.begin(), val2.begin(), val2.end());
println(std::cout, val);
+ BOOST_ASSERT(val.size() == 4);
}
{
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