summaryrefslogtreecommitdiff
path: root/src/op.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-07 21:22:07 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-07 21:22:07 -0600
commitae4ef7a88ddd39ed544383e65d3c55ba97f4f8c1 (patch)
tree53935489e3a30d1e4a501bd10bd2fb8e607f57f7 /src/op.cc
parente7de77d8dfc764fd3764dc45d397d5f8454414be (diff)
downloadfork-ledger-ae4ef7a88ddd39ed544383e65d3c55ba97f4f8c1.tar.gz
fork-ledger-ae4ef7a88ddd39ed544383e65d3c55ba97f4f8c1.tar.bz2
fork-ledger-ae4ef7a88ddd39ed544383e65d3c55ba97f4f8c1.zip
More work done on proper evaluation of lambdas
Diffstat (limited to 'src/op.cc')
-rw-r--r--src/op.cc42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/op.cc b/src/op.cc
index a5db1690..6a1a8f54 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -155,23 +155,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth,
node->set_left(left()->right());
node->set_right(right());
- symbol_scope_t params(param_scope ?
- *param_scope : *scope_t::empty_scope);
- for (ptr_op_t sym = node->left();
- sym;
- sym = sym->has_right() ? sym->right() : NULL) {
- ptr_op_t varname = sym->kind == O_CONS ? sym->left() : sym;
- if (! varname->is_ident()) {
- throw_(calc_error, _("Invalid function definition"));
- } else {
- DEBUG("expr.compile",
- "Defining function parameter " << varname->as_ident());
- params.define(symbol_t::FUNCTION, varname->as_ident(),
- new op_t(op_t::PLUG));
- }
- }
-
- node = node->compile(*scope_ptr, depth + 1, &params);
+ node = node->compile(*scope_ptr, depth + 1, param_scope);
DEBUG("expr.compile",
"Defining " << left()->left()->as_ident() << " in " << scope_ptr);
@@ -185,6 +169,30 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth,
}
result = wrap_value(NULL_VALUE);
}
+ else if (kind == O_LAMBDA) {
+ symbol_scope_t params(param_scope ? *param_scope : *scope_t::empty_scope);
+
+ for (ptr_op_t sym = left();
+ sym;
+ sym = sym->has_right() ? sym->right() : NULL) {
+ ptr_op_t varname = sym->kind == O_CONS ? sym->left() : sym;
+
+ if (! varname->is_ident()) {
+ throw_(calc_error, _("Invalid function or lambda parameter"));
+ } else {
+ DEBUG("expr.compile",
+ "Defining function parameter " << varname->as_ident());
+ params.define(symbol_t::FUNCTION, varname->as_ident(),
+ new op_t(PLUG));
+ }
+ }
+
+ ptr_op_t rhs(right()->compile(*scope_ptr, depth + 1, &params));
+ if (rhs == right())
+ result = this;
+ else
+ result = copy(left(), rhs);
+ }
if (! result) {
ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1, param_scope));