Improved debug output of "--debug expr.calc"
This commit is contained in:
parent
fc84eeb358
commit
9b13e77ff5
2 changed files with 64 additions and 40 deletions
99
src/op.cc
99
src/op.cc
|
|
@ -38,10 +38,10 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
|
expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope, const int depth)
|
||||||
{
|
{
|
||||||
if (is_ident()) {
|
if (is_ident()) {
|
||||||
DEBUG("expr.compile", "Looking up identifier '" << as_ident() << "'");
|
DEBUG("expr.compile", "lookup: " << as_ident());
|
||||||
|
|
||||||
if (ptr_op_t def = scope.lookup(as_ident())) {
|
if (ptr_op_t def = scope.lookup(as_ident())) {
|
||||||
// Identifier references are first looked up at the point of
|
// Identifier references are first looked up at the point of
|
||||||
|
|
@ -79,9 +79,10 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
|
||||||
return wrap_value(value_t());
|
return wrap_value(value_t());
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_op_t lhs(left()->compile(scope));
|
ptr_op_t lhs(left()->compile(scope, depth));
|
||||||
ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ?
|
ptr_op_t rhs(kind > UNARY_OPERATORS && has_right() ?
|
||||||
(kind == O_LOOKUP ? right() : right()->compile(scope)) : NULL);
|
(kind == O_LOOKUP ? right() :
|
||||||
|
right()->compile(scope, depth)) : NULL);
|
||||||
|
|
||||||
if (lhs == left() && (! rhs || rhs == right()))
|
if (lhs == left() && (! rhs || rhs == right()))
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -90,19 +91,20 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
|
||||||
|
|
||||||
// Reduce constants immediately if possible
|
// Reduce constants immediately if possible
|
||||||
if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value()))
|
if ((! lhs || lhs->is_value()) && (! rhs || rhs->is_value()))
|
||||||
return wrap_value(intermediate->calc(scope));
|
return wrap_value(intermediate->calc(scope, NULL, depth));
|
||||||
|
|
||||||
return intermediate;
|
return intermediate;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
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 {
|
try {
|
||||||
|
|
||||||
value_t result;
|
value_t result;
|
||||||
|
|
||||||
DEBUG("expr.calc", "calculating '" << op_context(this) << "'");
|
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case VALUE:
|
case VALUE:
|
||||||
result = as_value();
|
result = as_value();
|
||||||
|
|
@ -116,7 +118,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
// 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);
|
call_scope_t call_args(scope);
|
||||||
result = left()->calc(call_args, locus);
|
result = left()->calc(call_args, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,6 +128,9 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
// resolved.
|
// resolved.
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
result = as_function()(call_args);
|
result = as_function()(call_args);
|
||||||
|
#if defined(DEBUG_ON)
|
||||||
|
skip_debug = true;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +162,8 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
throw_(calc_error,
|
throw_(calc_error,
|
||||||
_("Too many arguments in function call (saw %1)") << args_count);
|
_("Too many arguments in function call (saw %1)") << args_count);
|
||||||
|
|
||||||
result = right()->compile(local_scope)->calc(local_scope, locus);
|
result = right()->compile(local_scope, depth + 1)
|
||||||
|
->calc(local_scope, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,7 +179,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
} else {
|
} else {
|
||||||
scope_t& objscope(obj.as_ref_lval<scope_t>());
|
scope_t& objscope(obj.as_ref_lval<scope_t>());
|
||||||
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
||||||
result = member->calc(objscope);
|
result = member->calc(objscope, NULL, depth + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +198,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
|
|
||||||
if (has_right())
|
if (has_right())
|
||||||
call_args.set_args(right()->calc(scope, locus));
|
call_args.set_args(right()->calc(scope, locus, depth + 1));
|
||||||
|
|
||||||
ptr_op_t func = left();
|
ptr_op_t func = left();
|
||||||
const string& name(func->as_ident());
|
const string& name(func->as_ident());
|
||||||
|
|
@ -204,74 +210,83 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
if (func->is_function())
|
if (func->is_function())
|
||||||
result = func->as_function()(call_args);
|
result = func->as_function()(call_args);
|
||||||
else
|
else
|
||||||
result = func->calc(call_args, locus);
|
result = func->calc(call_args, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case O_MATCH:
|
case O_MATCH:
|
||||||
result = (right()->calc(scope, locus).as_mask()
|
result = (right()->calc(scope, locus, depth + 1).as_mask()
|
||||||
.match(left()->calc(scope, locus).to_string()));
|
.match(left()->calc(scope, locus, depth + 1).to_string()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_EQ:
|
case O_EQ:
|
||||||
result = left()->calc(scope, locus) == right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) ==
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_LT:
|
case O_LT:
|
||||||
result = left()->calc(scope, locus) < right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) <
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_LTE:
|
case O_LTE:
|
||||||
result = left()->calc(scope, locus) <= right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) <=
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_GT:
|
case O_GT:
|
||||||
result = left()->calc(scope, locus) > right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) >
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_GTE:
|
case O_GTE:
|
||||||
result = left()->calc(scope, locus) >= right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) >=
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_ADD:
|
case O_ADD:
|
||||||
result = left()->calc(scope, locus) + right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) +
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_SUB:
|
case O_SUB:
|
||||||
result = left()->calc(scope, locus) - right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) -
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_MUL:
|
case O_MUL:
|
||||||
result = left()->calc(scope, locus) * right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) *
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
case O_DIV:
|
case O_DIV:
|
||||||
result = left()->calc(scope, locus) / right()->calc(scope, locus);
|
result = (left()->calc(scope, locus, depth + 1) /
|
||||||
|
right()->calc(scope, locus, depth + 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_NEG:
|
case O_NEG:
|
||||||
result = left()->calc(scope, locus).negated();
|
result = left()->calc(scope, locus, depth + 1).negated();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_NOT:
|
case O_NOT:
|
||||||
result = ! left()->calc(scope, locus);
|
result = ! left()->calc(scope, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_AND:
|
case O_AND:
|
||||||
if (left()->calc(scope, locus))
|
if (left()->calc(scope, locus, depth + 1))
|
||||||
result = right()->calc(scope, locus);
|
result = right()->calc(scope, locus, depth + 1);
|
||||||
else
|
else
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_OR:
|
case O_OR:
|
||||||
if (value_t temp = left()->calc(scope, locus))
|
if (value_t temp = left()->calc(scope, locus, depth + 1))
|
||||||
result = temp;
|
result = temp;
|
||||||
else
|
else
|
||||||
result = right()->calc(scope, locus);
|
result = right()->calc(scope, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_QUERY:
|
case O_QUERY:
|
||||||
assert(right());
|
assert(right());
|
||||||
assert(right()->kind == O_COLON);
|
assert(right()->kind == O_COLON);
|
||||||
|
|
||||||
if (value_t temp = left()->calc(scope, locus))
|
if (value_t temp = left()->calc(scope, locus, depth + 1))
|
||||||
result = right()->left()->calc(scope, locus);
|
result = right()->left()->calc(scope, locus, depth + 1);
|
||||||
else
|
else
|
||||||
result = right()->right()->calc(scope, locus);
|
result = right()->right()->calc(scope, locus, depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_COLON:
|
case O_COLON:
|
||||||
|
|
@ -279,7 +294,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_CONS:
|
case O_CONS:
|
||||||
result = left()->calc(scope, locus);
|
result = left()->calc(scope, locus, depth + 1);
|
||||||
DEBUG("op.cons", "car = " << result);
|
DEBUG("op.cons", "car = " << result);
|
||||||
|
|
||||||
if (has_right()) {
|
if (has_right()) {
|
||||||
|
|
@ -296,7 +311,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
value_op = next;
|
value_op = next;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
temp.push_back(value_op->calc(scope, locus));
|
temp.push_back(value_op->calc(scope, locus, depth + 1));
|
||||||
DEBUG("op.cons", "temp now = " << temp);
|
DEBUG("op.cons", "temp now = " << temp);
|
||||||
}
|
}
|
||||||
result = temp;
|
result = temp;
|
||||||
|
|
@ -304,7 +319,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case O_SEQ: {
|
case O_SEQ: {
|
||||||
left()->calc(scope, locus);
|
left()->calc(scope, locus, depth + 1);
|
||||||
assert(has_right());
|
assert(has_right());
|
||||||
|
|
||||||
ptr_op_t next = right();
|
ptr_op_t next = right();
|
||||||
|
|
@ -317,7 +332,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
value_op = next;
|
value_op = next;
|
||||||
next = NULL;
|
next = NULL;
|
||||||
}
|
}
|
||||||
result = value_op->calc(scope, locus);
|
result = value_op->calc(scope, locus, depth + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -328,7 +343,15 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("expr.calc", "result is '" << result << "'");
|
#if defined(DEBUG_ON)
|
||||||
|
if (! skip_debug && SHOW_DEBUG("expr.calc")) {
|
||||||
|
for (int i = 0; i < depth; i++)
|
||||||
|
ledger::_log_buffer << '.';
|
||||||
|
ledger::_log_buffer << op_context(this) << " => ";
|
||||||
|
result.dump(ledger::_log_buffer, true);
|
||||||
|
DEBUG("expr.calc", "");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
||||||
5
src/op.h
5
src/op.h
|
|
@ -262,8 +262,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ptr_op_t compile(scope_t& scope);
|
ptr_op_t compile(scope_t& scope, const int depth = 0);
|
||||||
value_t calc(scope_t& scope, ptr_op_t * locus = NULL);
|
value_t calc(scope_t& scope, ptr_op_t * locus = NULL,
|
||||||
|
const int depth = 0);
|
||||||
|
|
||||||
struct context_t
|
struct context_t
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue