summaryrefslogtreecommitdiff
path: root/src/op.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-06-13 05:02:14 -0400
committerJohn Wiegley <johnw@newartisans.com>2010-06-13 05:02:14 -0400
commitea1642b3f969463a49e5a671478c92e4ef129665 (patch)
tree9eba47b8708123b4e3f539dd9d747f1f85d9d2fe /src/op.cc
parentad3b30a9641b8e09c38ea76e7011b614152d8faf (diff)
downloadfork-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.cc52
1 files changed, 16 insertions, 36 deletions
diff --git a/src/op.cc b/src/op.cc
index 0feb157f..c2001ec3 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -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;