summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-08 21:17:23 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-08 21:17:23 -0400
commite0b108ff3a64ae76d9fa420b35e35f77f30a54e0 (patch)
tree0e624d7bcb1fab855c8016f43f5c83e9872af352 /python
parent623c57a623eae8e2e79af7bfe1680e507e5d333c (diff)
downloadfork-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.cc68
-rw-r--r--python/py_scope.cc52
-rw-r--r--python/py_value.cc42
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")