*** empty log message ***

This commit is contained in:
John Wiegley 2006-02-28 03:20:06 +00:00
parent 08ad1f544f
commit a2423f99db
6 changed files with 45 additions and 35 deletions

View file

@ -144,8 +144,11 @@ class balance_t
// multiplication and divide // multiplication and divide
balance_t& operator*=(const balance_t& bal) { 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; return *this *= (*bal.amounts.begin()).second;
else
throw amount_error("It makes no sense to multiply two balances"); throw amount_error("It makes no sense to multiply two balances");
} }
balance_t& operator*=(const amount_t& amt) { balance_t& operator*=(const amount_t& amt) {
@ -173,8 +176,13 @@ class balance_t
} }
balance_t& operator/=(const balance_t& bal) { 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; return *this /= (*bal.amounts.begin()).second;
else
throw amount_error("It makes no sense to divide two balances"); throw amount_error("It makes no sense to divide two balances");
} }
balance_t& operator/=(const amount_t& amt) { balance_t& operator/=(const amount_t& amt) {
@ -428,8 +436,7 @@ class balance_t
balance_t value(const std::time_t moment) const; balance_t value(const std::time_t moment) const;
balance_t price() const; balance_t price() const;
void write(std::ostream& out, void write(std::ostream& out, const int first_width,
const int first_width,
const int latter_width = -1) const; const int latter_width = -1) const;
void abs() { void abs() {
@ -563,7 +570,6 @@ class balance_pair_t
else else
cost = new balance_t(*bal_pair.cost); cost = new balance_t(*bal_pair.cost);
} }
return *this; return *this;
} }
balance_pair_t& operator+=(const balance_t& bal) { balance_pair_t& operator+=(const balance_t& bal) {
@ -594,7 +600,6 @@ class balance_pair_t
else else
cost = new balance_t(- *bal_pair.cost); cost = new balance_t(- *bal_pair.cost);
} }
return *this; return *this;
} }
balance_pair_t& operator-=(const balance_t& bal) { balance_pair_t& operator-=(const balance_t& bal) {
@ -677,7 +682,6 @@ class balance_pair_t
cost = NULL; cost = NULL;
} }
} }
return *this; return *this;
} }
balance_pair_t& operator*=(const balance_t& bal) { 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) { balance_pair_t& operator/=(const balance_pair_t& bal_pair) {
if (bal_pair.quantity)
quantity /= bal_pair.quantity; quantity /= bal_pair.quantity;
else
throw amount_error("Attempt to divide by zero");
if (bal_pair.price) { if (bal_pair.price) {
if (price) if (price)
*price /= *bal_pair.price; *price /= *bal_pair.price;
} else {
throw amount_error("Attempt to divide by zero");
} }
if (bal_pair.cost) { if (bal_pair.cost) {
if (cost) if (cost)
*cost /= *bal_pair.cost; *cost /= *bal_pair.cost;
} else {
throw amount_error("Attempt to divide by zero");
} }
return *this; return *this;
} }
balance_pair_t& operator/=(const balance_t& bal) { balance_pair_t& operator/=(const balance_t& bal) {
@ -899,8 +901,7 @@ class balance_pair_t
balance_pair_t& add(const amount_t& amount, balance_pair_t& add(const amount_t& amount,
const amount_t * a_price = NULL, const amount_t * a_price = NULL,
const amount_t * a_cost = NULL) const amount_t * a_cost = NULL) {
{
quantity += amount; quantity += amount;
if (a_price) { if (a_price) {
@ -915,7 +916,6 @@ class balance_pair_t
else else
cost = new balance_t(*a_cost); cost = new balance_t(*a_cost);
} }
return *this; return *this;
} }

View file

@ -343,9 +343,9 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
xact->data = NULL; xact->data = NULL;
if (xact->amount_expr) if (xact->amount_expr)
compute_amount(xact->amount_expr, xact->amount, *xact); compute_amount(xact->amount_expr, xact->amount, xact);
if (xact->cost_expr) 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, inline void read_binary_entry_base(char *& data, entry_base_t * entry,

View file

@ -164,7 +164,7 @@ value_expr_t * parse_amount(const char * text, amount_t& amt,
if (altbuf) if (altbuf)
delete[] 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"); throw parse_error(path, linenum, "Value expression yields a balance");
} }

View file

@ -19,10 +19,11 @@ details_t::details_t(const transaction_t& _xact)
DEBUG_PRINT("ledger.memory.ctors", "ctor details_t"); 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; value_t result;
expr->compute(result, details_t(xact)); expr->compute(result, xact ? details_t(*xact) : details_t(), context);
switch (result.type) { switch (result.type) {
case value_t::BOOLEAN: case value_t::BOOLEAN:
amt = *((bool *) result.data); amt = *((bool *) result.data);
@ -537,11 +538,10 @@ void value_expr_t::compute(value_t& result, const details_t& details,
index = 0; index = 0;
expr = find_leaf(context, 1, index); expr = find_leaf(context, 1, index);
value_t temp;
expr->compute(temp, details, context);
if (expr->kind == CONSTANT_T) amount_t moment;
result = result.value(expr->constant_t); if (compute_amount(expr, moment, details.xact, context))
result = result.value((long)moment);
else else
throw compute_error("Invalid date passed to P(value,date)"); throw compute_error("Invalid date passed to P(value,date)");
@ -1279,6 +1279,7 @@ void init_value_expr()
globals->define("P", node); globals->define("P", node);
globals->define("val", node); globals->define("val", node);
globals->define("value", node); globals->define("value", node);
parse_boolean_expr("current_value(x)=P(x,m)", globals);
// Macros // Macros
node = parse_value_expr("P(a,d)"); node = parse_value_expr("P(a,d)");

View file

@ -215,11 +215,19 @@ struct scope_t
DEBUG_PRINT("ledger.valexpr.syms", DEBUG_PRINT("ledger.valexpr.syms",
"Defining '" << name << "' = " << def); "Defining '" << name << "' = " << def);
std::pair<symbol_map::iterator, bool> result std::pair<symbol_map::iterator, bool> result
= symbols.insert(symbol_pair(name, def->acquire())); = symbols.insert(symbol_pair(name, def));
if (! result.second) 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 '") + throw value_expr_error(std::string("Redefinition of '") +
name + "' in same scope"); name + "' in same scope");
} }
}
def->acquire();
}
value_expr_t * lookup(const std::string& name) { value_expr_t * lookup(const std::string& name) {
symbol_map::const_iterator i = symbols.find(name); symbol_map::const_iterator i = symbols.find(name);
if (i != symbols.end()) if (i != symbols.end())
@ -237,7 +245,9 @@ extern bool initialized;
void init_value_expr(); 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; struct scope_t;
value_expr_t * parse_boolean_expr(std::istream& in, scope_t * scope); value_expr_t * parse_boolean_expr(std::istream& in, scope_t * scope);

View file

@ -733,11 +733,10 @@ value_t value_t::price() const
return *this; return *this;
case BALANCE_PAIR: case BALANCE_PAIR:
assert(((balance_pair_t *) data)->price);
if (((balance_pair_t *) data)->price) if (((balance_pair_t *) data)->price)
return *(((balance_pair_t *) data)->price); return *(((balance_pair_t *) data)->price);
else else
return ((balance_pair_t *) data)->quantity; return 0L;
default: default:
assert(0); assert(0);