diff options
author | John Wiegley <johnw@newartisans.com> | 2009-02-08 21:17:23 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-02-08 21:17:23 -0400 |
commit | e0b108ff3a64ae76d9fa420b35e35f77f30a54e0 (patch) | |
tree | 0e624d7bcb1fab855c8016f43f5c83e9872af352 /python | |
parent | 623c57a623eae8e2e79af7bfe1680e507e5d333c (diff) | |
download | fork-ledger-e0b108ff3a64ae76d9fa420b35e35f77f30a54e0.tar.gz fork-ledger-e0b108ff3a64ae76d9fa420b35e35f77f30a54e0.tar.bz2 fork-ledger-e0b108ff3a64ae76d9fa420b35e35f77f30a54e0.zip |
Attribute lookup on a Value object which is a Scope now searches the scope.
Diffstat (limited to 'python')
-rw-r--r-- | python/py_expr.cc | 68 | ||||
-rw-r--r-- | python/py_scope.cc | 52 | ||||
-rw-r--r-- | python/py_value.cc | 42 |
3 files changed, 125 insertions, 37 deletions
diff --git a/python/py_expr.cc b/python/py_expr.cc new file mode 100644 index 00000000..047fd2bc --- /dev/null +++ b/python/py_expr.cc @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003-2009, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pyinterp.h" +#include "pyutils.h" +#include "expr.h" + +namespace ledger { + +using namespace boost::python; + +namespace { + value_t py_expr_call(expr_t& expr) + { + return expr.calc(); + } +} + +void export_expr() +{ + class_< expr_t > ("Expr") + .def(init<string>()) + + .def("__nonzero__", &expr_t::operator bool) + .def("text", &expr_t::text) + .def("set_text", &expr_t::set_text) + + //.def("parse", &expr_t::parse) + + .def("__call__", py_expr_call) + .def("compile", &expr_t::compile) + //.def("calc", &expr_t::calc) + + .def("is_constant", &expr_t::is_constant) + + //.def("constant_value", &expr_t::constant_value) + ; +} + +} // namespace ledger diff --git a/python/py_scope.cc b/python/py_scope.cc index e4eef37d..51a72c59 100644 --- a/python/py_scope.cc +++ b/python/py_scope.cc @@ -37,36 +37,42 @@ namespace ledger { using namespace boost::python; -#define EXC_TRANSLATOR(type) \ - void exc_translate_ ## type(const type& err) { \ - PyErr_SetString(PyExc_ArithmeticError, err.what()); \ +namespace { + void py_scope_define(scope_t& scope, const string& name, expr_t& def) + { + return scope.define(name, def.get_op()); } -//EXC_TRANSLATOR(scope_error) + expr_t py_scope_lookup(scope_t& scope, const string& name) + { + return scope.lookup(name); + } -void export_scope() -{ -#if 0 - class_< scope_t > ("Scope") - ; - class_< child_scope_t > ("ChildScope") - ; - class_< symbol_scope_t > ("SymbolScope") - ; - class_< call_scope_t > ("CallScope") - ; - class_< bind_scope_t > ("BindScope") - ; -#endif + expr_t py_scope_getattr(scope_t& scope, const string& name) + { + return scope.lookup(name); + } - //register_optional_to_python<amount_t>(); + struct scope_wrapper : public scope_t + { + PyObject * self; - //implicitly_convertible<string, amount_t>(); + scope_wrapper(PyObject * self_) : self(self_) {} -#define EXC_TRANSLATE(type) \ - register_exception_translator<type>(&exc_translate_ ## type); + virtual expr_t::ptr_op_t lookup(const string& name) { + return NULL; + } + }; +} - //EXC_TRANSLATE(scope_error); +void export_scope() +{ + class_< scope_t, scope_wrapper, boost::noncopyable > ("Scope", no_init) + .def("define", py_scope_define) + .def("lookup", py_scope_lookup) + .def("resolve", &scope_t::resolve) + .def("__getattr__", py_scope_getattr) + ; } } // namespace ledger diff --git a/python/py_value.cc b/python/py_value.cc index f4fe11bc..4962f182 100644 --- a/python/py_value.cc +++ b/python/py_value.cc @@ -39,28 +39,40 @@ using namespace boost::python; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(value_overloads, value, 0, 2) -string py_dump(const value_t& value) { - std::ostringstream buf; - value.dump(buf); - return buf.str(); -} +namespace { + expr_t py_value_getattr(value_t& value, const string& name) + { + if (value.is_pointer()) { + if (scope_t * scope = value.as_pointer_lval<scope_t>()) + return expr_t(scope->lookup(name), scope); + } + throw_(value_error, "Cannot lookup attributes in " << value.label()); + return expr_t(); + } -string py_dump_relaxed(const value_t& value) { - std::ostringstream buf; - value.dump(buf, true); - return buf.str(); -} + string py_dump(const value_t& value) { + std::ostringstream buf; + value.dump(buf); + return buf.str(); + } -void py_set_string(value_t& amount, const string& str) { - return amount.set_string(str); -} + string py_dump_relaxed(const value_t& value) { + std::ostringstream buf; + value.dump(buf, true); + return buf.str(); + } + + void py_set_string(value_t& amount, const string& str) { + return amount.set_string(str); + } #define EXC_TRANSLATOR(type) \ void exc_translate_ ## type(const type& err) { \ PyErr_SetString(PyExc_ArithmeticError, err.what()); \ } -EXC_TRANSLATOR(value_error) + EXC_TRANSLATOR(value_error) +} void export_value() { @@ -262,6 +274,8 @@ void export_value() .def("print", &value_t::print) .def("valid", &value_t::valid) + + .def("__getattr__", py_value_getattr) ; enum_< value_t::type_t >("ValueType") |