Report error context in expressions more precisely
This commit is contained in:
parent
7708ed1a75
commit
2ea075dc4f
6 changed files with 27 additions and 17 deletions
|
|
@ -295,7 +295,7 @@ namespace {
|
||||||
|
|
||||||
foreach (post_t * p, account.posts) {
|
foreach (post_t * p, account.posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -308,7 +308,7 @@ namespace {
|
||||||
|
|
||||||
foreach (post_t * p, account.posts) {
|
foreach (post_t * p, account.posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -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
|
// Evaluating an identifier is the same as calling its definition
|
||||||
// directly, so we create an empty call_scope_t to reflect the scope for
|
// directly, so we create an empty call_scope_t to reflect the scope for
|
||||||
// this implicit call.
|
// 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)
|
result = left()->compile(call_args, depth + 1)
|
||||||
->calc(call_args, locus, depth + 1);
|
->calc(call_args, locus, depth + 1);
|
||||||
check_type_context(scope, result);
|
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
|
// Evaluating a FUNCTION is the same as calling it directly; this happens
|
||||||
// when certain functions-that-look-like-variables (such as "amount") are
|
// when certain functions-that-look-like-variables (such as "amount") are
|
||||||
// resolved.
|
// 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);
|
result = as_function()(call_args);
|
||||||
check_type_context(scope, result);
|
check_type_context(scope, result);
|
||||||
#if defined(DEBUG_ON)
|
#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: {
|
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())
|
if (has_right())
|
||||||
call_args.set_args(split_cons_expr(right()->kind == O_SEQ ?
|
call_args.set_args(split_cons_expr(right()->kind == O_SEQ ?
|
||||||
right()->left() : right()));
|
right()->left() : right()));
|
||||||
|
|
|
||||||
12
src/post.cc
12
src/post.cc
|
|
@ -353,12 +353,14 @@ namespace {
|
||||||
foreach (post_t * p, post.xact->posts) {
|
foreach (post_t * p, post.xact->posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
bind_scope_t bound_scope(args, *p);
|
||||||
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
|
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
|
// If the user specifies any(EXPR, false), and the context is a
|
||||||
// posting, then that posting isn't considered by the test.
|
// posting, then that posting isn't considered by the test.
|
||||||
; // skip it
|
; // skip it
|
||||||
}
|
}
|
||||||
else if (expr->calc(bound_scope).to_boolean()) {
|
else if (expr->calc(bound_scope, args.locus,
|
||||||
|
args.depth).to_boolean()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,12 +375,14 @@ namespace {
|
||||||
foreach (post_t * p, post.xact->posts) {
|
foreach (post_t * p, post.xact->posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
bind_scope_t bound_scope(args, *p);
|
||||||
if (p == &post && args.has<expr_t::ptr_op_t>(1) &&
|
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
|
// If the user specifies any(EXPR, false), and the context is a
|
||||||
// posting, then that posting isn't considered by the test.
|
// posting, then that posting isn't considered by the test.
|
||||||
; // skip it
|
; // skip it
|
||||||
}
|
}
|
||||||
else if (! expr->calc(bound_scope).to_boolean()) {
|
else if (! expr->calc(bound_scope, args.locus,
|
||||||
|
args.depth).to_boolean()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ value_t& call_scope_t::resolve(const std::size_t index,
|
||||||
value_t& value(args[index]);
|
value_t& value(args[index]);
|
||||||
if (value.is_any()) {
|
if (value.is_any()) {
|
||||||
context_scope_t scope(*this, context, required);
|
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))
|
if (required && ! value.is_type(context))
|
||||||
throw_(calc_error, _("Expected %1 for argument %2, but received %3")
|
throw_(calc_error, _("Expected %1 for argument %2, but received %3")
|
||||||
<< value.label(context) << index
|
<< value.label(context) << index
|
||||||
|
|
|
||||||
16
src/scope.h
16
src/scope.h
|
|
@ -335,11 +335,17 @@ class call_scope_t : public context_scope_t
|
||||||
const bool required = false);
|
const bool required = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit call_scope_t(scope_t& _parent,
|
expr_t::ptr_op_t * locus;
|
||||||
value_t::type_t _type_context = value_t::VOID,
|
const int depth;
|
||||||
const bool _required = true)
|
|
||||||
: context_scope_t(_parent, _type_context, _required), ptr(NULL) {
|
explicit call_scope_t(scope_t& _parent,
|
||||||
TRACE_CTOR(call_scope_t, "scope_t&, value_t::type_t, bool");
|
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() {
|
virtual ~call_scope_t() {
|
||||||
TRACE_DTOR(call_scope_t);
|
TRACE_DTOR(call_scope_t);
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ namespace {
|
||||||
|
|
||||||
foreach (post_t * p, post.xact->posts) {
|
foreach (post_t * p, post.xact->posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -522,7 +522,7 @@ namespace {
|
||||||
|
|
||||||
foreach (post_t * p, post.xact->posts) {
|
foreach (post_t * p, post.xact->posts) {
|
||||||
bind_scope_t bound_scope(args, *p);
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue