summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.cc31
-rw-r--r--src/expr.h22
-rw-r--r--src/op.cc62
-rw-r--r--src/op.h4
4 files changed, 71 insertions, 48 deletions
diff --git a/src/expr.cc b/src/expr.cc
index 69319105..14fb2be8 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -35,19 +35,19 @@
namespace ledger {
-expr_t::expr_t() : compiled(false)
+expr_t::expr_t() : context(NULL), compiled(false)
{
TRACE_CTOR(expr_t, "");
}
expr_t::expr_t(const expr_t& other)
- : ptr(other.ptr), str(other.str), compiled(false)
+ : ptr(other.ptr), context(other.context), str(other.str), compiled(false)
{
TRACE_CTOR(expr_t, "copy");
}
expr_t::expr_t(const string& _str, const uint_least8_t flags)
- : str(_str), compiled(false)
+ : context(NULL), str(_str), compiled(false)
{
TRACE_CTOR(expr_t, "const string&");
if (! _str.empty())
@@ -55,16 +55,16 @@ expr_t::expr_t(const string& _str, const uint_least8_t flags)
}
expr_t::expr_t(std::istream& in, const uint_least8_t flags)
- : compiled(false)
+ : context(NULL), compiled(false)
{
TRACE_CTOR(expr_t, "std::istream&");
parse(in, flags);
}
-expr_t::expr_t(const ptr_op_t& _ptr, const string& _str)
- : ptr(_ptr), str(_str), compiled(false)
+expr_t::expr_t(const ptr_op_t& _ptr, scope_t * _context, const string& _str)
+ : ptr(_ptr), context(_context), str(_str), compiled(false)
{
- TRACE_CTOR(expr_t, "const ptr_op_t&, const string&");
+ TRACE_CTOR(expr_t, "const ptr_op_t&, scope_t *, const string&");
}
expr_t::~expr_t() throw()
@@ -72,11 +72,17 @@ expr_t::~expr_t() throw()
TRACE_DTOR(expr_t);
}
+expr_t::ptr_op_t expr_t::get_op() throw()
+{
+ return ptr;
+}
+
expr_t& expr_t::operator=(const expr_t& _expr)
{
if (this != &_expr) {
str = _expr.str;
ptr = _expr.ptr;
+ context = _expr.context;
compiled = _expr.compiled;
}
return *this;
@@ -87,6 +93,7 @@ void expr_t::parse(const string& _str, const uint32_t flags)
parser_t parser;
str = _str;
ptr = parser.parse(str, flags);
+ context = NULL;
compiled = false;
}
@@ -96,6 +103,7 @@ void expr_t::parse(std::istream& in, const uint32_t flags,
parser_t parser;
str = "<stream>";
ptr = parser.parse(in, flags, original_string);
+ context = NULL;
compiled = false;
}
@@ -103,6 +111,7 @@ void expr_t::compile(scope_t& scope)
{
if (ptr.get() && ! compiled) {
ptr = ptr->compile(scope);
+ context = &scope;
compiled = true;
}
}
@@ -124,14 +133,14 @@ value_t expr_t::calc(scope_t& scope)
}
}
- ptr_op_t context;
+ ptr_op_t locus;
try {
- return ptr->calc(scope, &context);
+ return ptr->calc(scope, &locus);
}
catch (const std::exception& err) {
- if (context) {
+ if (locus) {
add_error_context("While evaluating value expression:");
- add_error_context(op_context(ptr, context));
+ add_error_context(op_context(ptr, locus));
}
throw;
}
diff --git a/src/expr.h b/src/expr.h
index 6805e6d5..508e521a 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -87,14 +87,16 @@ public:
};
private:
- ptr_op_t ptr;
- string str;
- bool compiled;
+ ptr_op_t ptr;
+ scope_t * context;
+ string str;
+ bool compiled;
public:
expr_t();
expr_t(const expr_t& other);
- expr_t(const ptr_op_t& _ptr, const string& _str = "");
+ expr_t(const ptr_op_t& _ptr, scope_t * context = NULL,
+ const string& _str = "");
expr_t(const string& _str, const uint_least8_t flags = 0);
expr_t(std::istream& in, const uint_least8_t flags = 0);
@@ -110,6 +112,9 @@ public:
operator bool() const throw() {
return ptr.get() != NULL;
}
+
+ ptr_op_t get_op() throw();
+
string text() const throw() {
return str;
}
@@ -127,6 +132,15 @@ public:
value_t calc(scope_t& scope);
value_t calc(scope_t& scope) const;
+ value_t calc() {
+ assert(context);
+ return calc(*context);
+ }
+ value_t calc() const {
+ assert(context);
+ return calc(*context);
+ }
+
bool is_constant() const;
bool is_function() const;
diff --git a/src/op.cc b/src/op.cc
index 615b7c76..902ed647 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -91,7 +91,7 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
return intermediate;
}
-value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
+value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
{
try {
@@ -112,7 +112,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
// directly, so we create an empty call_scope_t to reflect the scope for
// this implicit call.
call_scope_t call_args(scope);
- result = left()->calc(call_args, context);
+ result = left()->calc(call_args, locus);
break;
}
@@ -153,7 +153,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
throw_(calc_error,
"Too many arguments in function call (saw " << args_count << ")");
- result = right()->compile(local_scope)->calc(local_scope, context);
+ result = right()->compile(local_scope)->calc(local_scope, locus);
break;
}
@@ -183,7 +183,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
call_scope_t call_args(scope);
if (has_right())
- call_args.set_args(right()->calc(scope, context));
+ call_args.set_args(right()->calc(scope, locus));
ptr_op_t func = left();
const string& name(func->as_ident());
@@ -195,7 +195,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
if (func->is_function())
result = func->as_function()(call_args);
else
- result = func->calc(call_args, context);
+ result = func->calc(call_args, locus);
break;
}
@@ -203,69 +203,69 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
if (! right()->is_value() || ! right()->as_value().is_mask())
throw_(calc_error, "Right-hand argument to match operator must be a regex");
- result = (right()->calc(scope, context).as_mask()
- .match(left()->calc(scope, context).to_string()));
+ result = (right()->calc(scope, locus).as_mask()
+ .match(left()->calc(scope, locus).to_string()));
break;
case O_EQ:
- result = left()->calc(scope, context) == right()->calc(scope, context);
+ result = left()->calc(scope, locus) == right()->calc(scope, locus);
break;
case O_LT:
- result = left()->calc(scope, context) < right()->calc(scope, context);
+ result = left()->calc(scope, locus) < right()->calc(scope, locus);
break;
case O_LTE:
- result = left()->calc(scope, context) <= right()->calc(scope, context);
+ result = left()->calc(scope, locus) <= right()->calc(scope, locus);
break;
case O_GT:
- result = left()->calc(scope, context) > right()->calc(scope, context);
+ result = left()->calc(scope, locus) > right()->calc(scope, locus);
break;
case O_GTE:
- result = left()->calc(scope, context) >= right()->calc(scope, context);
+ result = left()->calc(scope, locus) >= right()->calc(scope, locus);
break;
case O_ADD:
- result = left()->calc(scope, context) + right()->calc(scope, context);
+ result = left()->calc(scope, locus) + right()->calc(scope, locus);
break;
case O_SUB:
- result = left()->calc(scope, context) - right()->calc(scope, context);
+ result = left()->calc(scope, locus) - right()->calc(scope, locus);
break;
case O_MUL:
- result = left()->calc(scope, context) * right()->calc(scope, context);
+ result = left()->calc(scope, locus) * right()->calc(scope, locus);
break;
case O_DIV:
- result = left()->calc(scope, context) / right()->calc(scope, context);
+ result = left()->calc(scope, locus) / right()->calc(scope, locus);
break;
case O_NEG:
- result = left()->calc(scope, context).negate();
+ result = left()->calc(scope, locus).negate();
break;
case O_NOT:
- result = ! left()->calc(scope, context);
+ result = ! left()->calc(scope, locus);
break;
case O_AND:
- if (left()->calc(scope, context))
- result = right()->calc(scope, context);
+ if (left()->calc(scope, locus))
+ result = right()->calc(scope, locus);
else
result = false;
break;
case O_OR:
- if (value_t temp = left()->calc(scope, context))
+ if (value_t temp = left()->calc(scope, locus))
result = temp;
else
- result = right()->calc(scope, context);
+ result = right()->calc(scope, locus);
break;
case O_QUERY:
assert(right());
assert(right()->kind == O_COLON);
- if (value_t temp = left()->calc(scope, context))
- result = right()->left()->calc(scope, context);
+ if (value_t temp = left()->calc(scope, locus))
+ result = right()->left()->calc(scope, locus);
else
- result = right()->right()->calc(scope, context);
+ result = right()->right()->calc(scope, locus);
break;
case O_COLON:
@@ -273,7 +273,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
break;
case O_COMMA: {
- value_t temp(left()->calc(scope, context));
+ value_t temp(left()->calc(scope, locus));
ptr_op_t next = right();
while (next) {
@@ -286,7 +286,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
next = NULL;
}
- temp.push_back(value_op->calc(scope, context));
+ temp.push_back(value_op->calc(scope, locus));
}
result = temp;
break;
@@ -304,8 +304,8 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
}
catch (const std::exception& err) {
- if (context && ! *context)
- *context = this;
+ if (locus && ! *locus)
+ *locus = this;
throw;
}
}
@@ -600,10 +600,10 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const
}
string op_context(const expr_t::ptr_op_t op,
- const expr_t::ptr_op_t goal)
+ const expr_t::ptr_op_t locus)
{
ostream_pos_type start_pos, end_pos;
- expr_t::op_t::context_t context(op, goal, &start_pos, &end_pos);
+ expr_t::op_t::context_t context(op, locus, &start_pos, &end_pos);
std::ostringstream buf;
buf << " ";
if (op->print(buf, context)) {
diff --git a/src/op.h b/src/op.h
index 850e86b7..7af4ff64 100644
--- a/src/op.h
+++ b/src/op.h
@@ -262,7 +262,7 @@ private:
public:
ptr_op_t compile(scope_t& scope);
- value_t calc(scope_t& scope, ptr_op_t * context = NULL);
+ value_t calc(scope_t& scope, ptr_op_t * locus = NULL);
struct context_t
{
@@ -314,7 +314,7 @@ inline expr_t::ptr_op_t expr_t::op_t::wrap_functor(const function_t& fobj) {
#define WRAP_FUNCTOR(x) expr_t::op_t::wrap_functor(x)
string op_context(const expr_t::ptr_op_t op,
- const expr_t::ptr_op_t goal = NULL);
+ const expr_t::ptr_op_t locus = NULL);
} // namespace ledger