summaryrefslogtreecommitdiff
path: root/valexpr.h
diff options
context:
space:
mode:
Diffstat (limited to 'valexpr.h')
-rw-r--r--valexpr.h154
1 files changed, 79 insertions, 75 deletions
diff --git a/valexpr.h b/valexpr.h
index 7a029650..10e7fe5d 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -33,39 +33,6 @@ struct details_t
#endif
};
-class value_calc
-{
-public:
- virtual ~value_calc() {}
- virtual void compute(value_t& result,
- const details_t& details = details_t(),
- value_expr_t * context = NULL) = 0;
- virtual value_t compute(const details_t& details = details_t(),
- value_expr_t * context = NULL) = 0;
-};
-
-typedef void (*value_func_t)(value_t& result, const details_t& details,
- value_expr_t * context);
-
-class value_func : public value_calc
-{
- value_func_t func;
-public:
- value_func(value_func_t _func) : func(_func) {}
-
- virtual void compute(value_t& result,
- const details_t& details = details_t(),
- value_expr_t * context = NULL) {
- func(result, details, context);
- }
- virtual value_t compute(const details_t& details = details_t(),
- value_expr_t * context = NULL) {
- value_t temp;
- func(temp, details, context);
- return temp;
- }
-};
-
struct value_expr_t
{
enum kind_t {
@@ -252,8 +219,8 @@ struct scope_t
= symbols.insert(symbol_pair(name, def));
if (! result.second) {
def->release();
- throw value_expr_error(std::string("Redefinition of '") +
- name + "' in same scope");
+ throw new compute_error(std::string("Redefinition of '") +
+ name + "' in same scope");
}
}
def->acquire();
@@ -282,37 +249,87 @@ bool compute_amount(value_expr_t * expr, amount_t& amt,
struct scope_t;
value_expr_t * parse_boolean_expr(std::istream& in, scope_t * scope);
-inline value_expr_t * parse_boolean_expr(const char * p,
+inline value_expr_t * parse_boolean_expr(const std::string& str,
scope_t * scope = NULL) {
- std::istringstream stream(p);
- return parse_boolean_expr(stream, scope);
+ std::istringstream stream(str);
+ try {
+ return parse_boolean_expr(stream, scope);
+ }
+ catch (error * err) {
+ err->context.push_back
+ (new error_context("While parsing value expression: " + str));
+ throw err;
+ }
}
-inline value_expr_t * parse_boolean_expr(const std::string& str,
+inline value_expr_t * parse_boolean_expr(const char * p,
scope_t * scope = NULL) {
- return parse_boolean_expr(str.c_str(), scope);
+ return parse_boolean_expr(std::string(p), scope);
}
value_expr_t * parse_value_expr(std::istream& in,
scope_t * scope = NULL,
const bool partial = false);
-inline value_expr_t * parse_value_expr(const char * p,
+inline value_expr_t * parse_value_expr(const std::string& str,
scope_t * scope = NULL,
const bool partial = false) {
- std::istringstream stream(p);
- return parse_value_expr(stream, scope, partial);
+ std::istringstream stream(str);
+ try {
+ return parse_value_expr(stream, scope, partial);
+ }
+ catch (error * err) {
+ err->context.push_back
+ (new line_context(str, (long)stream.tellg() - 1,
+ "While parsing value expression:"));
+ throw err;
+ }
}
-inline value_expr_t * parse_value_expr(const std::string& str,
+inline value_expr_t * parse_value_expr(const char * p,
scope_t * scope = NULL,
const bool partial = false) {
- return parse_value_expr(str.c_str(), scope);
+ return parse_value_expr(std::string(p), scope, partial);
}
void dump_value_expr(std::ostream& out, const value_expr_t * node,
const int depth = 0);
+unsigned long write_value_expr(std::ostream& out,
+ const value_expr_t * node,
+ const value_expr_t * node_to_find = NULL,
+ unsigned long start_pos = 0UL);
+
+//////////////////////////////////////////////////////////////////////
+
+inline void guarded_compute(const value_expr_t * expr,
+ value_t& result,
+ const details_t& details = details_t(),
+ value_expr_t * context = NULL) {
+ try {
+ expr->compute(result, details);
+ }
+ catch (error * err) {
+ if (err->context.empty() ||
+ ! dynamic_cast<valexpr_context *>(err->context.back()))
+ err->context.push_back(new valexpr_context(expr));
+ error_context * last = err->context.back();
+ if (valexpr_context * ctxt = dynamic_cast<valexpr_context *>(last)) {
+ ctxt->expr = expr->acquire();
+ ctxt->desc = "While computing value expression:";
+ }
+ throw err;
+ }
+}
+
+inline value_t guarded_compute(const value_expr_t * expr,
+ const details_t& details = details_t(),
+ value_expr_t * context = NULL) {
+ value_t temp;
+ guarded_compute(expr, temp, details, context);
+ return temp;
+}
+
//////////////////////////////////////////////////////////////////////
//
// This class is used so that during the "in between" stages of value
@@ -323,10 +340,11 @@ void dump_value_expr(std::ostream& out, const value_expr_t * node,
struct value_auto_ptr {
value_expr_t * ptr;
value_auto_ptr() : ptr(NULL) {}
- explicit value_auto_ptr(value_expr_t * _ptr) : ptr(_ptr) {}
+ explicit value_auto_ptr(value_expr_t * _ptr)
+ : ptr(_ptr ? _ptr->acquire() : NULL) {}
~value_auto_ptr() {
- if (ptr && ptr->refc == 0)
- delete ptr;
+ if (ptr)
+ ptr->release();
}
value_expr_t& operator*() const throw() {
return *ptr;
@@ -342,31 +360,24 @@ struct value_auto_ptr {
}
void reset(value_expr_t * p = 0) throw() {
if (p != ptr) {
- if (ptr && ptr->refc == 0)
- delete ptr;
- ptr = p;
+ if (ptr)
+ ptr->release();
+ ptr = p->acquire();
}
}
};
//////////////////////////////////////////////////////////////////////
-class value_expr : public value_calc
+class value_expr
{
- std::string expr;
value_expr_t * parsed;
-
public:
+ std::string expr;
+
value_expr(const std::string& _expr) : expr(_expr) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_expr");
- try {
- parsed = parse_value_expr(expr);
- parsed->acquire();
- }
- catch (const value_expr_error& err) {
- throw error(std::string("In value expression '") +
- expr + "': " + err.what());
- }
+ parsed = parse_value_expr(expr)->acquire();
}
value_expr(value_expr_t * _parsed) : parsed(_parsed->acquire()) {
DEBUG_PRINT("ledger.memory.ctors", "ctor value_expr");
@@ -380,18 +391,18 @@ public:
virtual void compute(value_t& result,
const details_t& details = details_t(),
value_expr_t * context = NULL) {
- parsed->compute(result, details, context);
+ guarded_compute(parsed, result, details, context);
}
virtual value_t compute(const details_t& details = details_t(),
value_expr_t * context = NULL) {
value_t temp;
- parsed->compute(temp, details, context);
+ guarded_compute(parsed, temp, details, context);
return temp;
}
};
-extern std::auto_ptr<value_calc> amount_expr;
-extern std::auto_ptr<value_calc> total_expr;
+extern std::auto_ptr<value_expr> amount_expr;
+extern std::auto_ptr<value_expr> total_expr;
inline void compute_amount(value_t& result,
const details_t& details = details_t()) {
@@ -425,15 +436,8 @@ class item_predicate
item_predicate(const std::string& _predicate) : predicate(NULL) {
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
- if (! _predicate.empty()) {
- try {
- predicate = parse_value_expr(_predicate)->acquire();
- }
- catch (value_expr_error& err) {
- throw value_expr_error(std::string("In predicate '") +
- _predicate + "': " + err.what());
- }
- }
+ if (! _predicate.empty())
+ predicate = parse_value_expr(_predicate)->acquire();
}
item_predicate(const value_expr_t * _predicate = NULL)
: predicate(_predicate->acquire()) {