fixed support for multiple argument passing to Python functions
This commit is contained in:
parent
8c8c9a01e7
commit
f84f8dbd5d
3 changed files with 53 additions and 18 deletions
|
|
@ -2200,7 +2200,7 @@ it demonstrates the potential for more complex extensions:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
!python
|
!python
|
||||||
from ledger import *
|
import ledger
|
||||||
def foo(d, val):
|
def foo(d, val):
|
||||||
return d.xact.amount + val
|
return d.xact.amount + val
|
||||||
!end
|
!end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
!python
|
||||||
|
def foo(d, val, x):
|
||||||
|
return d.xact.amount + val
|
||||||
|
!end
|
||||||
|
|
||||||
|
--amount-expr 'foo'({$100}, 20)
|
||||||
|
|
||||||
2004/05/01 Checking balance
|
2004/05/01 Checking balance
|
||||||
Assets:Checking $500.00
|
Assets:Checking $500.00
|
||||||
Equity:Opening Balances
|
Equity:Opening Balances
|
||||||
|
|
|
||||||
32
valexpr.cc
32
valexpr.cc
|
|
@ -287,15 +287,39 @@ void value_expr_t::compute(value_t& result, const details_t& details) const
|
||||||
try {
|
try {
|
||||||
object func = python_interpretor->main_namespace[constant_s];
|
object func = python_interpretor->main_namespace[constant_s];
|
||||||
if (right) {
|
if (right) {
|
||||||
|
if (right->right) {
|
||||||
|
list args;
|
||||||
|
args.append(details);
|
||||||
|
for (value_expr_t * arg = right; arg; arg = arg->right) {
|
||||||
|
assert(arg->kind == O_ARG);
|
||||||
|
arg->left->compute(result, details);
|
||||||
|
args.append(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * val = PyObject_CallObject(func.ptr(), tuple(args).ptr());
|
||||||
|
if (val) {
|
||||||
|
result = extract<value_t>(val)();
|
||||||
|
Py_DECREF(val);
|
||||||
|
}
|
||||||
|
else if (PyObject * err = PyErr_Occurred()) {
|
||||||
|
PyErr_Print();
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
assert(right->kind == O_ARG);
|
assert(right->kind == O_ARG);
|
||||||
right->left->compute(result, details);
|
right->left->compute(result, details);
|
||||||
result = call<value_t>(func.ptr(), details, result);
|
result = call<value_t>(func.ptr(), details, result);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
result = call<value_t>(func.ptr(), details);
|
result = call<value_t>(func.ptr(), details);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(const boost::python::error_already_set&) {
|
catch(const boost::python::error_already_set&) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
@ -542,8 +566,9 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node.reset(new value_expr_t(value_expr_t::F_INTERP_FUNC));
|
node.reset(new value_expr_t(value_expr_t::F_INTERP_FUNC));
|
||||||
node->constant_s = buf;
|
node->constant_s = buf;
|
||||||
if (peek_next_nonws(in) == '(') {
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
|
if (! in.eof()) {
|
||||||
|
if (c == '(') {
|
||||||
node->right = new value_expr_t(value_expr_t::O_ARG);
|
node->right = new value_expr_t(value_expr_t::O_ARG);
|
||||||
value_expr_t * cur = node->right;
|
value_expr_t * cur = node->right;
|
||||||
cur->left = parse_value_expr(in, true);
|
cur->left = parse_value_expr(in, true);
|
||||||
|
|
@ -557,7 +582,10 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
if (c != ')')
|
if (c != ')')
|
||||||
unexpected(c, ')');
|
unexpected(c, ')');
|
||||||
} else {
|
} else {
|
||||||
node->left = parse_value_term(in);
|
in.unget();
|
||||||
|
node->right = new value_expr_t(value_expr_t::O_ARG);
|
||||||
|
node->right->left = parse_value_term(in);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue