Report error context in expressions more precisely

This commit is contained in:
John Wiegley 2010-06-13 18:39:26 -04:00
parent 7708ed1a75
commit 2ea075dc4f
6 changed files with 27 additions and 17 deletions

View file

@ -295,7 +295,7 @@ namespace {
foreach (post_t * p, account.posts) {
bind_scope_t bound_scope(args, *p);
if (expr->calc(bound_scope).to_boolean())
if (expr->calc(bound_scope, args.locus, args.depth).to_boolean())
return true;
}
return false;
@ -308,7 +308,7 @@ namespace {
foreach (post_t * p, account.posts) {
bind_scope_t bound_scope(args, *p);
if (! expr->calc(bound_scope).to_boolean())
if (! expr->calc(bound_scope, args.locus, args.depth).to_boolean())
return false;
}
return true;

View file

@ -157,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(), scope.type_required());
call_scope_t call_args(scope, locus, depth);
result = left()->compile(call_args, depth + 1)
->calc(call_args, locus, depth + 1);
check_type_context(scope, result);
@ -168,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(), scope.type_required());
call_scope_t call_args(scope, locus, depth);
result = as_function()(call_args);
check_type_context(scope, result);
#if defined(DEBUG_ON)
@ -235,7 +235,7 @@ 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, scope.type_context(), scope.type_required());
call_scope_t call_args(scope, locus, depth);
if (has_right())
call_args.set_args(split_cons_expr(right()->kind == O_SEQ ?
right()->left() : right()));

View file

@ -353,12 +353,14 @@ namespace {
foreach (post_t * p, post.xact->posts) {
bind_scope_t bound_scope(args, *p);
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
! args.get<expr_t::ptr_op_t>(1)->calc(bound_scope).to_boolean()) {
! args.get<expr_t::ptr_op_t>(1)
->calc(bound_scope, args.locus, args.depth).to_boolean()) {
// If the user specifies any(EXPR, false), and the context is a
// posting, then that posting isn't considered by the test.
; // skip it
}
else if (expr->calc(bound_scope).to_boolean()) {
else if (expr->calc(bound_scope, args.locus,
args.depth).to_boolean()) {
return true;
}
}
@ -373,12 +375,14 @@ namespace {
foreach (post_t * p, post.xact->posts) {
bind_scope_t bound_scope(args, *p);
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
! args.get<expr_t::ptr_op_t>(1)->calc(bound_scope).to_boolean()) {
! args.get<expr_t::ptr_op_t>(1)
->calc(bound_scope, args.locus, args.depth).to_boolean()) {
// If the user specifies any(EXPR, false), and the context is a
// posting, then that posting isn't considered by the test.
; // skip it
}
else if (! expr->calc(bound_scope).to_boolean()) {
else if (! expr->calc(bound_scope, args.locus,
args.depth).to_boolean()) {
return false;
}
}

View file

@ -81,7 +81,7 @@ value_t& call_scope_t::resolve(const std::size_t index,
value_t& value(args[index]);
if (value.is_any()) {
context_scope_t scope(*this, context, required);
value = as_expr(value)->calc(scope);
value = as_expr(value)->calc(scope, locus, depth);
if (required && ! value.is_type(context))
throw_(calc_error, _("Expected %1 for argument %2, but received %3")
<< value.label(context) << index

View file

@ -335,11 +335,17 @@ class call_scope_t : public context_scope_t
const bool required = false);
public:
explicit call_scope_t(scope_t& _parent,
value_t::type_t _type_context = value_t::VOID,
const bool _required = true)
: context_scope_t(_parent, _type_context, _required), ptr(NULL) {
TRACE_CTOR(call_scope_t, "scope_t&, value_t::type_t, bool");
expr_t::ptr_op_t * locus;
const int depth;
explicit call_scope_t(scope_t& _parent,
expr_t::ptr_op_t * _locus = NULL,
const int _depth = 0)
: context_scope_t(_parent, _parent.type_context(),
_parent.type_required()),
ptr(NULL), locus(_locus), depth(_depth) {
TRACE_CTOR(call_scope_t,
"scope_t&, value_t::type_t, bool, expr_t::ptr_op_t *, int");
}
virtual ~call_scope_t() {
TRACE_DTOR(call_scope_t);

View file

@ -509,7 +509,7 @@ namespace {
foreach (post_t * p, post.xact->posts) {
bind_scope_t bound_scope(args, *p);
if (expr->calc(bound_scope).to_boolean())
if (expr->calc(bound_scope, args.locus, args.depth).to_boolean())
return true;
}
return false;
@ -522,7 +522,7 @@ namespace {
foreach (post_t * p, post.xact->posts) {
bind_scope_t bound_scope(args, *p);
if (! expr->calc(bound_scope).to_boolean())
if (! expr->calc(bound_scope, args.locus, args.depth).to_boolean())
return false;
}
return true;