diff options
author | John Wiegley <johnw@newartisans.com> | 2006-02-28 03:20:06 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 02:41:27 -0400 |
commit | a2423f99db3eb80c5fdb7208f90a3933e3716112 (patch) | |
tree | d53b3423ccbe3127c20301cd0fa9a071f43c1f75 | |
parent | 08ad1f544fb8b4b2d7a936d28cf47a1edb05c37b (diff) | |
download | fork-ledger-a2423f99db3eb80c5fdb7208f90a3933e3716112.tar.gz fork-ledger-a2423f99db3eb80c5fdb7208f90a3933e3716112.tar.bz2 fork-ledger-a2423f99db3eb80c5fdb7208f90a3933e3716112.zip |
*** empty log message ***
-rw-r--r-- | balance.h | 38 | ||||
-rw-r--r-- | binary.cc | 4 | ||||
-rw-r--r-- | textual.cc | 2 | ||||
-rw-r--r-- | valexpr.cc | 13 | ||||
-rw-r--r-- | valexpr.h | 20 | ||||
-rw-r--r-- | value.cc | 3 |
6 files changed, 45 insertions, 35 deletions
@@ -144,9 +144,12 @@ class balance_t // multiplication and divide balance_t& operator*=(const balance_t& bal) { - if (amounts.size() == 1 && bal.amounts.size() == 1) + if (! *this || ! bal) + return (*this = 0L); + else if (amounts.size() == 1 && bal.amounts.size() == 1) return *this *= (*bal.amounts.begin()).second; - throw amount_error("It makes no sense to multiply two balances"); + else + throw amount_error("It makes no sense to multiply two balances"); } balance_t& operator*=(const amount_t& amt) { // Multiplying by the null commodity causes all amounts to be @@ -173,9 +176,14 @@ class balance_t } balance_t& operator/=(const balance_t& bal) { - if (amounts.size() == 1 && bal.amounts.size() == 1) + if (! *this) + return (*this = 0L); + else if (! bal) + throw amount_error("Attempt to divide by zero"); + else if (amounts.size() == 1 && bal.amounts.size() == 1) return *this /= (*bal.amounts.begin()).second; - throw amount_error("It makes no sense to divide two balances"); + else + throw amount_error("It makes no sense to divide two balances"); } balance_t& operator/=(const amount_t& amt) { // Dividing by the null commodity causes all amounts to be @@ -428,9 +436,8 @@ class balance_t balance_t value(const std::time_t moment) const; balance_t price() const; - void write(std::ostream& out, - const int first_width, - const int latter_width = -1) const; + void write(std::ostream& out, const int first_width, + const int latter_width = -1) const; void abs() { for (amounts_map::iterator i = amounts.begin(); @@ -563,7 +570,6 @@ class balance_pair_t else cost = new balance_t(*bal_pair.cost); } - return *this; } balance_pair_t& operator+=(const balance_t& bal) { @@ -594,7 +600,6 @@ class balance_pair_t else cost = new balance_t(- *bal_pair.cost); } - return *this; } balance_pair_t& operator-=(const balance_t& bal) { @@ -677,7 +682,6 @@ class balance_pair_t cost = NULL; } } - return *this; } balance_pair_t& operator*=(const balance_t& bal) { @@ -694,21 +698,19 @@ class balance_pair_t } balance_pair_t& operator/=(const balance_pair_t& bal_pair) { - quantity /= bal_pair.quantity; + if (bal_pair.quantity) + quantity /= bal_pair.quantity; + else + throw amount_error("Attempt to divide by zero"); if (bal_pair.price) { if (price) *price /= *bal_pair.price; - } else { - throw amount_error("Attempt to divide by zero"); } if (bal_pair.cost) { if (cost) *cost /= *bal_pair.cost; - } else { - throw amount_error("Attempt to divide by zero"); } - return *this; } balance_pair_t& operator/=(const balance_t& bal) { @@ -899,8 +901,7 @@ class balance_pair_t balance_pair_t& add(const amount_t& amount, const amount_t * a_price = NULL, - const amount_t * a_cost = NULL) - { + const amount_t * a_cost = NULL) { quantity += amount; if (a_price) { @@ -915,7 +916,6 @@ class balance_pair_t else cost = new balance_t(*a_cost); } - return *this; } @@ -343,9 +343,9 @@ inline void read_binary_transaction(char *& data, transaction_t * xact) xact->data = NULL; if (xact->amount_expr) - compute_amount(xact->amount_expr, xact->amount, *xact); + compute_amount(xact->amount_expr, xact->amount, xact); if (xact->cost_expr) - compute_amount(xact->cost_expr, *xact->cost, *xact); + compute_amount(xact->cost_expr, *xact->cost, xact); } inline void read_binary_entry_base(char *& data, entry_base_t * entry, @@ -164,7 +164,7 @@ value_expr_t * parse_amount(const char * text, amount_t& amt, if (altbuf) delete[] altbuf; - if (! compute_amount(expr, amt, xact)) + if (! compute_amount(expr, amt, &xact)) throw parse_error(path, linenum, "Value expression yields a balance"); } @@ -19,10 +19,11 @@ details_t::details_t(const transaction_t& _xact) DEBUG_PRINT("ledger.memory.ctors", "ctor details_t"); } -bool compute_amount(value_expr_t * expr, amount_t& amt, transaction_t& xact) +bool compute_amount(value_expr_t * expr, amount_t& amt, + const transaction_t * xact, value_expr_t * context) { value_t result; - expr->compute(result, details_t(xact)); + expr->compute(result, xact ? details_t(*xact) : details_t(), context); switch (result.type) { case value_t::BOOLEAN: amt = *((bool *) result.data); @@ -537,11 +538,10 @@ void value_expr_t::compute(value_t& result, const details_t& details, index = 0; expr = find_leaf(context, 1, index); - value_t temp; - expr->compute(temp, details, context); - if (expr->kind == CONSTANT_T) - result = result.value(expr->constant_t); + amount_t moment; + if (compute_amount(expr, moment, details.xact, context)) + result = result.value((long)moment); else throw compute_error("Invalid date passed to P(value,date)"); @@ -1279,6 +1279,7 @@ void init_value_expr() globals->define("P", node); globals->define("val", node); globals->define("value", node); + parse_boolean_expr("current_value(x)=P(x,m)", globals); // Macros node = parse_value_expr("P(a,d)"); @@ -215,10 +215,18 @@ struct scope_t DEBUG_PRINT("ledger.valexpr.syms", "Defining '" << name << "' = " << def); std::pair<symbol_map::iterator, bool> result - = symbols.insert(symbol_pair(name, def->acquire())); - if (! result.second) - throw value_expr_error(std::string("Redefinition of '") + - name + "' in same scope"); + = symbols.insert(symbol_pair(name, def)); + if (! result.second) { + symbols.erase(name); + std::pair<symbol_map::iterator, bool> result + = symbols.insert(symbol_pair(name, def)); + if (! result.second) { + def->release(); + throw value_expr_error(std::string("Redefinition of '") + + name + "' in same scope"); + } + } + def->acquire(); } value_expr_t * lookup(const std::string& name) { symbol_map::const_iterator i = symbols.find(name); @@ -237,7 +245,9 @@ extern bool initialized; void init_value_expr(); -bool compute_amount(value_expr_t * expr, amount_t& amt, transaction_t& xact); +bool compute_amount(value_expr_t * expr, amount_t& amt, + const transaction_t * xact, + value_expr_t * context = NULL); struct scope_t; value_expr_t * parse_boolean_expr(std::istream& in, scope_t * scope); @@ -733,11 +733,10 @@ value_t value_t::price() const return *this; case BALANCE_PAIR: - assert(((balance_pair_t *) data)->price); if (((balance_pair_t *) data)->price) return *(((balance_pair_t *) data)->price); else - return ((balance_pair_t *) data)->quantity; + return 0L; default: assert(0); |