diff options
author | John Wiegley <johnw@newartisans.com> | 2010-06-13 05:02:14 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-06-13 05:02:14 -0400 |
commit | ea1642b3f969463a49e5a671478c92e4ef129665 (patch) | |
tree | 9eba47b8708123b4e3f539dd9d747f1f85d9d2fe /src/op.cc | |
parent | ad3b30a9641b8e09c38ea76e7011b614152d8faf (diff) | |
download | fork-ledger-ea1642b3f969463a49e5a671478c92e4ef129665.tar.gz fork-ledger-ea1642b3f969463a49e5a671478c92e4ef129665.tar.bz2 fork-ledger-ea1642b3f969463a49e5a671478c92e4ef129665.zip |
Completely reworked argument passing in expressions
Diffstat (limited to 'src/op.cc')
-rw-r--r-- | src/op.cc | 52 |
1 files changed, 16 insertions, 36 deletions
@@ -39,15 +39,11 @@ namespace ledger { namespace { - value_t split_cons_expr(expr_t::ptr_op_t op, - scope_t& scope, - std::vector<expr_t>& exprs) + value_t split_cons_expr(expr_t::ptr_op_t op) { - value_t seq; - if (op->kind == expr_t::op_t::O_CONS) { - exprs.push_back(expr_t(op->left(), &scope)); - seq.push_back(value_t(exprs.back())); + value_t seq; + seq.push_back(expr_value(op->left())); expr_t::ptr_op_t next = op->right(); while (next) { @@ -59,19 +55,18 @@ namespace { value_op = next; next = NULL; } - exprs.push_back(expr_t(value_op, &scope)); - seq.push_back(value_t(exprs.back())); + seq.push_back(expr_value(value_op)); } + return seq; } else { - exprs.push_back(expr_t(op, &scope)); - seq.push_back(value_t(exprs.back())); + return expr_value(op); } - return seq; } - void check_type_context(scope_t& scope, value_t& result) + inline void check_type_context(scope_t& scope, value_t& result) { - if (scope.type_context() != value_t::VOID && + if (scope.type_required() && + scope.type_context() != value_t::VOID && result.type() != scope.type_context()) { throw_(calc_error, _("Expected return of %1, but received %2") @@ -162,7 +157,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) // 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, scope.type_context()); + call_scope_t call_args(scope, scope.type_context(), scope.type_required()); result = left()->compile(call_args, depth + 1) ->calc(call_args, locus, depth + 1); check_type_context(scope, result); @@ -173,7 +168,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int 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, scope.type_context()); + call_scope_t call_args(scope, scope.type_context(), scope.type_required()); result = as_function()(call_args); check_type_context(scope, result); #if defined(DEBUG_ON) @@ -239,24 +234,11 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth) break; } - case O_CALL: - case O_EXPAND: { - call_scope_t call_args(scope, scope.type_context()); - // When evaluating a macro call, these expressions have to live beyond the - // call to calc() below. - optional<std::vector<expr_t> > args_expr; - - if (has_right()) { - if (kind == O_CALL) { - call_args.set_args(right()->calc(scope, locus, depth + 1)); - } else { - // macros defer calculation to the callee - args_expr = std::vector<expr_t>(); - call_args.set_args(split_cons_expr(right()->kind == O_SEQ ? - right()->left() : right(), - scope, *args_expr)); - } - } + case O_CALL: { + call_scope_t call_args(scope, scope.type_context(), scope.type_required()); + if (has_right()) + call_args.set_args(split_cons_expr(right()->kind == O_SEQ ? + right()->left() : right())); ptr_op_t func = left(); const string& name(func->as_ident()); @@ -656,7 +638,6 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const break; case O_CALL: - case O_EXPAND: if (left() && left()->print(out, context)) found = true; if (has_right()) { @@ -728,7 +709,6 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const case O_DEFINE: out << "O_DEFINE"; break; case O_LOOKUP: out << "O_LOOKUP"; break; case O_CALL: out << "O_CALL"; break; - case O_EXPAND: out << "O_EXPAND"; break; case O_MATCH: out << "O_MATCH"; break; case O_NOT: out << "O_NOT"; break; |