From bc9ff7095fbfa1812e4f47dbf8531dec76cd0d00 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 20 Feb 2012 17:20:16 -0600 Subject: Introduced a new SCOPE expression terminal --- src/op.cc | 93 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 36 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 537f5371..d5a589c8 100644 --- a/src/op.cc +++ b/src/op.cc @@ -50,7 +50,7 @@ namespace { expr_t::ptr_op_t value_op; if (next->kind == expr_t::op_t::O_CONS) { value_op = next->left(); - next = next->right(); + next = next->has_right() ? next->right() : NULL; } else { value_op = next; next = NULL; @@ -78,10 +78,12 @@ namespace { expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) { + scope_t * scope_ptr = &scope; + if (is_ident()) { DEBUG("expr.compile", "lookup: " << as_ident()); - if (ptr_op_t def = scope.lookup(symbol_t::FUNCTION, as_ident())) { + if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) { // Identifier references are first looked up at the point of // definition, and then at the point of every use if they could // not be found there. @@ -91,21 +93,26 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) def->dump(*_log_stream, 0); } #endif // defined(DEBUG_ON) - return copy(def); + return copy(def); } else if (left()) { return copy(); } return this; } - - if (kind < TERMINALS) + else if (is_scope()) { + shared_ptr subscope(new symbol_scope_t(scope)); + DEBUG("expr.compile", "creating scope"); + set_scope(subscope); + scope_ptr = subscope.get(); + } + else if (kind < TERMINALS) { return this; - - if (kind == O_DEFINE) { + } + else if (kind == O_DEFINE) { switch (left()->kind) { case IDENT: - scope.define(symbol_t::FUNCTION, left()->as_ident(), right()); + scope_ptr->define(symbol_t::FUNCTION, left()->as_ident(), right()); break; case O_CALL: if (left()->left()->is_ident()) { @@ -113,7 +120,8 @@ 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()); - scope.define(symbol_t::FUNCTION, left()->left()->as_ident(), node); + scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(), + node); } else { throw_(compile_error, _("Invalid function definition")); } @@ -121,13 +129,13 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) default: throw_(compile_error, _("Invalid function definition")); } - return wrap_value(value_t()); + return wrap_value(NULL_VALUE); } - ptr_op_t lhs(left()->compile(scope, depth)); + ptr_op_t lhs(left()->compile(*scope_ptr, depth)); ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ? (kind == O_LOOKUP ? right() : - right()->compile(scope, depth)) : NULL); + right()->compile(*scope_ptr, depth)) : NULL); if (lhs == left() && (! rhs || rhs == right())) return this; @@ -136,22 +144,19 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) // Reduce constants immediately if possible if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value())) - return wrap_value(intermediate->calc(scope, NULL, depth)); + return wrap_value(intermediate->calc(*scope_ptr, NULL, depth)); return intermediate; } value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) { -#if defined(DEBUG_ON) - bool skip_debug = false; -#endif try { value_t result; #if defined(DEBUG_ON) - if (! skip_debug && SHOW_DEBUG("expr.calc")) { + if (SHOW_DEBUG("expr.calc")) { for (int i = 0; i < depth; i++) ledger::_log_buffer << '.'; ledger::_log_buffer << op_context(this) << " => ..."; @@ -196,12 +201,18 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) call_scope_t call_args(scope, locus, depth); result = as_function()(call_args); check_type_context(scope, result); -#if defined(DEBUG_ON) - skip_debug = true; -#endif break; } + case SCOPE: + if (is_scope_unset()) { + symbol_scope_t subscope(scope); + result = left()->calc(subscope, locus, depth + 1); + } else { + result = left()->calc(*as_scope(), locus, depth + 1); + } + break; + case O_LAMBDA: { call_scope_t& call_args(downcast(scope)); std::size_t args_count(call_args.size()); @@ -267,7 +278,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) throw_(calc_error, _("Calling unknown function '%1'") << name); #if defined(DEBUG_ON) - if (! skip_debug && SHOW_DEBUG("expr.calc")) { + if (SHOW_DEBUG("expr.calc")) { for (int i = 0; i < depth; i++) ledger::_log_buffer << '.'; ledger::_log_buffer << " args: "; @@ -382,7 +393,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) ptr_op_t value_op; if (next->kind == O_CONS) { value_op = next->left(); - next = next->right(); + next = next->has_right() ? next->right() : NULL; } else { value_op = next; next = NULL; @@ -395,14 +406,13 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; case O_SEQ: { - symbol_scope_t seq_scope(scope); - - // An O_SEQ is very similar to an O_CONS except that only the last result - // value in the series is kept. O_CONS builds up a list. + // An O_SEQ is very similar to an O_CONS except that only the last + // result value in the series is kept. O_CONS builds up a list. // - // Another feature of O_SEQ is that it pushes a new symbol scope onto the - // stack. - result = left()->calc(seq_scope, locus, depth + 1); + // Another feature of O_SEQ is that it pushes a new symbol scope + // onto the stack. We evaluate the left side here to catch any + // side-effects, such as definitions in the case of 'x = 1; x'. + result = left()->calc(scope, locus, depth + 1); if (has_right()) { ptr_op_t next = right(); @@ -415,7 +425,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) value_op = next; next = NULL; } - result = value_op->calc(seq_scope, locus, depth + 1); + result = value_op->calc(scope, locus, depth + 1); } } break; @@ -426,7 +436,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) } #if defined(DEBUG_ON) - if (! skip_debug && SHOW_DEBUG("expr.calc")) { + if (SHOW_DEBUG("expr.calc")) { for (int i = 0; i < depth; i++) ledger::_log_buffer << '.'; ledger::_log_buffer << op_context(this) << " => "; @@ -476,9 +486,8 @@ namespace { if (op->has_right()) { out << "; "; - - if (op->right()->kind == expr_t::op_t::O_CONS) - found = print_cons(out, op->right(), context); + if (op->right()->kind == expr_t::op_t::O_SEQ) + found = print_seq(out, op->right(), context); else if (op->right()->print(out, context)) found = true; } @@ -515,6 +524,11 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const out << ""; break; + case SCOPE: + if (left() && left()->print(out, context)) + found = true; + break; + case O_NOT: out << "! "; if (left() && left()->print(out, context)) @@ -625,7 +639,6 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const case O_CONS: found = print_cons(out, this, context); break; - case O_SEQ: found = print_seq(out, this, context); break; @@ -726,6 +739,14 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const out << "FUNCTION"; break; + case SCOPE: + out << "SCOPE: "; + if (is_scope_unset()) + out << "null"; + else + out << as_scope().get(); + break; + case O_DEFINE: out << "O_DEFINE"; break; case O_LOOKUP: out << "O_LOOKUP"; break; case O_LAMBDA: out << "O_LAMBDA"; break; @@ -765,7 +786,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const // An identifier is a special non-terminal, in that its left() can // hold the compiled definition of the identifier. - if (kind > TERMINALS || is_ident()) { + if (kind > TERMINALS || is_ident() || is_scope()) { if (left()) { left()->dump(out, depth + 1); if (kind > UNARY_OPERATORS && has_right()) -- cgit v1.2.3 From 1837e323916c7479623bb61e479407b85edee562 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 21 Feb 2012 01:45:26 -0600 Subject: The new SCOPE mechanism is working --- src/op.cc | 139 ++++++++++++++++++++++++----------------------------------- src/scope.cc | 8 +++- src/scope.h | 2 + 3 files changed, 65 insertions(+), 84 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index d5a589c8..bf6fa543 100644 --- a/src/op.cc +++ b/src/op.cc @@ -81,7 +81,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) scope_t * scope_ptr = &scope; if (is_ident()) { - DEBUG("expr.compile", "lookup: " << as_ident()); + DEBUG("expr.compile", "Lookup: " << as_ident()); if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) { // Identifier references are first looked up at the point of @@ -93,7 +93,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) def->dump(*_log_stream, 0); } #endif // defined(DEBUG_ON) - return copy(def); + return copy(def); } else if (left()) { return copy(); @@ -102,7 +102,6 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) } else if (is_scope()) { shared_ptr subscope(new symbol_scope_t(scope)); - DEBUG("expr.compile", "creating scope"); set_scope(subscope); scope_ptr = subscope.get(); } @@ -114,22 +113,21 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) case IDENT: scope_ptr->define(symbol_t::FUNCTION, left()->as_ident(), right()); break; + case O_CALL: if (left()->left()->is_ident()) { ptr_op_t node(new op_t(op_t::O_LAMBDA)); node->set_left(left()->right()); node->set_right(right()); - scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(), node); - } else { - throw_(compile_error, _("Invalid function definition")); + break; } - break; + // fall through... + default: throw_(compile_error, _("Invalid function definition")); } - return wrap_value(NULL_VALUE); } ptr_op_t lhs(left()->compile(*scope_ptr, depth)); @@ -144,7 +142,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) // Reduce constants immediately if possible if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value())) - return wrap_value(intermediate->calc(*scope_ptr, NULL, depth)); + return wrap_value(intermediate->calc(*scope_ptr, NULL, depth + 1)); return intermediate; } @@ -159,7 +157,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) if (SHOW_DEBUG("expr.calc")) { for (int i = 0; i < depth; i++) ledger::_log_buffer << '.'; - ledger::_log_buffer << op_context(this) << " => ..."; + ledger::_log_buffer << op_context(this) << " => ..."; DEBUG("expr.calc", ""); } #endif @@ -170,84 +168,48 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; case O_DEFINE: - //result = left()->calc(scope, locus, depth + 1); result = NULL_VALUE; break; case IDENT: { ptr_op_t definition = left(); + // If no definition was pre-compiled for this identifier, look it up + // in the current scope. if (! definition) { - // If no definition was pre-compiled for this identifier, look it - // up in the current scope. + DEBUG("scope.symbols", "Looking for IDENT '" << as_ident() << "'"); definition = scope.lookup(symbol_t::FUNCTION, as_ident()); } if (! definition) throw_(calc_error, _("Unknown identifier '%1'") << as_ident()); // Evaluating an identifier is the same as calling its definition - // directly, so we create an empty call_scope_t to reflect the scope for - // this implicit call. - call_scope_t call_args(scope, locus, depth); - result = definition->compile(call_args, depth + 1) - ->calc(call_args, locus, depth + 1); + // directly + result = definition->calc(scope, locus, depth + 1); check_type_context(scope, result); break; } case FUNCTION: { - // Evaluating a FUNCTION is the same as calling it directly; this happens - // when certain functions-that-look-like-variables (such as "amount") are - // resolved. - call_scope_t call_args(scope, locus, depth); + // Evaluating a FUNCTION is the same as calling it directly; this + // happens when certain functions-that-look-like-variables (such as + // "amount") are resolved. + call_scope_t call_args(scope, locus, depth + 1); result = as_function()(call_args); check_type_context(scope, result); break; } case SCOPE: + assert(! is_scope_unset()); if (is_scope_unset()) { symbol_scope_t subscope(scope); result = left()->calc(subscope, locus, depth + 1); } else { - result = left()->calc(*as_scope(), locus, depth + 1); + bind_scope_t bound_scope(scope, *as_scope()); + result = left()->calc(bound_scope, locus, depth + 1); } break; - case O_LAMBDA: { - call_scope_t& call_args(downcast(scope)); - std::size_t args_count(call_args.size()); - std::size_t args_index(0); - symbol_scope_t call_scope(call_args); - ptr_op_t sym(left()); - - for (; sym; sym = sym->has_right() ? sym->right() : NULL) { - ptr_op_t varname = sym; - if (sym->kind == O_CONS) - varname = sym->left(); - - if (! varname->is_ident()) { - throw_(calc_error, _("Invalid function definition")); - } - else if (args_index == args_count) { - call_scope.define(symbol_t::FUNCTION, varname->as_ident(), - wrap_value(NULL_VALUE)); - } - else { - DEBUG("expr.compile", - "Defining function parameter " << varname->as_ident()); - call_scope.define(symbol_t::FUNCTION, varname->as_ident(), - wrap_value(call_args[args_index++])); - } - } - - if (args_index < args_count) - throw_(calc_error, - _("Too few arguments in function call (saw %1)") << args_count); - - result = right()->calc(call_scope, locus, depth + 1); - break; - } - case O_LOOKUP: { context_scope_t context_scope(scope, value_t::SCOPE); bool scope_error = true; @@ -264,10 +226,6 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) } case O_CALL: { - call_scope_t call_args(scope, locus, depth); - if (has_right()) - call_args.set_args(split_cons_expr(right())); - ptr_op_t func = left(); const string& name(func->as_ident()); @@ -277,20 +235,9 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) if (! func) throw_(calc_error, _("Calling unknown function '%1'") << name); -#if defined(DEBUG_ON) - if (SHOW_DEBUG("expr.calc")) { - for (int i = 0; i < depth; i++) - ledger::_log_buffer << '.'; - ledger::_log_buffer << " args: "; - if (call_args.args.is_sequence()) { - foreach (value_t& arg, call_args) - ledger::_log_buffer << arg << " "; - } else { - ledger::_log_buffer << call_args.args[0] << " "; - } - DEBUG("expr.calc", ""); - } -#endif + call_scope_t call_args(scope, locus, depth + 1); + if (has_right()) + call_args.set_args(split_cons_expr(right())); if (func->is_function()) result = func->as_function()(call_args); @@ -301,6 +248,39 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; } + case O_LAMBDA: { + call_scope_t& call_args(downcast(scope)); + std::size_t args_count(call_args.size()); + std::size_t args_index(0); + symbol_scope_t call_scope(call_args); + + 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 definition")); + } + else if (args_index == args_count) { + call_scope.define(symbol_t::FUNCTION, varname->as_ident(), + wrap_value(NULL_VALUE)); + } + else { + DEBUG("expr.compile", + "Defining function parameter " << varname->as_ident()); + call_scope.define(symbol_t::FUNCTION, varname->as_ident(), + wrap_value(call_args[args_index++])); + } + } + + if (args_index < args_count) + throw_(calc_error, + _("Too few arguments in function call (saw %1)") << args_count); + + result = right()->calc(call_scope, locus, depth + 1); + break; + } + case O_MATCH: result = (right()->calc(scope, locus, depth + 1).as_mask() .match(left()->calc(scope, locus, depth + 1).to_string())); @@ -369,7 +349,6 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) case O_QUERY: assert(right()); assert(right()->kind == O_COLON); - if (value_t temp = left()->calc(scope, locus, depth + 1)) result = right()->left()->calc(scope, locus, depth + 1); else @@ -382,8 +361,6 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) case O_CONS: result = left()->calc(scope, locus, depth + 1); - DEBUG("op.cons", "car = " << result); - if (has_right()) { value_t temp; temp.push_back(result); @@ -399,7 +376,6 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) next = NULL; } temp.push_back(value_op->calc(scope, locus, depth + 1)); - DEBUG("op.cons", "temp now = " << temp); } result = temp; } @@ -413,7 +389,6 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) // onto the stack. We evaluate the left side here to catch any // side-effects, such as definitions in the case of 'x = 1; x'. result = left()->calc(scope, locus, depth + 1); - if (has_right()) { ptr_op_t next = right(); while (next) { @@ -786,7 +761,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const // An identifier is a special non-terminal, in that its left() can // hold the compiled definition of the identifier. - if (kind > TERMINALS || is_ident() || is_scope()) { + if (kind > TERMINALS || is_scope()) { if (left()) { left()->dump(out, depth + 1); if (kind > UNARY_OPERATORS && has_right()) diff --git a/src/scope.cc b/src/scope.cc index e18b5a0a..95347c8d 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -40,7 +40,8 @@ scope_t * scope_t::default_scope = NULL; void symbol_scope_t::define(const symbol_t::kind_t kind, const string& name, expr_t::ptr_op_t def) { - DEBUG("scope.symbols", "Defining '" << name << "' = " << def); + DEBUG("scope.symbols", + "Defining '" << name << "' = " << def << " in " << this); if (! symbols) symbols = symbol_map(); @@ -64,9 +65,12 @@ expr_t::ptr_op_t symbol_scope_t::lookup(const symbol_t::kind_t kind, const string& name) { if (symbols) { + DEBUG("scope.symbols", "Looking for '" << name << "' in " << this); symbol_map::const_iterator i = symbols->find(symbol_t(kind, name)); - if (i != symbols->end()) + if (i != symbols->end()) { + DEBUG("scope.symbols", "Found '" << name << "' in " << this); return (*i).second; + } } return child_scope_t::lookup(kind, name); } diff --git a/src/scope.h b/src/scope.h index a7b3c5cb..fbc1a889 100644 --- a/src/scope.h +++ b/src/scope.h @@ -188,6 +188,8 @@ public: scope_t& _grandchild) : child_scope_t(_parent), grandchild(_grandchild) { TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); + DEBUG("scope.symbols", + "Binding scope " << &_parent << " with " << &_grandchild); } virtual ~bind_scope_t() { TRACE_DTOR(bind_scope_t); -- cgit v1.2.3 From c47350dce9c666987f924c54507973fc11587b2e Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 21 Feb 2012 03:53:00 -0600 Subject: Corrected handling of nested definitions --- src/op.cc | 73 ++++++++++++++++++++++++++++++----------- src/parser.cc | 8 ++--- src/report.cc | 4 +++ test/baseline/cmd-script.test | 3 ++ test/baseline/cmd-script_2.test | 3 ++ 5 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 test/baseline/cmd-script.test create mode 100644 test/baseline/cmd-script_2.test (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index bf6fa543..6dff031c 100644 --- a/src/op.cc +++ b/src/op.cc @@ -78,11 +78,19 @@ namespace { expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) { - scope_t * scope_ptr = &scope; + scope_t * scope_ptr = &scope; + expr_t::ptr_op_t result; - if (is_ident()) { - DEBUG("expr.compile", "Lookup: " << as_ident()); +#if defined(DEBUG_ON) + if (SHOW_DEBUG("expr.compile")) { + for (int i = 0; i < depth; i++) + ledger::_log_buffer << '.'; + DEBUG("expr.compile", ""); + } +#endif + if (is_ident()) { + DEBUG("expr.compile", "Lookup: " << as_ident() << " in " << scope_ptr); if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) { // Identifier references are first looked up at the point of // definition, and then at the point of every use if they could @@ -93,12 +101,14 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) def->dump(*_log_stream, 0); } #endif // defined(DEBUG_ON) - return copy(def); + result = copy(def); } else if (left()) { - return copy(); + result = copy(); + } + else { + result = this; } - return this; } else if (is_scope()) { shared_ptr subscope(new symbol_scope_t(scope)); @@ -106,19 +116,28 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) scope_ptr = subscope.get(); } else if (kind < TERMINALS) { - return this; + result = this; } else if (kind == O_DEFINE) { switch (left()->kind) { - case IDENT: - scope_ptr->define(symbol_t::FUNCTION, left()->as_ident(), right()); + case IDENT: { + ptr_op_t node(right()->compile(*scope_ptr, depth + 1)); + + DEBUG("expr.compile", + "Defining " << left()->as_ident() << " in " << scope_ptr); + scope_ptr->define(symbol_t::FUNCTION, left()->as_ident(), node); break; + } case O_CALL: if (left()->left()->is_ident()) { ptr_op_t node(new op_t(op_t::O_LAMBDA)); node->set_left(left()->right()); node->set_right(right()); + node = node->compile(*scope_ptr, depth + 1); + + DEBUG("expr.compile", + "Defining " << left()->left()->as_ident() << " in " << scope_ptr); scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(), node); break; @@ -128,23 +147,37 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) default: throw_(compile_error, _("Invalid function definition")); } + result = wrap_value(NULL_VALUE); } - ptr_op_t lhs(left()->compile(*scope_ptr, depth)); - ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ? - (kind == O_LOOKUP ? right() : - right()->compile(*scope_ptr, depth)) : NULL); + if (! result) { + ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1)); + ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ? + (kind == O_LOOKUP ? right() : + right()->compile(*scope_ptr, depth + 1)) : NULL); - if (lhs == left() && (! rhs || rhs == right())) - return this; + if (lhs == left() && (! rhs || rhs == right())) { + result = this; + } else { + ptr_op_t intermediate(copy(lhs, rhs)); - ptr_op_t intermediate(copy(lhs, rhs)); + // Reduce constants immediately if possible + if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value())) + result = wrap_value(intermediate->calc(*scope_ptr, NULL, depth + 1)); + else + result = intermediate; + } + } - // Reduce constants immediately if possible - if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value())) - return wrap_value(intermediate->calc(*scope_ptr, NULL, depth + 1)); +#if defined(DEBUG_ON) + if (SHOW_DEBUG("expr.compile")) { + for (int i = 0; i < depth; i++) + ledger::_log_buffer << '.'; + DEBUG("expr.compile", ""); + } +#endif - return intermediate; + return result; } value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) diff --git a/src/parser.cc b/src/parser.cc index ad621106..6197af6b 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -517,14 +517,10 @@ expr_t::parser_t::parse_value_expr(std::istream& in, ptr_op_t seq(new op_t(op_t::O_SEQ)); if (! chain) { seq->set_left(node); - ptr_op_t scope(new op_t(op_t::SCOPE)); - scope->set_left(seq); - node = scope; + node = seq; } else { seq->set_left(chain->right()); - ptr_op_t scope(new op_t(op_t::SCOPE)); - scope->set_left(seq); - chain->set_right(scope); + chain->set_right(seq); } seq->set_right(parse_assign_expr(in, tflags)); chain = seq; diff --git a/src/report.cc b/src/report.cc index f4dc450e..38ae596a 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1559,6 +1559,10 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, if (is_eq(p, "query")) return WRAP_FUNCTOR(query_command); break; + case 's': + if (is_eq(p, "script")) + return WRAP_FUNCTOR(source_command); + break; case 't': if (is_eq(p, "template")) return WRAP_FUNCTOR(template_command); diff --git a/test/baseline/cmd-script.test b/test/baseline/cmd-script.test new file mode 100644 index 00000000..ed665dcc --- /dev/null +++ b/test/baseline/cmd-script.test @@ -0,0 +1,3 @@ +test eval 'foo(w, u)=(z=w+u;z*2); (a=1 + 1; foo(10, 15))' +50 +end test diff --git a/test/baseline/cmd-script_2.test b/test/baseline/cmd-script_2.test new file mode 100644 index 00000000..a6f6f37a --- /dev/null +++ b/test/baseline/cmd-script_2.test @@ -0,0 +1,3 @@ +test eval 'x=total_expr;x=x/count;x=amount_expr-x*count;x' +0 +end test -- cgit v1.2.3 From e2afc783db0dff1927b00dc506390353d9e3bbd2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Feb 2012 22:32:23 -0600 Subject: Increased file copyrights to 2012 --- src/account.cc | 2 +- src/account.h | 2 +- src/accum.cc | 2 +- src/accum.h | 2 +- src/amount.cc | 2 +- src/amount.h | 2 +- src/annotate.cc | 2 +- src/annotate.h | 2 +- src/archive.cc | 2 +- src/archive.h | 2 +- src/balance.cc | 2 +- src/balance.h | 2 +- src/chain.cc | 2 +- src/chain.h | 2 +- src/commodity.cc | 2 +- src/commodity.h | 2 +- src/compare.cc | 2 +- src/compare.h | 2 +- src/convert.cc | 2 +- src/convert.h | 2 +- src/csv.cc | 2 +- src/csv.h | 2 +- src/draft.cc | 2 +- src/draft.h | 2 +- src/emacs.cc | 2 +- src/emacs.h | 2 +- src/error.cc | 2 +- src/error.h | 2 +- src/expr.cc | 2 +- src/expr.h | 2 +- src/exprbase.h | 2 +- src/filters.cc | 2 +- src/filters.h | 2 +- src/flags.h | 2 +- src/format.cc | 2 +- src/format.h | 2 +- src/generate.cc | 2 +- src/generate.h | 2 +- src/global.cc | 2 +- src/global.h | 4 ++-- src/item.cc | 2 +- src/item.h | 2 +- src/iterators.cc | 2 +- src/iterators.h | 2 +- src/journal.cc | 2 +- src/journal.h | 2 +- src/lookup.cc | 2 +- src/lookup.h | 2 +- src/main.cc | 2 +- src/mask.cc | 2 +- src/mask.h | 2 +- src/op.cc | 2 +- src/op.h | 2 +- src/option.cc | 2 +- src/option.h | 2 +- src/org.cc | 2 +- src/org.h | 2 +- src/output.cc | 2 +- src/output.h | 2 +- src/parser.cc | 2 +- src/parser.h | 2 +- src/pool.cc | 2 +- src/pool.h | 2 +- src/post.cc | 2 +- src/post.h | 2 +- src/precmd.cc | 2 +- src/precmd.h | 2 +- src/predicate.cc | 2 +- src/predicate.h | 2 +- src/print.cc | 2 +- src/print.h | 2 +- src/pstream.h | 2 +- src/py_account.cc | 2 +- src/py_amount.cc | 2 +- src/py_balance.cc | 2 +- src/py_commodity.cc | 2 +- src/py_expr.cc | 2 +- src/py_format.cc | 2 +- src/py_item.cc | 2 +- src/py_journal.cc | 2 +- src/py_post.cc | 2 +- src/py_times.cc | 2 +- src/py_utils.cc | 2 +- src/py_value.cc | 2 +- src/py_xact.cc | 2 +- src/pyfstream.h | 2 +- src/pyinterp.cc | 2 +- src/pyinterp.h | 2 +- src/pyledger.cc | 2 +- src/pyutils.h | 2 +- src/query.cc | 2 +- src/query.h | 2 +- src/quotes.cc | 2 +- src/quotes.h | 2 +- src/report.cc | 2 +- src/report.h | 2 +- src/scope.cc | 2 +- src/scope.h | 2 +- src/series.h | 2 +- src/session.cc | 2 +- src/session.h | 2 +- src/stats.cc | 2 +- src/stats.h | 2 +- src/stream.cc | 2 +- src/stream.h | 2 +- src/system.hh.in | 2 +- src/temps.cc | 2 +- src/temps.h | 2 +- src/textual.cc | 2 +- src/timelog.cc | 2 +- src/timelog.h | 2 +- src/times.cc | 2 +- src/times.h | 2 +- src/token.cc | 2 +- src/token.h | 2 +- src/unistring.h | 2 +- src/utils.cc | 2 +- src/utils.h | 2 +- src/value.cc | 2 +- src/value.h | 2 +- src/xact.cc | 2 +- src/xact.h | 2 +- src/xml.cc | 2 +- src/xml.h | 2 +- 124 files changed, 125 insertions(+), 125 deletions(-) (limited to 'src/op.cc') diff --git a/src/account.cc b/src/account.cc index 42c10839..40ddf70b 100644 --- a/src/account.cc +++ b/src/account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/account.h b/src/account.h index 7a632b35..8f0f915f 100644 --- a/src/account.h +++ b/src/account.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/accum.cc b/src/accum.cc index 0187995e..3add051b 100644 --- a/src/accum.cc +++ b/src/accum.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/accum.h b/src/accum.h index 411bcbe6..349aeba9 100644 --- a/src/accum.h +++ b/src/accum.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/amount.cc b/src/amount.cc index 85afc3d8..4d26a688 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/amount.h b/src/amount.h index f7e877a7..3a8e06b9 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/annotate.cc b/src/annotate.cc index 8ba46f4f..cd1733ca 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/annotate.h b/src/annotate.h index b590ca45..3c6db8e8 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/archive.cc b/src/archive.cc index 28760512..72ec0419 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/archive.h b/src/archive.h index 1ebf3496..4ce5e0e7 100644 --- a/src/archive.h +++ b/src/archive.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/balance.cc b/src/balance.cc index 7ce9d994..4fba7344 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/balance.h b/src/balance.h index ac22f3e7..57e6ace4 100644 --- a/src/balance.h +++ b/src/balance.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/chain.cc b/src/chain.cc index 61388840..fc1be5bd 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/chain.h b/src/chain.h index 7bd76712..080c4231 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/commodity.cc b/src/commodity.cc index 5fd54d11..643d0d1e 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/commodity.h b/src/commodity.h index d7747b2a..68f788e3 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/compare.cc b/src/compare.cc index cdc96a86..e2a298c2 100644 --- a/src/compare.cc +++ b/src/compare.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/compare.h b/src/compare.h index 0e7bf5e5..e1abbca1 100644 --- a/src/compare.h +++ b/src/compare.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/convert.cc b/src/convert.cc index 15995d05..1b1bf814 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/convert.h b/src/convert.h index 6d02f24a..de958108 100644 --- a/src/convert.h +++ b/src/convert.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/csv.cc b/src/csv.cc index 82c28ff3..823238c7 100644 --- a/src/csv.cc +++ b/src/csv.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/csv.h b/src/csv.h index 909439ff..4d6e1253 100644 --- a/src/csv.h +++ b/src/csv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/draft.cc b/src/draft.cc index 9f9ec6e8..7c95caf7 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/draft.h b/src/draft.h index 59039f77..41485731 100644 --- a/src/draft.h +++ b/src/draft.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/emacs.cc b/src/emacs.cc index 5048a348..41c67cc6 100644 --- a/src/emacs.cc +++ b/src/emacs.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/emacs.h b/src/emacs.h index 97292728..a018ce68 100644 --- a/src/emacs.h +++ b/src/emacs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/error.cc b/src/error.cc index 88adfbdb..4a16f4e3 100644 --- a/src/error.cc +++ b/src/error.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/error.h b/src/error.h index b9960b03..7630f017 100644 --- a/src/error.h +++ b/src/error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/expr.cc b/src/expr.cc index b3d4abcd..74d16ecc 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/expr.h b/src/expr.h index 79ae2864..e082efa5 100644 --- a/src/expr.h +++ b/src/expr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/exprbase.h b/src/exprbase.h index e0e2824f..0b1ef243 100644 --- a/src/exprbase.h +++ b/src/exprbase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/filters.cc b/src/filters.cc index fa1f6fa2..72ce9c32 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/filters.h b/src/filters.h index c972de82..22f2d2cb 100644 --- a/src/filters.h +++ b/src/filters.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/flags.h b/src/flags.h index 09b7eec4..e2046c08 100644 --- a/src/flags.h +++ b/src/flags.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/format.cc b/src/format.cc index 65c06488..a391fdf1 100644 --- a/src/format.cc +++ b/src/format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/format.h b/src/format.h index f30b8184..74d77768 100644 --- a/src/format.h +++ b/src/format.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/generate.cc b/src/generate.cc index 963cd845..bf9a8036 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/generate.h b/src/generate.h index abf719d4..1b22004b 100644 --- a/src/generate.h +++ b/src/generate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/global.cc b/src/global.cc index 34427f4b..ee921fc5 100644 --- a/src/global.cc +++ b/src/global.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/global.h b/src/global.h index 6504230d..28bffc3a 100644 --- a/src/global.h +++ b/src/global.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -113,7 +113,7 @@ public: out << "Ledger " << ledger::version << _(", the command-line accounting tool"); out << - _("\n\nCopyright (c) 2003-2010, John Wiegley. All rights reserved.\n\n\ + _("\n\nCopyright (c) 2003-2012, John Wiegley. All rights reserved.\n\n\ This program is made available under the terms of the BSD Public License.\n\ See LICENSE file included with the distribution for details and disclaimer."); out << std::endl; diff --git a/src/item.cc b/src/item.cc index d123ee5a..3a2b0b60 100644 --- a/src/item.cc +++ b/src/item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/item.h b/src/item.h index af3992c0..3a9c55bb 100644 --- a/src/item.h +++ b/src/item.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/iterators.cc b/src/iterators.cc index b398646e..72e0481c 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/iterators.h b/src/iterators.h index 93782400..6d490259 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/journal.cc b/src/journal.cc index ea90fa05..2ebe90fb 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/journal.h b/src/journal.h index 70820cbd..6d10ffda 100644 --- a/src/journal.h +++ b/src/journal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/lookup.cc b/src/lookup.cc index 452727d6..ce22529d 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/lookup.h b/src/lookup.h index 8e83b84e..ba64b0b5 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/main.cc b/src/main.cc index 9031341f..2202a5de 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/mask.cc b/src/mask.cc index 52907cfe..5bc10d5f 100644 --- a/src/mask.cc +++ b/src/mask.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/mask.h b/src/mask.h index e72347ad..15929b2e 100644 --- a/src/mask.h +++ b/src/mask.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/op.cc b/src/op.cc index 6dff031c..372101f0 100644 --- a/src/op.cc +++ b/src/op.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/op.h b/src/op.h index c4d353dc..192c1f5e 100644 --- a/src/op.h +++ b/src/op.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/option.cc b/src/option.cc index 2843c775..170b94af 100644 --- a/src/option.cc +++ b/src/option.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/option.h b/src/option.h index 8f89d081..dc1099db 100644 --- a/src/option.h +++ b/src/option.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/org.cc b/src/org.cc index 7c8e8c0d..3c897f54 100644 --- a/src/org.cc +++ b/src/org.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/org.h b/src/org.h index ed023be2..0b34b610 100644 --- a/src/org.h +++ b/src/org.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/output.cc b/src/output.cc index b26881a3..aaf81f60 100644 --- a/src/output.cc +++ b/src/output.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/output.h b/src/output.h index ac3925c4..281f69b6 100644 --- a/src/output.h +++ b/src/output.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/parser.cc b/src/parser.cc index 6197af6b..2c9069d7 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/parser.h b/src/parser.h index 09e12d95..75fd9a41 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pool.cc b/src/pool.cc index 65edbd6a..ba408fc5 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pool.h b/src/pool.h index 4b935f69..87b315f9 100644 --- a/src/pool.h +++ b/src/pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/post.cc b/src/post.cc index 125947e4..e0ca149f 100644 --- a/src/post.cc +++ b/src/post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/post.h b/src/post.h index 0cfd3e90..ce33fefc 100644 --- a/src/post.h +++ b/src/post.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/precmd.cc b/src/precmd.cc index 663b638d..6f8becb6 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/precmd.h b/src/precmd.h index 277933c3..1c52d8a7 100644 --- a/src/precmd.h +++ b/src/precmd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/predicate.cc b/src/predicate.cc index fd301a7d..58d6c752 100644 --- a/src/predicate.cc +++ b/src/predicate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/predicate.h b/src/predicate.h index 673f1d5d..7d58dc2f 100644 --- a/src/predicate.h +++ b/src/predicate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/print.cc b/src/print.cc index 63f38d80..c544c4e0 100644 --- a/src/print.cc +++ b/src/print.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/print.h b/src/print.h index 527f1912..42bfc8b6 100644 --- a/src/print.h +++ b/src/print.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pstream.h b/src/pstream.h index 8134495d..a894325d 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/py_account.cc b/src/py_account.cc index 5ef86871..64a7ae54 100644 --- a/src/py_account.cc +++ b/src/py_account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_amount.cc b/src/py_amount.cc index 9ce4a02d..f10595e8 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_balance.cc b/src/py_balance.cc index 0140a625..6c9ccb24 100644 --- a/src/py_balance.cc +++ b/src/py_balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_commodity.cc b/src/py_commodity.cc index 6d8a29b3..11ebe844 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_expr.cc b/src/py_expr.cc index 027125e2..dd9df1f5 100644 --- a/src/py_expr.cc +++ b/src/py_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_format.cc b/src/py_format.cc index fc2103c7..482eaf5b 100644 --- a/src/py_format.cc +++ b/src/py_format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_item.cc b/src/py_item.cc index a12784ff..e3e49457 100644 --- a/src/py_item.cc +++ b/src/py_item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_journal.cc b/src/py_journal.cc index bd781225..4f5427f5 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_post.cc b/src/py_post.cc index cace419f..bd599604 100644 --- a/src/py_post.cc +++ b/src/py_post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_times.cc b/src/py_times.cc index c2e0b8f8..17f9ec7e 100644 --- a/src/py_times.cc +++ b/src/py_times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_utils.cc b/src/py_utils.cc index 710dca4b..45ffe545 100644 --- a/src/py_utils.cc +++ b/src/py_utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_value.cc b/src/py_value.cc index f8f36453..3b67c4c6 100644 --- a/src/py_value.cc +++ b/src/py_value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/py_xact.cc b/src/py_xact.cc index af1fcdd5..97d5df47 100644 --- a/src/py_xact.cc +++ b/src/py_xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pyfstream.h b/src/pyfstream.h index 49b072f2..972f976f 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pyinterp.cc b/src/pyinterp.cc index e48f16c6..44bea2cd 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pyinterp.h b/src/pyinterp.h index ea947c5a..ae8dd9c2 100644 --- a/src/pyinterp.h +++ b/src/pyinterp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pyledger.cc b/src/pyledger.cc index 4a53532a..cf5e362e 100644 --- a/src/pyledger.cc +++ b/src/pyledger.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/pyutils.h b/src/pyutils.h index 7e016502..44bb6d90 100644 --- a/src/pyutils.h +++ b/src/pyutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/query.cc b/src/query.cc index 812123cb..8bdabb38 100644 --- a/src/query.cc +++ b/src/query.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/query.h b/src/query.h index 8f7917b2..52168539 100644 --- a/src/query.h +++ b/src/query.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/quotes.cc b/src/quotes.cc index 0cc8d06b..b29eb8bd 100644 --- a/src/quotes.cc +++ b/src/quotes.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/quotes.h b/src/quotes.h index 376d8918..52092fbc 100644 --- a/src/quotes.h +++ b/src/quotes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/report.cc b/src/report.cc index 530e7727..2c0c3970 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/report.h b/src/report.h index 2b521aae..35d45437 100644 --- a/src/report.h +++ b/src/report.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/scope.cc b/src/scope.cc index 2b9851b0..b2a7b17b 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/scope.h b/src/scope.h index 2720e8fc..6fcd67e9 100644 --- a/src/scope.h +++ b/src/scope.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/series.h b/src/series.h index 40f34051..75b98194 100644 --- a/src/series.h +++ b/src/series.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/session.cc b/src/session.cc index 31122daa..9d994a9b 100644 --- a/src/session.cc +++ b/src/session.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/session.h b/src/session.h index 680b8a0e..93bee8ba 100644 --- a/src/session.h +++ b/src/session.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/stats.cc b/src/stats.cc index 524f5a87..0966fee2 100644 --- a/src/stats.cc +++ b/src/stats.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/stats.h b/src/stats.h index b7bf94c5..7b00fec8 100644 --- a/src/stats.h +++ b/src/stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/stream.cc b/src/stream.cc index 5d4cf5e0..ce40bfcc 100644 --- a/src/stream.cc +++ b/src/stream.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/stream.h b/src/stream.h index 42c85534..c317ebdf 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/system.hh.in b/src/system.hh.in index 42a82e41..e14166b2 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/temps.cc b/src/temps.cc index 365c33c5..cb471d41 100644 --- a/src/temps.cc +++ b/src/temps.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/temps.h b/src/temps.h index 1e7eb69f..ad4e5672 100644 --- a/src/temps.h +++ b/src/temps.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/textual.cc b/src/textual.cc index 4977852c..15642cae 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/timelog.cc b/src/timelog.cc index 5ab6a25c..8d3d69c1 100644 --- a/src/timelog.cc +++ b/src/timelog.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/timelog.h b/src/timelog.h index 020ae4f2..12083302 100644 --- a/src/timelog.h +++ b/src/timelog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/times.cc b/src/times.cc index 8ea90892..21ec1859 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/times.h b/src/times.h index bc462efa..6eadcad3 100644 --- a/src/times.h +++ b/src/times.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/token.cc b/src/token.cc index 77092d49..9449d9b7 100644 --- a/src/token.cc +++ b/src/token.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/token.h b/src/token.h index cbdf1258..01ff7ee9 100644 --- a/src/token.h +++ b/src/token.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/unistring.h b/src/unistring.h index 4be36b0d..a33c6e3f 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/utils.cc b/src/utils.cc index 5260fd42..09526267 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/utils.h b/src/utils.h index c7aaac52..e37f37aa 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/value.cc b/src/value.cc index 61066f03..5fa748f6 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/value.h b/src/value.h index f8495002..1e4d0ce9 100644 --- a/src/value.h +++ b/src/value.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/xact.cc b/src/xact.cc index 8e1951a5..0fedb42a 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/xact.h b/src/xact.h index ff4b7bc2..cb7bdeb3 100644 --- a/src/xact.h +++ b/src/xact.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/xml.cc b/src/xml.cc index 90efd4b3..560db805 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 diff --git a/src/xml.h b/src/xml.h index 5d14dab3..871fd120 100644 --- a/src/xml.h +++ b/src/xml.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, 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 -- cgit v1.2.3 From cfd7ffb12645c198a5b15891654f6ad6a0e4db27 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 1 Mar 2012 22:20:38 -0600 Subject: Provide more context if a valexpr function call fails --- src/op.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 372101f0..8e9df812 100644 --- a/src/op.cc +++ b/src/op.cc @@ -272,10 +272,16 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) if (has_right()) call_args.set_args(split_cons_expr(right())); - if (func->is_function()) - result = func->as_function()(call_args); - else - result = func->calc(call_args, locus, depth + 1); + try { + if (func->is_function()) + result = func->as_function()(call_args); + else + result = func->calc(call_args, locus, depth + 1); + } + catch (const std::exception&) { + add_error_context(_("While calling function '%1':" << name)); + throw; + } check_type_context(scope, result); break; @@ -308,7 +314,8 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) if (args_index < args_count) throw_(calc_error, - _("Too few arguments in function call (saw %1)") << args_count); + _("Too few arguments in function call (saw %1, wanted %2)") + << args_count << args_index); result = right()->calc(call_scope, locus, depth + 1); break; -- cgit v1.2.3 From c8c2a17e282c2cbf3c0edb1b756e16be58328331 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 3 Mar 2012 01:17:21 -0600 Subject: Fixed invocation of lambda expressions foo = x, y, z -> print(x, y, z) foo(1, 2, 3) However, this still does not work: (x, y, z -> print(x, y, z))(1, 2, 3) --- src/op.cc | 2 +- src/scope.h | 24 +++++++++++++++++++----- test/baseline/cmd-script.test | 5 +++++ tools/proof | 4 ++-- 4 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 8e9df812..bd2cc32f 100644 --- a/src/op.cc +++ b/src/op.cc @@ -288,7 +288,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) } case O_LAMBDA: { - call_scope_t& call_args(downcast(scope)); + call_scope_t& call_args(find_scope(scope, true)); std::size_t args_count(call_args.size()); std::size_t args_index(0); symbol_scope_t call_scope(call_args); diff --git a/src/scope.h b/src/scope.h index 90f9c37a..785ce284 100644 --- a/src/scope.h +++ b/src/scope.h @@ -227,15 +227,17 @@ private: }; template -T * search_scope(scope_t * ptr) +T * search_scope(scope_t * ptr, bool prefer_direct_parents = false) { if (T * sought = dynamic_cast(ptr)) return sought; if (bind_scope_t * scope = dynamic_cast(ptr)) { - if (T * sought = search_scope(&scope->grandchild)) + if (T * sought = search_scope(prefer_direct_parents ? + scope->parent : &scope->grandchild)) return sought; - return search_scope(scope->parent); + return search_scope(prefer_direct_parents ? + &scope->grandchild : scope->parent); } else if (child_scope_t * child_scope = dynamic_cast(ptr)) { return search_scope(child_scope->parent); @@ -244,9 +246,21 @@ T * search_scope(scope_t * ptr) } template -inline T& find_scope(child_scope_t& scope, bool skip_this = true) +inline T& find_scope(child_scope_t& scope, bool skip_this = true, + bool prefer_direct_parents = false) { - if (T * sought = search_scope(skip_this ? scope.parent : &scope)) + if (T * sought = search_scope(skip_this ? scope.parent : &scope, + prefer_direct_parents)) + return *sought; + + throw_(std::runtime_error, _("Could not find scope")); + return reinterpret_cast(scope); // never executed +} + +template +inline T& find_scope(scope_t& scope, bool prefer_direct_parents = false) +{ + if (T * sought = search_scope(&scope, prefer_direct_parents)) return *sought; throw_(std::runtime_error, _("Could not find scope")); diff --git a/test/baseline/cmd-script.test b/test/baseline/cmd-script.test index 12e9c868..ce920ebb 100644 --- a/test/baseline/cmd-script.test +++ b/test/baseline/cmd-script.test @@ -10,3 +10,8 @@ end test test eval 'total_expr=$100;amount_expr=$15;x=total_expr;x=x/5;x=amount_expr-x*5;x' $-85 end test + +test eval 'foo = x, y, z -> print(x, y, z); foo(1, 2, 3)' +123 +1 +end test diff --git a/tools/proof b/tools/proof index f37c1488..3b997143 100755 --- a/tools/proof +++ b/tools/proof @@ -15,12 +15,12 @@ ledger_proof() { exit 0 fi - rm -fr $DEST/ledger-proof + sudo rm -fr $DEST/ledger-proof time nice -n 20 \ ./acprep --debug --enable-doxygen --universal --clang -j16 proof 2>&1 | \ tee $LOGDIR/ledger-proof.log - rm -fr $DEST/ledger-proof + sudo rm -fr $DEST/ledger-proof time nice -n 20 \ ./acprep --debug --enable-doxygen --universal --python --clang -j16 proof 2>&1 | \ tee -a $LOGDIR/ledger-proof.log -- cgit v1.2.3 From fa3805282a7967ebd4dd26d2dc1d5cc1a3140a74 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 05:53:41 -0600 Subject: Added an assert --- src/op.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index bd2cc32f..c8e099e7 100644 --- a/src/op.cc +++ b/src/op.cc @@ -89,6 +89,8 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) } #endif + assert(kind < LAST); + if (is_ident()) { DEBUG("expr.compile", "Lookup: " << as_ident() << " in " << scope_ptr); if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) { -- cgit v1.2.3 From acb5e1beea4176ab51ca2c9d32b006e7c0a7bef0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 22:01:41 -0600 Subject: Generalized function call parsing Directly calling a lambda now works: (x -> x + 10)(10) => 20 --- src/op.cc | 19 ++++++++++++------- src/parser.cc | 47 +++++++++++++++++++++++++++++++---------------- src/parser.h | 2 ++ 3 files changed, 45 insertions(+), 23 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index c8e099e7..56d3710e 100644 --- a/src/op.cc +++ b/src/op.cc @@ -262,13 +262,18 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) case O_CALL: { ptr_op_t func = left(); - const string& name(func->as_ident()); - - func = func->left(); - if (! func) - func = scope.lookup(symbol_t::FUNCTION, name); - if (! func) - throw_(calc_error, _("Calling unknown function '%1'") << name); + string name; + + if (func->is_ident()) { + name = func->as_ident(); + func = func->left(); + if (! func) + func = scope.lookup(symbol_t::FUNCTION, name); + if (! func) + throw_(calc_error, _("Calling unknown function '%1'") << name); + } else { + name = ""; + } call_scope_t call_args(scope, locus, depth + 1); if (has_right()) diff --git a/src/parser.cc b/src/parser.cc index 2c9069d7..b3f50e41 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -54,20 +54,6 @@ expr_t::parser_t::parse_value_term(std::istream& in, node = new op_t(op_t::IDENT); node->set_ident(ident); - - // An identifier followed by ( represents a function call - tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT)); - if (tok.kind == token_t::LPAREN) { - op_t::kind_t kind = op_t::O_CALL; - ptr_op_t call_node(new op_t(kind)); - call_node->set_left(node); - node = call_node; - - push_token(tok); // let the parser see it again - node->set_right(parse_value_expr(in, tflags.plus_flags(PARSE_SINGLE))); - } else { - push_token(tok); - } break; } @@ -85,12 +71,41 @@ expr_t::parser_t::parse_value_term(std::istream& in, return node; } + expr_t::ptr_op_t -expr_t::parser_t::parse_dot_expr(std::istream& in, +expr_t::parser_t::parse_call_expr(std::istream& in, const parse_flags_t& tflags) const { ptr_op_t node(parse_value_term(in, tflags)); + if (node && ! tflags.has_flags(PARSE_SINGLE)) { + while (true) { + token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT)); + if (tok.kind == token_t::LPAREN) { + ptr_op_t prev(node); + node = new op_t(op_t::O_CALL); + node->set_left(prev); + push_token(tok); // let the parser see the '(' again + node->set_right(parse_value_expr(in, tflags.plus_flags(PARSE_SINGLE))); + if (! node->right()) + throw_(parse_error, + _("%1 operator not followed by argument") << tok.symbol); + } else { + push_token(tok); + break; + } + } + } + + return node; +} + +expr_t::ptr_op_t +expr_t::parser_t::parse_dot_expr(std::istream& in, + const parse_flags_t& tflags) const +{ + ptr_op_t node(parse_call_expr(in, tflags)); + if (node && ! tflags.has_flags(PARSE_SINGLE)) { while (true) { token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT)); @@ -98,7 +113,7 @@ expr_t::parser_t::parse_dot_expr(std::istream& in, ptr_op_t prev(node); node = new op_t(op_t::O_LOOKUP); node->set_left(prev); - node->set_right(parse_value_term(in, tflags)); + node->set_right(parse_call_expr(in, tflags)); if (! node->right()) throw_(parse_error, _("%1 operator not followed by argument") << tok.symbol); diff --git a/src/parser.h b/src/parser.h index 75fd9a41..db16a919 100644 --- a/src/parser.h +++ b/src/parser.h @@ -81,6 +81,8 @@ class expr_t::parser_t : public noncopyable ptr_op_t parse_value_term(std::istream& in, const parse_flags_t& flags) const; + ptr_op_t parse_call_expr(std::istream& in, + const parse_flags_t& flags) const; ptr_op_t parse_dot_expr(std::istream& in, const parse_flags_t& flags) const; ptr_op_t parse_unary_expr(std::istream& in, -- cgit v1.2.3 From 71d0033b6f65260698cf0bf367002a9b6429a3fd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 6 Mar 2012 23:04:27 -0600 Subject: Corrected several compile and link problems --- src/account.cc | 6 ++++-- src/amount.cc | 2 ++ src/draft.cc | 7 +++++++ src/filters.cc | 13 +++++++++++-- src/format.cc | 2 ++ src/op.cc | 10 ++++++++++ src/op.h | 8 ++------ src/pool.cc | 18 +++++++++++------- src/pyinterp.cc | 1 + src/query.h | 1 + src/textual.cc | 10 +++++++--- src/times.h | 2 ++ src/xact.cc | 2 ++ 13 files changed, 62 insertions(+), 20 deletions(-) (limited to 'src/op.cc') diff --git a/src/account.cc b/src/account.cc index e1874839..29c05719 100644 --- a/src/account.cc +++ b/src/account.cc @@ -89,8 +89,10 @@ account_t * account_t::find_account(const string& acct_name, if (has_flags(ACCOUNT_GENERATED)) account->add_flags(ACCOUNT_GENERATED); - std::pair result - = accounts.insert(accounts_map::value_type(first, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + accounts.insert(accounts_map::value_type(first, account)); assert(result.second); } else { account = (*i).second; diff --git a/src/amount.cc b/src/amount.cc index f9e2309b..313f8d27 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -120,11 +120,13 @@ namespace { { char * buf = NULL; try { +#if defined(DEBUG_ON) IF_DEBUG("amount.convert") { char * tbuf = mpq_get_str(NULL, 10, quant); DEBUG("amount.convert", "Rational to convert = " << tbuf); std::free(tbuf); } +#endif // Convert the rational number to a floating-point, extending the // floating-point to a large enough size to get a precise answer. diff --git a/src/draft.cc b/src/draft.cc index 017c637d..9abc769e 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -109,7 +109,14 @@ void draft_t::parse_args(const value_t& args) } else if (check_for_date && bool(weekday = string_to_day_of_week(what[0]))) { +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif short dow = static_cast(*weekday); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif date_t date = CURRENT_DATE() - date_duration(1); while (date.day_of_week() != dow) date -= date_duration(1); diff --git a/src/filters.cc b/src/filters.cc index 8543cddb..34df2056 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -833,10 +833,17 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, foreach (post_t * post, component_posts) { date_t date = post->date(); date_t value_date = post->value_date(); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif if (! range_start || date < *range_start) range_start = date; if (! range_finish || value_date > *range_finish) range_finish = value_date; +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif } } component_posts.clear(); @@ -880,8 +887,10 @@ void subtotal_posts::operator()(post_t& post) if (i == values.end()) { value_t temp; post.add_to_value(temp, amount_expr); - std::pair result - = values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); +#if defined(DEBUG_ON) + std::pair result = +#endif + values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); assert(result.second); } else { post.add_to_value((*i).second.value, amount_expr); diff --git a/src/format.cc b/src/format.cc index d8c03e6a..79f94869 100644 --- a/src/format.cc +++ b/src/format.cc @@ -221,8 +221,10 @@ format_t::element_t * format_t::parse_elements(const string& fmt, static_cast(current->max_width) : -1); else if (keyword == "left") expr << (current->has_flags(ELEMENT_ALIGN_LEFT) ? "false" : "true"); +#if defined(DEBUG_ON) else assert("Unrecognized format substitution keyword" == NULL); +#endif } else { expr << *ptr++; } diff --git a/src/op.cc b/src/op.cc index 56d3710e..1889f2aa 100644 --- a/src/op.cc +++ b/src/op.cc @@ -38,6 +38,16 @@ namespace ledger { +void intrusive_ptr_add_ref(const expr_t::op_t * op) +{ + op->acquire(); +} + +void intrusive_ptr_release(const expr_t::op_t * op) +{ + op->release(); +} + namespace { value_t split_cons_expr(expr_t::ptr_op_t op) { diff --git a/src/op.h b/src/op.h index 192c1f5e..1807cdd7 100644 --- a/src/op.h +++ b/src/op.h @@ -260,12 +260,8 @@ private: checked_delete(this); } - friend inline void intrusive_ptr_add_ref(const op_t * op) { - op->acquire(); - } - friend inline void intrusive_ptr_release(const op_t * op) { - op->release(); - } + friend void intrusive_ptr_add_ref(const op_t * op); + friend void intrusive_ptr_release(const op_t * op); ptr_op_t copy(ptr_op_t _left = NULL, ptr_op_t _right = NULL) const { ptr_op_t node(new_node(kind, _left, _right)); diff --git a/src/pool.cc b/src/pool.cc index ca50db2c..a6ae0919 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -70,9 +70,11 @@ commodity_t * commodity_pool_t::create(const string& symbol) DEBUG("pool.commodities", "Creating commodity '" << commodity->symbol() << "'"); - std::pair result - = commodities.insert(commodities_map::value_type - (commodity->base_symbol(), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + commodities.insert(commodities_map::value_type + (commodity->base_symbol(), commodity)); assert(result.second); commodity_price_history.add_commodity(*commodity.get()); @@ -211,10 +213,12 @@ commodity_pool_t::create(commodity_t& comm, << "symbol " << commodity->symbol() << std::endl << details); - std::pair result - = annotated_commodities.insert(annotated_commodities_map::value_type - (annotated_commodities_map::key_type - (comm.symbol(), details), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + annotated_commodities.insert(annotated_commodities_map::value_type + (annotated_commodities_map::key_type + (comm.symbol(), details), commodity)); assert(result.second); return commodity.get(); diff --git a/src/pyinterp.cc b/src/pyinterp.cc index d733c40d..d1f46580 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -535,6 +535,7 @@ namespace { case value_t::ANY: // a pointer to an arbitrary object return object(val); } + return object(); } } diff --git a/src/query.h b/src/query.h index f95988a7..7286e89b 100644 --- a/src/query.h +++ b/src/query.h @@ -186,6 +186,7 @@ public: assert(false); return ""; } + return ""; } void unexpected(); diff --git a/src/textual.cc b/src/textual.cc index cf15f048..258a4d76 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -107,10 +107,12 @@ namespace { return (in.good() && ! in.eof() && (in.peek() == ' ' || in.peek() == '\t')); } +#if defined(HAVE_BOOST_PYTHON) bool peek_blank_line() { return (in.good() && ! in.eof() && (in.peek() == '\n' || in.peek() == '\r')); } +#endif void read_next_directive(); @@ -943,9 +945,11 @@ void instance_t::account_alias_directive(account_t * account, string alias) // (account), add a reference to the account in the `account_aliases' // map, which is used by the post parser to resolve alias references. trim(alias); - std::pair result - = context.journal - ->account_aliases.insert(accounts_map::value_type(alias, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + context.journal->account_aliases.insert + (accounts_map::value_type(alias, account)); assert(result.second); } diff --git a/src/times.h b/src/times.h index 6eadcad3..edc6d8b8 100644 --- a/src/times.h +++ b/src/times.h @@ -218,6 +218,7 @@ struct date_duration_t case YEARS: return date + gregorian::years(length); } + return date_t(); } date_t subtract(const date_t& date) const { @@ -233,6 +234,7 @@ struct date_duration_t case YEARS: return date - gregorian::years(length); } + return date_t(); } string to_string() const { diff --git a/src/xact.cc b/src/xact.cc index 5cec9ab0..5c43558d 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -336,7 +336,9 @@ bool xact_base_t::finalize() amount_t> sorted_amounts_map; sorted_amounts_map samp; foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) { +#if defined(DEBUG_ON) std::pair result = +#endif samp.insert(sorted_amounts_map::value_type (sorted_amounts_map::key_type (pair.first->symbol(), -- cgit v1.2.3 From 65835a89ccbcb9c0a0297b4f7c6adbfd768dca84 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 05:21:40 -0600 Subject: Dump IDENT referral values in op_t::dump --- src/op.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 1889f2aa..b8893bc9 100644 --- a/src/op.cc +++ b/src/op.cc @@ -818,7 +818,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const // An identifier is a special non-terminal, in that its left() can // hold the compiled definition of the identifier. - if (kind > TERMINALS || is_scope()) { + if (kind > TERMINALS || is_scope() || is_ident()) { if (left()) { left()->dump(out, depth + 1); if (kind > UNARY_OPERATORS && has_right()) -- cgit v1.2.3 From b17b6cd9d42eda5db0ecf69d7fdef7f4e64d6cb1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 05:38:13 -0600 Subject: Fixed parameter and argument scoping for O_CALL nodes --- src/op.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- src/op.h | 4 +++- 2 files changed, 53 insertions(+), 16 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index b8893bc9..a8b71468 100644 --- a/src/op.cc +++ b/src/op.cc @@ -86,7 +86,8 @@ namespace { } } -expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) +expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, + scope_t * param_scope) { scope_t * scope_ptr = &scope; expr_t::ptr_op_t result; @@ -103,7 +104,12 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) if (is_ident()) { DEBUG("expr.compile", "Lookup: " << as_ident() << " in " << scope_ptr); - if (ptr_op_t def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident())) { + ptr_op_t def; + if (param_scope) + def = param_scope->lookup(symbol_t::FUNCTION, as_ident()); + if (! def) + def = scope_ptr->lookup(symbol_t::FUNCTION, as_ident()); + if (def) { // Identifier references are first looked up at the point of // definition, and then at the point of every use if they could // not be found there. @@ -133,7 +139,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) else if (kind == O_DEFINE) { switch (left()->kind) { case IDENT: { - ptr_op_t node(right()->compile(*scope_ptr, depth + 1)); + ptr_op_t node(right()->compile(*scope_ptr, depth + 1, param_scope)); DEBUG("expr.compile", "Defining " << left()->as_ident() << " in " << scope_ptr); @@ -146,12 +152,28 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) ptr_op_t node(new op_t(op_t::O_LAMBDA)); node->set_left(left()->right()); node->set_right(right()); - node = node->compile(*scope_ptr, depth + 1); + + empty_scope_t empty_scope; + symbol_scope_t params(param_scope ? *param_scope : 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, ¶ms); DEBUG("expr.compile", "Defining " << left()->left()->as_ident() << " in " << scope_ptr); - scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(), - node); + scope_ptr->define(symbol_t::FUNCTION, left()->left()->as_ident(), node); break; } // fall through... @@ -163,10 +185,10 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth) } if (! result) { - ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1)); + ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1, param_scope)); ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ? (kind == O_LOOKUP ? right() : - right()->compile(*scope_ptr, depth + 1)) : NULL); + right()->compile(*scope_ptr, depth + 1, param_scope)) : NULL); if (lhs == left() && (! rhs || rhs == right())) { result = this; @@ -220,7 +242,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) ptr_op_t definition = left(); // If no definition was pre-compiled for this identifier, look it up // in the current scope. - if (! definition) { + if (! definition || definition->kind == PLUG) { DEBUG("scope.symbols", "Looking for IDENT '" << as_ident() << "'"); definition = scope.lookup(symbol_t::FUNCTION, as_ident()); } @@ -308,7 +330,8 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) call_scope_t& call_args(find_scope(scope, true)); std::size_t args_count(call_args.size()); std::size_t args_index(0); - symbol_scope_t call_scope(call_args); + empty_scope_t empty_scope; + symbol_scope_t args_scope(empty_scope); for (ptr_op_t sym = left(); sym; @@ -318,13 +341,15 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) throw_(calc_error, _("Invalid function definition")); } else if (args_index == args_count) { - call_scope.define(symbol_t::FUNCTION, varname->as_ident(), + DEBUG("expr.compile", "Defining function argument as null: " + << varname->as_ident()); + args_scope.define(symbol_t::FUNCTION, varname->as_ident(), wrap_value(NULL_VALUE)); } else { - DEBUG("expr.compile", - "Defining function parameter " << varname->as_ident()); - call_scope.define(symbol_t::FUNCTION, varname->as_ident(), + DEBUG("expr.compile", "Defining function argument from call_args: " + << varname->as_ident()); + args_scope.define(symbol_t::FUNCTION, varname->as_ident(), wrap_value(call_args[args_index++])); } } @@ -334,7 +359,13 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) _("Too few arguments in function call (saw %1, wanted %2)") << args_count << args_index); - result = right()->calc(call_scope, locus, depth + 1); + if (right()->is_scope()) { + bind_scope_t outer_scope(scope, *right()->as_scope()); + bind_scope_t bound_scope(outer_scope, args_scope); + result = right()->left()->calc(bound_scope, locus, depth + 1); + } else { + result = right()->calc(args_scope, locus, depth + 1); + } break; } @@ -758,6 +789,10 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const out << " "; switch (kind) { + case PLUG: + out << "PLUG"; + break; + case VALUE: out << "VALUE: "; as_value().dump(out); diff --git a/src/op.h b/src/op.h index 8b914311..c93f218b 100644 --- a/src/op.h +++ b/src/op.h @@ -69,6 +69,7 @@ private: public: enum kind_t { // Constants + PLUG, VALUE, IDENT, @@ -274,7 +275,8 @@ public: static ptr_op_t new_node(kind_t _kind, ptr_op_t _left = NULL, ptr_op_t _right = NULL); - ptr_op_t compile(scope_t& scope, const int depth = 0); + ptr_op_t compile(scope_t& scope, const int depth = 0, + scope_t * param_scope = NULL); value_t calc(scope_t& scope, ptr_op_t * locus = NULL, const int depth = 0); -- cgit v1.2.3 From 7e250696e02e0392bc865f66570da296ced124ab Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 12:46:46 -0600 Subject: Many options now have additive effect For example, -A and -V used to override each other, whereas now: -A report the average amount -V report all amounts at current value -AV report the current value of the average -VA report the average of all current values --- src/chain.cc | 4 ++ src/filters.h | 12 +++--- src/global.cc | 1 + src/global.h | 1 + src/op.cc | 17 +++++---- src/report.h | 82 ++++++++++++++++++---------------------- src/scope.cc | 3 +- src/scope.h | 5 ++- test/baseline/opt-deviation.test | 2 +- test/baseline/opt-unround.test | 2 +- 10 files changed, 65 insertions(+), 64 deletions(-) (limited to 'src/op.cc') diff --git a/src/chain.cc b/src/chain.cc index 400b8f26..f8f0aeff 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -118,6 +118,10 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler, expr_t& expr(report.HANDLER(amount_).expr); expr.set_context(&report); + report.HANDLER(total_).expr.set_context(&report); + report.HANDLER(display_amount_).expr.set_context(&report); + report.HANDLER(display_total_).expr.set_context(&report); + if (! for_accounts_report) { // Make sure only forecast postings which match are allowed through if (report.HANDLED(forecast_while_)) { diff --git a/src/filters.h b/src/filters.h index 22f2d2cb..7be3acb9 100644 --- a/src/filters.h +++ b/src/filters.h @@ -65,14 +65,14 @@ protected: value_to_posts_map posts_map; post_handler_ptr post_chain; report_t& report; - expr_t group_by_expr; + expr_t& group_by_expr; custom_flusher_t preflush_func; optional postflush_func; public: post_splitter(post_handler_ptr _post_chain, report_t& _report, - expr_t _group_by_expr) + expr_t& _group_by_expr) : post_chain(_post_chain), report(_report), group_by_expr(_group_by_expr) { TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t"); @@ -521,8 +521,8 @@ class display_filter_posts : public item_handler // later in the chain. report_t& report; - expr_t display_amount_expr; - expr_t display_total_expr; + expr_t& display_amount_expr; + expr_t& display_total_expr; bool show_rounding; value_t last_display_total; temporaries_t temps; @@ -569,8 +569,8 @@ class changed_value_posts : public item_handler // later in the chain. report_t& report; - expr_t total_expr; - expr_t display_total_expr; + expr_t& total_expr; + expr_t& display_total_expr; bool changed_values_only; bool for_accounts_report; bool show_unrealized; diff --git a/src/global.cc b/src/global.cc index 5b7bb1c1..cc14c99e 100644 --- a/src/global.cc +++ b/src/global.cc @@ -70,6 +70,7 @@ global_scope_t::global_scope_t(char ** envp) // generated. report_stack.push_front(new report_t(*session_ptr)); scope_t::default_scope = &report(); + scope_t::empty_scope = &empty_scope; // Read the user's options, in the following order: // diff --git a/src/global.h b/src/global.h index ce0534b0..7429b1f5 100644 --- a/src/global.h +++ b/src/global.h @@ -50,6 +50,7 @@ class global_scope_t : public noncopyable, public scope_t { shared_ptr session_ptr; ptr_list report_stack; + empty_scope_t empty_scope; public: global_scope_t(char ** envp); diff --git a/src/op.cc b/src/op.cc index a8b71468..a5db1690 100644 --- a/src/op.cc +++ b/src/op.cc @@ -89,8 +89,9 @@ namespace { expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, scope_t * param_scope) { - scope_t * scope_ptr = &scope; - expr_t::ptr_op_t result; + scope_t * scope_ptr = &scope; + unique_ptr bound_scope; + expr_t::ptr_op_t result; #if defined(DEBUG_ON) if (SHOW_DEBUG("expr.compile")) { @@ -129,9 +130,10 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, } } else if (is_scope()) { - shared_ptr subscope(new symbol_scope_t(scope)); + shared_ptr subscope(new symbol_scope_t(*scope_t::empty_scope)); set_scope(subscope); - scope_ptr = subscope.get(); + bound_scope.reset(new bind_scope_t(*scope_ptr, *subscope.get())); + scope_ptr = bound_scope.get(); } else if (kind < TERMINALS) { result = this; @@ -153,8 +155,8 @@ 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()); - empty_scope_t empty_scope; - symbol_scope_t params(param_scope ? *param_scope : empty_scope); + 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) { @@ -330,8 +332,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) call_scope_t& call_args(find_scope(scope, true)); std::size_t args_count(call_args.size()); std::size_t args_index(0); - empty_scope_t empty_scope; - symbol_scope_t args_scope(empty_scope); + symbol_scope_t args_scope(*scope_t::empty_scope); for (ptr_op_t sym = left(); sym; diff --git a/src/report.h b/src/report.h index 9541da43..f50bdc28 100644 --- a/src/report.h +++ b/src/report.h @@ -366,12 +366,9 @@ public: OPTION__ (report_t, amount_, // -t - expr_t expr; - CTOR(report_t, amount_) { - set_expr(none, "amount"); - } + DECL1(report_t, amount_, merged_expr_t, expr, ("amount_expr", "amount")) {} void set_expr(const optional& whence, const string& str) { - expr = str; + expr.append(str); on(whence, str); } DO_(args) { @@ -384,7 +381,7 @@ public: OPTION_(report_t, average, DO() { // -A parent->HANDLER(display_total_) - .set_expr(string("--average"), "count>0?(total_expr/count):0"); + .set_expr(string("--average"), "count>0?(display_total/count):0"); }); OPTION__(report_t, balance_format_, CTOR(report_t, balance_format_) { @@ -405,7 +402,7 @@ public: OPTION_(report_t, basis, DO() { // -B parent->HANDLER(revalued).on_only(string("--basis")); - parent->HANDLER(amount_).set_expr(string("--basis"), "rounded(cost)"); + parent->HANDLER(amount_).expr.set_base_expr("rounded(cost)"); }); OPTION_(report_t, begin_, DO_(args) { // -b @@ -438,20 +435,20 @@ public: OPTION__(report_t, budget_format_, CTOR(report_t, budget_format_) { on(none, - "%(justify(scrub(get_at(total_expr, 0)), 12, -1, true, color))" - " %(justify(-scrub(get_at(total_expr, 1)), 12, " + "%(justify(scrub(get_at(display_total, 0)), 12, -1, true, color))" + " %(justify(-scrub(get_at(display_total, 1)), 12, " " 12 + 1 + 12, true, color))" - " %(justify(scrub(get_at(total_expr, 1) + " - " get_at(total_expr, 0)), 12, " + " %(justify(scrub(get_at(display_total, 1) + " + " get_at(display_total, 0)), 12, " " 12 + 1 + 12 + 1 + 12, true, color))" " %(ansify_if(" - " justify((get_at(total_expr, 1) ? " - " (100% * scrub(get_at(total_expr, 0))) / " - " -scrub(get_at(total_expr, 1)) : 0), " + " justify((get_at(display_total, 1) ? " + " (100% * scrub(get_at(display_total, 0))) / " + " -scrub(get_at(display_total, 1)) : 0), " " 5, -1, true, false)," - " magenta if (color and get_at(total_expr, 1) and " - " (abs(quantity(scrub(get_at(total_expr, 0))) / " - " quantity(scrub(get_at(total_expr, 1)))) >= 1))))" + " magenta if (color and get_at(display_total, 1) and " + " (abs(quantity(scrub(get_at(display_total, 0))) / " + " quantity(scrub(get_at(display_total, 1)))) >= 1))))" " %(!options.flat ? depth_spacer : \"\")" "%-(ansify_if(partial_account(options.flat), blue if color))\n" "%/%$1 %$2 %$3 %$4\n%/" @@ -467,8 +464,8 @@ public: OPTION__(report_t, cleared_format_, CTOR(report_t, cleared_format_) { on(none, - "%(justify(scrub(get_at(total_expr, 0)), 16, 16 + prepend_width, " - " true, color)) %(justify(scrub(get_at(total_expr, 1)), 18, " + "%(justify(scrub(get_at(display_total, 0)), 16, 16 + prepend_width, " + " true, color)) %(justify(scrub(get_at(display_total, 1)), 18, " " 36 + prepend_width, true, color))" " %(latest_cleared ? format_date(latest_cleared) : \" \")" " %(!options.flat ? depth_spacer : \"\")" @@ -524,7 +521,7 @@ public: OPTION_(report_t, deviation, DO() { parent->HANDLER(display_total_) - .set_expr(string("--deviation"), "amount_expr-total_expr/count"); + .set_expr(string("--deviation"), "display_amount-display_total"); }); OPTION__ @@ -541,12 +538,10 @@ public: OPTION__ (report_t, display_amount_, - expr_t expr; - CTOR(report_t, display_amount_) { - set_expr(none, "amount_expr"); - } + DECL1(report_t, display_amount_, merged_expr_t, expr, + ("display_amount", "amount_expr")) {} void set_expr(const optional& whence, const string& str) { - expr = str; + expr.append(str); on(whence, str); } DO_(args) { @@ -555,12 +550,10 @@ public: OPTION__ (report_t, display_total_, - expr_t expr; - CTOR(report_t, display_total_) { - set_expr(none, "total_expr"); - } + DECL1(report_t, display_total_, merged_expr_t, expr, + ("display_total", "total_expr")) {} void set_expr(const optional& whence, const string& str) { - expr = str; + expr.append(str); on(whence, str); } DO_(args) { @@ -608,7 +601,10 @@ public: OPTION_(report_t, gain, DO() { // -G parent->HANDLER(revalued).on_only(string("--gain")); - parent->HANDLER(amount_).set_expr(string("--gain"), "(amount, cost)"); + + parent->HANDLER(amount_).expr.set_base_expr("(amount, cost)"); + parent->HANDLER(total_).expr.set_base_expr("total"); + // Since we are displaying the amounts of revalued postings, they // will end up being composite totals, and hence a pair of pairs. parent->HANDLER(display_amount_) @@ -676,10 +672,10 @@ public: parent->HANDLER(revalued).on_only(string("--market")); parent->HANDLER(display_amount_) .set_expr(string("--market"), - "market(amount_expr, value_date, exchange)"); + "market(display_amount, value_date, exchange)"); parent->HANDLER(display_total_) .set_expr(string("--market"), - "market(total_expr, value_date, exchange)"); + "market(display_total, value_date, exchange)"); }); OPTION(report_t, meta_); @@ -802,10 +798,7 @@ public: }); OPTION_(report_t, price, DO() { // -I - parent->HANDLER(display_amount_) - .set_expr(string("--price"), "price(amount_expr)"); - parent->HANDLER(display_total_) - .set_expr(string("--price"), "price(total_expr)"); + parent->HANDLER(amount_).expr.set_base_expr("price"); }); OPTION__(report_t, prices_format_, CTOR(report_t, prices_format_) { @@ -823,8 +816,8 @@ public: OPTION_(report_t, quantity, DO() { // -O parent->HANDLER(revalued).off(); - parent->HANDLER(amount_).set_expr(string("--quantity"), "amount"); - parent->HANDLER(total_).set_expr(string("--quantity"), "total"); + parent->HANDLER(amount_).expr.set_base_expr("amount"); + parent->HANDLER(total_).expr.set_base_expr("total"); }); OPTION_(report_t, quarterly, DO() { @@ -919,12 +912,9 @@ public: OPTION__ (report_t, total_, // -T - expr_t expr; - CTOR(report_t, total_) { - set_expr(none, "total"); - } + DECL1(report_t, total_, merged_expr_t, expr, ("total_expr", "total")) {} void set_expr(const optional& whence, const string& str) { - expr = str; + expr.append(str); on(whence, str); } DO_(args) { @@ -961,9 +951,9 @@ public: OPTION(report_t, unrealized_losses_); OPTION_(report_t, unround, DO() { - parent->HANDLER(display_amount_) + parent->HANDLER(amount_) .set_expr(string("--unround"), "unrounded(amount_expr)"); - parent->HANDLER(display_total_) + parent->HANDLER(total_) .set_expr(string("--unround"), "unrounded(total_expr)"); }); diff --git a/src/scope.cc b/src/scope.cc index 160a97c9..00327159 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -35,7 +35,8 @@ namespace ledger { -scope_t * scope_t::default_scope = NULL; +scope_t * scope_t::default_scope = NULL; +empty_scope_t * scope_t::empty_scope = NULL; void symbol_scope_t::define(const symbol_t::kind_t kind, const string& name, expr_t::ptr_op_t def) diff --git a/src/scope.h b/src/scope.h index 75dc2c0f..31ef61cb 100644 --- a/src/scope.h +++ b/src/scope.h @@ -99,10 +99,13 @@ private: #endif // HAVE_BOOST_SERIALIZATION }; +class empty_scope_t; + class scope_t { public: - static scope_t * default_scope; + static scope_t * default_scope; + static empty_scope_t * empty_scope; explicit scope_t() { TRACE_CTOR(scope_t, ""); diff --git a/test/baseline/opt-deviation.test b/test/baseline/opt-deviation.test index df216b9c..a677ff6e 100644 --- a/test/baseline/opt-deviation.test +++ b/test/baseline/opt-deviation.test @@ -190,7 +190,7 @@ Expenses:Books $120.00 Assets:Cash -test reg --deviation books +test reg -A --deviation books 08-Jan-01 January Expenses:Books $10.00 0 08-Jan-31 End of January Expenses:Books $10.00 0 08-Feb-01 February Expenses:Books $20.00 $6.67 diff --git a/test/baseline/opt-unround.test b/test/baseline/opt-unround.test index cef212ae..755bb62c 100644 --- a/test/baseline/opt-unround.test +++ b/test/baseline/opt-unround.test @@ -82,7 +82,7 @@ Expenses:Travel:Passport $127.00 Assets:Checking -test bal --unround --percent +test bal --percent --unround 100.00% Assets:Checking 100.00% Expenses:Travel 92.14958953% Airfare -- cgit v1.2.3 From ae4ef7a88ddd39ed544383e65d3c55ba97f4f8c1 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 21:22:07 -0600 Subject: More work done on proper evaluation of lambdas --- src/op.cc | 42 +++++++++++++++++++++++++----------------- src/parser.cc | 4 +++- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src/op.cc') 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, ¶ms); + 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, ¶ms)); + if (rhs == right()) + result = this; + else + result = copy(left(), rhs); + } if (! result) { ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1, param_scope)); diff --git a/src/parser.cc b/src/parser.cc index b3f50e41..ce70a49e 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -485,7 +485,9 @@ expr_t::parser_t::parse_lambda_expr(std::istream& in, ptr_op_t prev(node); node = new op_t(op_t::O_LAMBDA); node->set_left(prev); - node->set_right(parse_querycolon_expr(in, tflags)); + ptr_op_t scope(new op_t(op_t::SCOPE)); + scope->set_left(parse_querycolon_expr(in, tflags)); + node->set_right(scope); } else { push_token(tok); } -- cgit v1.2.3 From 4d011434003262c9a49b0b4636b2ac479a84e058 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 8 Mar 2012 00:44:27 -0600 Subject: Many improvements to lambdas and function calling --- src/op.cc | 340 ++++++++++++++++++++++++++---------------- src/op.h | 8 + src/parser.cc | 3 - test/baseline/cmd-script.test | 4 + 4 files changed, 223 insertions(+), 132 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 6a1a8f54..0773c093 100644 --- a/src/op.cc +++ b/src/op.cc @@ -178,7 +178,10 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, ptr_op_t varname = sym->kind == O_CONS ? sym->left() : sym; if (! varname->is_ident()) { - throw_(calc_error, _("Invalid function or lambda parameter")); + std::ostringstream buf; + varname->dump(buf, 0); + throw_(calc_error, + _("Invalid function or lambda parameter: %1") << buf.str()); } else { DEBUG("expr.compile", "Defining function parameter " << varname->as_ident()); @@ -224,6 +227,23 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, return result; } +namespace { + expr_t::ptr_op_t lookup_ident(expr_t::ptr_op_t op, scope_t& scope) + { + expr_t::ptr_op_t def = op->left(); + + // If no definition was pre-compiled for this identifier, look it up + // in the current scope. + if (! def || def->kind == expr_t::op_t::PLUG) { + DEBUG("scope.symbols", "Looking for IDENT '" << op->as_ident() << "'"); + def = scope.lookup(symbol_t::FUNCTION, op->as_ident()); + } + if (! def) + throw_(calc_error, _("Unknown identifier '%1'") << op->as_ident()); + return def; + } +} + value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) { try { @@ -248,23 +268,14 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) result = NULL_VALUE; break; - case IDENT: { - ptr_op_t definition = left(); - // If no definition was pre-compiled for this identifier, look it up - // in the current scope. - if (! definition || definition->kind == PLUG) { - DEBUG("scope.symbols", "Looking for IDENT '" << as_ident() << "'"); - definition = scope.lookup(symbol_t::FUNCTION, as_ident()); + case IDENT: + if (ptr_op_t definition = lookup_ident(this, scope)) { + // Evaluating an identifier is the same as calling its definition + // directly + result = definition->calc(scope, locus, depth + 1); + check_type_context(scope, result); } - if (! definition) - throw_(calc_error, _("Unknown identifier '%1'") << as_ident()); - - // Evaluating an identifier is the same as calling its definition - // directly - result = definition->calc(scope, locus, depth + 1); - check_type_context(scope, result); break; - } case FUNCTION: { // Evaluating a FUNCTION is the same as calling it directly; this @@ -302,81 +313,14 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; } - case O_CALL: { - ptr_op_t func = left(); - string name; - - if (func->is_ident()) { - name = func->as_ident(); - func = func->left(); - if (! func) - func = scope.lookup(symbol_t::FUNCTION, name); - if (! func) - throw_(calc_error, _("Calling unknown function '%1'") << name); - } else { - name = ""; - } - - call_scope_t call_args(scope, locus, depth + 1); - if (has_right()) - call_args.set_args(split_cons_expr(right())); - - try { - if (func->is_function()) - result = func->as_function()(call_args); - else - result = func->calc(call_args, locus, depth + 1); - } - catch (const std::exception&) { - add_error_context(_("While calling function '%1':" << name)); - throw; - } - + case O_CALL: + result = calc_call(scope, locus, depth); check_type_context(scope, result); break; - } - - case O_LAMBDA: { - call_scope_t& call_args(find_scope(scope, true)); - std::size_t args_count(call_args.size()); - std::size_t args_index(0); - symbol_scope_t args_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 definition")); - } - else if (args_index == args_count) { - DEBUG("expr.compile", "Defining function argument as null: " - << varname->as_ident()); - args_scope.define(symbol_t::FUNCTION, varname->as_ident(), - wrap_value(NULL_VALUE)); - } - else { - DEBUG("expr.compile", "Defining function argument from call_args: " - << varname->as_ident()); - args_scope.define(symbol_t::FUNCTION, varname->as_ident(), - wrap_value(call_args[args_index++])); - } - } - if (args_index < args_count) - throw_(calc_error, - _("Too few arguments in function call (saw %1, wanted %2)") - << args_count << args_index); - - if (right()->is_scope()) { - bind_scope_t outer_scope(scope, *right()->as_scope()); - bind_scope_t bound_scope(outer_scope, args_scope); - result = right()->left()->calc(bound_scope, locus, depth + 1); - } else { - result = right()->calc(args_scope, locus, depth + 1); - } + case O_LAMBDA: + result = expr_value(this); break; - } case O_MATCH: result = (right()->calc(scope, locus, depth + 1).as_mask() @@ -457,51 +401,12 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; case O_CONS: - result = left()->calc(scope, locus, depth + 1); - if (has_right()) { - value_t temp; - temp.push_back(result); - - ptr_op_t next = right(); - while (next) { - ptr_op_t value_op; - if (next->kind == O_CONS) { - value_op = next->left(); - next = next->has_right() ? next->right() : NULL; - } else { - value_op = next; - next = NULL; - } - temp.push_back(value_op->calc(scope, locus, depth + 1)); - } - result = temp; - } + result = calc_cons(scope, locus, depth); break; - case O_SEQ: { - // An O_SEQ is very similar to an O_CONS except that only the last - // result value in the series is kept. O_CONS builds up a list. - // - // Another feature of O_SEQ is that it pushes a new symbol scope - // onto the stack. We evaluate the left side here to catch any - // side-effects, such as definitions in the case of 'x = 1; x'. - result = left()->calc(scope, locus, depth + 1); - if (has_right()) { - ptr_op_t next = right(); - while (next) { - ptr_op_t value_op; - if (next->kind == O_SEQ) { - value_op = next->left(); - next = next->right(); - } else { - value_op = next; - next = NULL; - } - result = value_op->calc(scope, locus, depth + 1); - } - } + case O_SEQ: + result = calc_seq(scope, locus, depth); break; - } default: throw_(calc_error, _("Unexpected expr node '%1'") << op_context(this)); @@ -527,6 +432,183 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) } } +namespace { + expr_t::ptr_op_t find_definition(expr_t::ptr_op_t op, scope_t& scope, + expr_t::ptr_op_t * locus, const int depth, + int recursion_depth = 0) + { + // If the object we are apply call notation to is a FUNCTION value + // or a O_LAMBDA expression, then this is the object we want to + // call. + if (op->is_function() || op->kind == expr_t::op_t::O_LAMBDA) + return op; + + if (recursion_depth > 256) + throw_(value_error, _("Function recursion_depth too deep (> 256)")); + + // If it's an identifier, look up its definition and see if it's a + // function. + if (op->is_ident()) + return find_definition(lookup_ident(op, scope), scope, + locus, depth, recursion_depth + 1); + + // Value objects might be callable if they contain an expression. + if (op->is_value()) { + value_t def(op->as_value()); + if (is_expr(def)) + return find_definition(as_expr(def), scope, locus, depth, + recursion_depth + 1); + else + throw_(value_error, _("Cannot call %1 as a function") << def.label()); + } + + // Resolve ordinary expressions. + return find_definition(expr_t::op_t::wrap_value(op->calc(scope, locus, + depth + 1)), + scope, locus, depth + 1, recursion_depth + 1); + } + + value_t call_lambda(expr_t::ptr_op_t func, scope_t& scope, + call_scope_t& call_args, expr_t::ptr_op_t * locus, + const int depth) + { + std::size_t args_index(0); + std::size_t args_count(call_args.size()); + + symbol_scope_t args_scope(*scope_t::empty_scope); + + for (expr_t::ptr_op_t sym = func->left(); + sym; + sym = sym->has_right() ? sym->right() : NULL) { + expr_t::ptr_op_t varname = + sym->kind == expr_t::op_t::O_CONS ? sym->left() : sym; + if (! varname->is_ident()) { + throw_(calc_error, _("Invalid function definition")); + } + else if (args_index == args_count) { + DEBUG("expr.calc", "Defining function argument as null: " + << varname->as_ident()); + args_scope.define(symbol_t::FUNCTION, varname->as_ident(), + expr_t::op_t::wrap_value(NULL_VALUE)); + } + else { + DEBUG("expr.calc", "Defining function argument from call_args: " + << varname->as_ident()); + args_scope.define(symbol_t::FUNCTION, varname->as_ident(), + expr_t::op_t::wrap_value(call_args[args_index++])); + } + } + + if (args_index < args_count) + throw_(calc_error, + _("Too few arguments in function call (saw %1, wanted %2)") + << args_count << args_index); + + if (func->right()->is_scope()) { + bind_scope_t outer_scope(scope, *func->right()->as_scope()); + bind_scope_t bound_scope(outer_scope, args_scope); + + return func->right()->left()->calc(bound_scope, locus, depth + 1); + } else { + return func->right()->calc(args_scope, locus, depth + 1); + } + } +} + + +value_t expr_t::op_t::call(const value_t& args, scope_t& scope, + ptr_op_t * locus, const int depth) +{ + call_scope_t call_args(scope, locus, depth + 1); + call_args.set_args(args); + + if (is_function()) + return as_function()(call_args); + else if (kind == O_LAMBDA) + return call_lambda(this, scope, call_args, locus, depth); + else + return find_definition(this, scope, locus, depth) + ->calc(call_args, locus, depth); +} + +value_t expr_t::op_t::calc_call(scope_t& scope, ptr_op_t * locus, + const int depth) +{ + ptr_op_t func = left(); + string name = func->is_ident() ? func->as_ident() : ""; + + try { + func = find_definition(func, scope, locus, depth); + + call_scope_t call_args(scope, locus, depth + 1); + if (has_right()) + call_args.set_args(split_cons_expr(right())); + + if (func->is_function()) { + return func->as_function()(call_args); + } else { + assert(func->kind == O_LAMBDA); + return call_lambda(func, scope, call_args, locus, depth); + } + } + catch (const std::exception&) { + add_error_context(_("While calling function '%1':" << name)); + throw; + } +} + +value_t expr_t::op_t::calc_cons(scope_t& scope, ptr_op_t * locus, + const int depth) +{ + value_t result = left()->calc(scope, locus, depth + 1); + if (has_right()) { + value_t temp; + temp.push_back(result); + + ptr_op_t next = right(); + while (next) { + ptr_op_t value_op; + if (next->kind == O_CONS) { + value_op = next->left(); + next = next->has_right() ? next->right() : NULL; + } else { + value_op = next; + next = NULL; + } + temp.push_back(value_op->calc(scope, locus, depth + 1)); + } + result = temp; + } + return result; +} + +value_t expr_t::op_t::calc_seq(scope_t& scope, ptr_op_t * locus, + const int depth) +{ + // An O_SEQ is very similar to an O_CONS except that only the last + // result value in the series is kept. O_CONS builds up a list. + // + // Another feature of O_SEQ is that it pushes a new symbol scope onto + // the stack. We evaluate the left side here to catch any + // side-effects, such as definitions in the case of 'x = 1; x'. + value_t result = left()->calc(scope, locus, depth + 1); + if (has_right()) { + ptr_op_t next = right(); + while (next) { + ptr_op_t value_op; + if (next->kind == O_SEQ) { + value_op = next->left(); + next = next->right(); + } else { + value_op = next; + next = NULL; + } + result = value_op->calc(scope, locus, depth + 1); + } + } + return result; +} + namespace { bool print_cons(std::ostream& out, const expr_t::const_ptr_op_t op, const expr_t::op_t::context_t& context) diff --git a/src/op.h b/src/op.h index c93f218b..03fcf816 100644 --- a/src/op.h +++ b/src/op.h @@ -280,6 +280,9 @@ public: value_t calc(scope_t& scope, ptr_op_t * locus = NULL, const int depth = 0); + value_t call(const value_t& args, scope_t& scope, + ptr_op_t * locus = NULL, const int depth = 0); + struct context_t { ptr_op_t expr_op; @@ -307,6 +310,11 @@ public: static ptr_op_t wrap_functor(expr_t::func_t fobj); static ptr_op_t wrap_scope(shared_ptr sobj); +private: + value_t calc_call(scope_t& scope, ptr_op_t * locus, const int depth); + value_t calc_cons(scope_t& scope, ptr_op_t * locus, const int depth); + value_t calc_seq(scope_t& scope, ptr_op_t * locus, const int depth); + #if defined(HAVE_BOOST_SERIALIZATION) private: /** Serialization. */ diff --git a/src/parser.cc b/src/parser.cc index ce70a49e..360ac93d 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -87,9 +87,6 @@ expr_t::parser_t::parse_call_expr(std::istream& in, node->set_left(prev); push_token(tok); // let the parser see the '(' again node->set_right(parse_value_expr(in, tflags.plus_flags(PARSE_SINGLE))); - if (! node->right()) - throw_(parse_error, - _("%1 operator not followed by argument") << tok.symbol); } else { push_token(tok); break; diff --git a/test/baseline/cmd-script.test b/test/baseline/cmd-script.test index ce920ebb..b33dd82d 100644 --- a/test/baseline/cmd-script.test +++ b/test/baseline/cmd-script.test @@ -15,3 +15,7 @@ test eval 'foo = x, y, z -> print(x, y, z); foo(1, 2, 3)' 123 1 end test + +test eval 'foo(x,y)=y(1, 2, 3);foo(amount_expr, (s,d,t -> t))' +3 +end test -- cgit v1.2.3 From 2a41649584c731024c3d3331b8a4a5f4011b9693 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 11 Mar 2012 03:05:33 -0500 Subject: Improve error reporting of nested function calls --- src/op.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 0773c093..23f47f73 100644 --- a/src/op.cc +++ b/src/op.cc @@ -537,13 +537,13 @@ value_t expr_t::op_t::calc_call(scope_t& scope, ptr_op_t * locus, ptr_op_t func = left(); string name = func->is_ident() ? func->as_ident() : ""; - try { - func = find_definition(func, scope, locus, depth); + func = find_definition(func, scope, locus, depth); - call_scope_t call_args(scope, locus, depth + 1); - if (has_right()) - call_args.set_args(split_cons_expr(right())); + call_scope_t call_args(scope, locus, depth + 1); + if (has_right()) + call_args.set_args(split_cons_expr(right())); + try { if (func->is_function()) { return func->as_function()(call_args); } else { @@ -552,7 +552,8 @@ value_t expr_t::op_t::calc_call(scope_t& scope, ptr_op_t * locus, } } catch (const std::exception&) { - add_error_context(_("While calling function '%1':" << name)); + add_error_context(_("While calling function '%1 %2':" << name + << call_args.args)); throw; } } -- cgit v1.2.3 From e65fc729bc4d8adaa66b3fd702f93ef790155543 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 13 Mar 2012 10:33:51 -0500 Subject: Made split_cons_expr a global function --- src/op.cc | 42 +++++++++++++++++++++--------------------- src/op.h | 2 ++ 2 files changed, 23 insertions(+), 21 deletions(-) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 23f47f73..7f2418b1 100644 --- a/src/op.cc +++ b/src/op.cc @@ -48,31 +48,31 @@ void intrusive_ptr_release(const expr_t::op_t * op) op->release(); } -namespace { - value_t split_cons_expr(expr_t::ptr_op_t op) - { - if (op->kind == expr_t::op_t::O_CONS) { - value_t seq; - seq.push_back(expr_value(op->left())); - - expr_t::ptr_op_t next = op->right(); - while (next) { - expr_t::ptr_op_t value_op; - if (next->kind == expr_t::op_t::O_CONS) { - value_op = next->left(); - next = next->has_right() ? next->right() : NULL; - } else { - value_op = next; - next = NULL; - } - seq.push_back(expr_value(value_op)); +value_t split_cons_expr(expr_t::ptr_op_t op) +{ + if (op->kind == expr_t::op_t::O_CONS) { + value_t seq; + seq.push_back(expr_value(op->left())); + + expr_t::ptr_op_t next = op->right(); + while (next) { + expr_t::ptr_op_t value_op; + if (next->kind == expr_t::op_t::O_CONS) { + value_op = next->left(); + next = next->has_right() ? next->right() : NULL; + } else { + value_op = next; + next = NULL; } - return seq; - } else { - return expr_value(op); + seq.push_back(expr_value(value_op)); } + return seq; + } else { + return expr_value(op); } +} +namespace { inline void check_type_context(scope_t& scope, value_t& result) { if (scope.type_required() && diff --git a/src/op.h b/src/op.h index 03fcf816..973ba67f 100644 --- a/src/op.h +++ b/src/op.h @@ -371,6 +371,8 @@ expr_t::op_t::wrap_functor(expr_t::func_t fobj) { string op_context(const expr_t::ptr_op_t op, const expr_t::ptr_op_t locus = NULL); +value_t split_cons_expr(expr_t::ptr_op_t op); + } // namespace ledger #endif // _OP_H -- cgit v1.2.3 From 927d404ad5d145bbcc58e0a4f9ee5d5df0637160 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 13 Mar 2012 10:33:59 -0500 Subject: Added a syntax error check --- src/op.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/op.cc') diff --git a/src/op.cc b/src/op.cc index 7f2418b1..8be0796a 100644 --- a/src/op.cc +++ b/src/op.cc @@ -198,6 +198,9 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth, } if (! result) { + if (! left()) + throw_(calc_error, _("Syntax error")); + ptr_op_t lhs(left()->compile(*scope_ptr, depth + 1, param_scope)); ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ? (kind == O_LOOKUP ? right() : -- cgit v1.2.3