diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.cc | 31 | ||||
-rw-r--r-- | src/expr.h | 22 | ||||
-rw-r--r-- | src/op.cc | 62 | ||||
-rw-r--r-- | src/op.h | 4 |
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; } @@ -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; @@ -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)) { @@ -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 |