diff options
author | John Wiegley <johnw@newartisans.com> | 2008-08-17 03:15:57 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-08-17 03:15:57 -0400 |
commit | 891d7b87c8bd9c2387a945a22b41f9b8f94f3327 (patch) | |
tree | 8d4ca5757a923d80bf82f625a16746aac68a0043 /src/op.cc | |
parent | 650527bef8bdac0edf08b383f6d721ca19aee5b1 (diff) | |
download | fork-ledger-891d7b87c8bd9c2387a945a22b41f9b8f94f3327.tar.gz fork-ledger-891d7b87c8bd9c2387a945a22b41f9b8f94f3327.tar.bz2 fork-ledger-891d7b87c8bd9c2387a945a22b41f9b8f94f3327.zip |
Removed some dead code and updated the binary streaming code for op_t and
value_t.
Diffstat (limited to 'src/op.cc')
-rw-r--r-- | src/op.cc | 719 |
1 files changed, 58 insertions, 661 deletions
@@ -35,573 +35,14 @@ namespace ledger { -#if 0 -void expr_t::op_t::compute(value_t& result, - const details_t& details, - ptr_op_t context) const -{ - try { - switch (kind) { - case INDEX: - throw compute_error("Cannot directly compute an argument index"); - - case VALUE: - result = as_value(); - break; - - case F_NOW: - result = terminus; - break; - - case AMOUNT: - if (details.xact) { - if (xact_has_xdata(*details.xact) && - xact_xdata_(*details.xact).dflags & XACT_COMPOUND) - result = xact_xdata_(*details.xact).value; - else - result = details.xact->amount; - } - else if (details.account && account_has_xdata(*details.account)) { - result = account_xdata(*details.account).value; - } - else { - result = 0L; - } - break; - - case PRICE: - if (details.xact) { - bool set = false; - if (xact_has_xdata(*details.xact)) { - xact_xdata_t& xdata(xact_xdata_(*details.xact)); - if (xdata.dflags & XACT_COMPOUND) { - result = xdata.value.value(); - set = true; - } - } - if (! set) { - optional<amount_t> value = details.xact->amount.value(); - if (value) - result = *value; - else - result = 0L; - } - } - else if (details.account && account_has_xdata(*details.account)) { - result = account_xdata(*details.account).value.value(); - } - else { - result = 0L; - } - break; - - case COST: - if (details.xact) { - bool set = false; - if (xact_has_xdata(*details.xact)) { - xact_xdata_t& xdata(xact_xdata_(*details.xact)); - if (xdata.dflags & XACT_COMPOUND) { - result = xdata.value.cost(); - set = true; - } - } - - if (! set) { - if (details.xact->cost) - result = *details.xact->cost; - else - result = details.xact->amount; - } - } - else if (details.account && account_has_xdata(*details.account)) { - result = account_xdata(*details.account).value.cost(); - } - else { - result = 0L; - } - break; - - case TOTAL: - if (details.xact && xact_has_xdata(*details.xact)) - result = xact_xdata_(*details.xact).total; - else if (details.account && account_has_xdata(*details.account)) - result = account_xdata(*details.account).total; - else - result = 0L; - break; - case PRICE_TOTAL: - if (details.xact && xact_has_xdata(*details.xact)) - result = xact_xdata_(*details.xact).total.value(); - else if (details.account && account_has_xdata(*details.account)) - result = account_xdata(*details.account).total.value(); - else - result = 0L; - break; - case COST_TOTAL: - if (details.xact && xact_has_xdata(*details.xact)) - result = xact_xdata_(*details.xact).total.cost(); - else if (details.account && account_has_xdata(*details.account)) - result = account_xdata(*details.account).total.cost(); - else - result = 0L; - break; - - case VALUE_EXPR: - if (value_expr::amount_expr.get()) - value_expr::amount_expr->compute(result, details, context); - else - result = 0L; - break; - case TOTAL_EXPR: - if (value_expr::total_expr.get()) - value_expr::total_expr->compute(result, details, context); - else - result = 0L; - break; - - case DATE: - if (details.xact && xact_has_xdata(*details.xact) && - is_valid(xact_xdata_(*details.xact).date)) - result = xact_xdata_(*details.xact).date; - else if (details.xact) - result = details.xact->date(); - else if (details.entry) - result = details.entry->date(); - else - result = terminus; - break; - - case ACT_DATE: - if (details.xact && xact_has_xdata(*details.xact) && - is_valid(xact_xdata_(*details.xact).date)) - result = xact_xdata_(*details.xact).date; - else if (details.xact) - result = details.xact->actual_date(); - else if (details.entry) - result = details.entry->actual_date(); - else - result = terminus; - break; - - case EFF_DATE: - if (details.xact && xact_has_xdata(*details.xact) && - is_valid(xact_xdata_(*details.xact).date)) - result = xact_xdata_(*details.xact).date; - else if (details.xact) - result = details.xact->effective_date(); - else if (details.entry) - result = details.entry->effective_date(); - else - result = terminus; - break; - - case CLEARED: - if (details.xact) - result = details.xact->state == xact_t::CLEARED; - else - result = false; - break; - case PENDING: - if (details.xact) - result = details.xact->state == xact_t::PENDING; - else - result = false; - break; - - case REAL: - if (details.xact) - result = ! (details.xact->has_flags(XACT_VIRTUAL)); - else - result = true; - break; - - case ACTUAL: - if (details.xact) - result = ! (details.xact->has_flags(XACT_AUTO)); - else - result = true; - break; - - case INDEX: - if (details.xact && xact_has_xdata(*details.xact)) - result = long(xact_xdata_(*details.xact).index + 1); - else if (details.account && account_has_xdata(*details.account)) - result = long(account_xdata(*details.account).count); - else - result = 0L; - break; - - case COUNT: - if (details.xact && xact_has_xdata(*details.xact)) - result = long(xact_xdata_(*details.xact).index + 1); - else if (details.account && account_has_xdata(*details.account)) - result = long(account_xdata(*details.account).total_count); - else - result = 0L; - break; - - case DEPTH: - if (details.account) - result = long(details.account->depth); - else - result = 0L; - break; - - case F_PRICE: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - result = result.value(); - break; - } - - case F_DATE: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - result = result.as_datetime(); - break; - } - - case F_DATECMP: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - result = result.as_datetime(); - if (! result) - break; - - arg_index = 0; - expr = find_leaf(context, 1, arg_index); - value_t moment; - expr->compute(moment, details, context); - if (moment.is_type(value_t::DATETIME)) { - result.cast(value_t::INTEGER); - moment.cast(value_t::INTEGER); - result -= moment; - } else { - add_error_context(expr_context(expr)); - throw compute_error("Invalid date passed to datecmp(value,date)"); - } - break; - } - - case F_YEAR: - case F_MONTH: - case F_DAY: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - - if (! result.is_type(value_t::DATETIME)) { - add_error_context(expr_context(expr)); - throw compute_error("Invalid date passed to year|month|day(date)"); - } - - const date_t& moment(result.as_date()); - switch (kind) { - case F_YEAR: - result = (long)moment.year(); - break; - case F_MONTH: - result = (long)moment.month(); - break; - case F_DAY: - result = (long)moment.day(); - break; - default: - break; - } - break; - } - - case F_ARITH_MEAN: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - if (details.xact && xact_has_xdata(*details.xact)) { - expr->compute(result, details, context); - result /= amount_t(long(xact_xdata_(*details.xact).index + 1)); - } - else if (details.account && account_has_xdata(*details.account) && - account_xdata(*details.account).total_count) { - expr->compute(result, details, context); - result /= amount_t(long(account_xdata(*details.account).total_count)); - } - else { - result = 0L; - } - break; - } - - case F_PARENT: - if (details.account && details.account->parent) - left()->compute(result, details_t(*details.account->parent), context); - break; - - case F_ABS: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - result.abs(); - break; - } - - case F_ROUND: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - result.round(); - break; - } - - case F_COMMODITY: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - if (! result.is_type(value_t::AMOUNT)) { - add_error_context(expr_context(expr)); - throw compute_error("Argument to commodity() must be a commoditized amount"); - } - amount_t temp("1"); - temp.set_commodity(result.as_amount().commodity()); - result = temp; - break; - } - - case F_SET_COMMODITY: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - value_t temp; - expr->compute(temp, details, context); - - arg_index = 0; - expr = find_leaf(context, 1, arg_index); - expr->compute(result, details, context); - if (! result.is_type(value_t::AMOUNT)) { - add_error_context(expr_context(expr)); - throw compute_error("Second argument to set_commodity() must be a commoditized amount"); - } - amount_t one("1"); - one.set_commodity(result.as_amount().commodity()); - result = one; - - result *= temp; - break; - } - - case F_QUANTITY: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - - const balance_t * bal = NULL; - switch (result.type()) { - case value_t::BALANCE_PAIR: - bal = &(result.as_balance_pair().quantity()); - // fall through... - - case value_t::BALANCE: - if (! bal) - bal = &result.as_balance(); - - if (bal->amounts.size() < 2) { - result.cast(value_t::AMOUNT); - } else { - value_t temp; - for (balance_t::amounts_map::value_type pair, bal->amounts) { - amount_t x = pair.second; - x.clear_commodity(); - temp += x; - } - result = temp; - assert(temp.is_type(value_t::AMOUNT)); - } - // fall through... - - case value_t::AMOUNT: - result.as_amount_lval().clear_commodity(); - break; - - default: - break; - } - break; - } - - case O_ARG: { - long arg_index = 0; - assert(left()->kind == INDEX); - ptr_op_t expr = find_leaf(context, left()->as_long(), arg_index); - if (expr) - expr->compute(result, details, context); - else - result = 0L; - break; - } - - case O_COMMA: - if (! left()) { - add_error_context(expr_context(*this)); - throw compute_error("Comma operator missing left operand"); - } - if (! right()) { - add_error_context(expr_context(*this)); - throw compute_error("Comma operator missing right operand"); - } - right()->compute(result, details, context); - break; - - case O_DEF: - result = 0L; - break; - - case O_REF: { - assert(left()); - if (right()) { - value_expr args(reduce_leaves(right(), details, context)); - left()->compute(result, details, args.get()); - } else { - left()->compute(result, details, context); - } - break; - } - - case F_VALUE: { - long arg_index = 0; - ptr_op_t expr = find_leaf(context, 0, arg_index); - expr->compute(result, details, context); - - arg_index = 0; - expr = find_leaf(context, 1, arg_index); - value_t moment; - expr->compute(moment, details, context); - if (! moment.is_type(value_t::DATETIME)) { - add_error_context(expr_context(expr)); - throw compute_error("Invalid date passed to P(value,date)"); - } - result = result.value(moment.as_datetime()); - break; - } - - case O_NOT: - left()->compute(result, details, context); - if (result.strip_annotations()) - result = false; - else - result = true; - break; - - case O_QUES: { - assert(left()); - assert(right()); - assert(right()->kind == O_COL); - left()->compute(result, details, context); - if (result.strip_annotations()) - right()->left()->compute(result, details, context); - else - right()->right()->compute(result, details, context); - break; - } - - case O_AND: - assert(left()); - assert(right()); - left()->compute(result, details, context); - result = result.strip_annotations(); - if (result) - right()->compute(result, details, context); - break; - - case O_OR: - assert(left()); - assert(right()); - left()->compute(result, details, context); - if (! result.strip_annotations()) - right()->compute(result, details, context); - break; - - case O_NEQ: - case O_EQ: - case O_LT: - case O_LTE: - case O_GT: - case O_GTE: { - assert(left()); - assert(right()); - value_t temp; - left()->compute(temp, details, context); - right()->compute(result, details, context); - switch (kind) { - case O_NEQ: result = temp != result; break; - case O_EQ: result = temp == result; break; - case O_LT: result = temp < result; break; - case O_LTE: result = temp <= result; break; - case O_GT: result = temp > result; break; - case O_GTE: result = temp >= result; break; - default: assert(false); break; - } - break; - } - - case O_NEG: - assert(left()); - left()->compute(result, details, context); - result.negate(); - break; - - case O_ADD: - case O_SUB: - case O_MUL: - case O_DIV: { - assert(left()); - assert(right()); - value_t temp; - right()->compute(temp, details, context); - left()->compute(result, details, context); - switch (kind) { - case O_ADD: result += temp; break; - case O_SUB: result -= temp; break; - case O_MUL: result *= temp; break; - case O_DIV: result /= temp; break; - default: assert(false); break; - } - break; - } - - case O_PERC: { - assert(left()); - result = "100.0%"; - value_t temp; - left()->compute(temp, details, context); - result *= temp; - break; - } - - case LAST: - default: - assert(false); - break; - } - } - catch (const std::exception& err) { - add_error_context(expr_context(*this)); - throw err; - } -} -#endif - expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope) { switch (kind) { case IDENT: if (ptr_op_t def = scope.lookup(as_ident())) { -#if 1 + // Definitions are compiled at the point of definition, not the + // point of use. return def; -#else - // jww (2008-08-02): Aren't definitions compiled when they go in? - // Would recompiling here really add any benefit? - return def->compile(scope); -#endif } return this; @@ -633,12 +74,6 @@ value_t expr_t::op_t::calc(scope_t& scope) return as_value(); case IDENT: -#if 0 - if (ptr_op_t reference = compile(scope)) { - if (reference != this) - return reference->calc(scope); - } -#endif throw_(calc_error, "Unknown identifier '" << as_ident() << "'"); case FUNCTION: { @@ -658,19 +93,6 @@ value_t expr_t::op_t::calc(scope_t& scope) ptr_op_t func = left(); string name; -#if 0 - // The expression must be compiled beforehand in order to resolve this - // into a function. - if (func->kind == IDENT) { - name = func->as_ident(); - ptr_op_t def = func->compile(scope); - if (def == func) - throw_(calc_error, - "Calling unknown function '" << name << "'"); - func = def; - } -#endif - if (func->kind != FUNCTION) throw_(calc_error, "Calling non-function"); @@ -1024,108 +446,83 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const void expr_t::op_t::read(const char *& data) { -#if 0 - if (! read_bool(data)) - return expr_t::ptr_op_t(); + kind = binary::read_long<kind_t>(data); - expr_t::op_t::kind_t kind; - read_number(data, kind); - - expr_t::ptr_op_t expr = new expr_t::op_t(kind); + if (kind > TERMINALS) { + set_left(new expr_t::op_t()); + left()->read(data); - if (kind > expr_t::op_t::TERMINALS) - expr->set_left(read_value_expr(data)); + if (binary::read_bool(data)) { + set_right(new expr_t::op_t()); + right()->read(data); + } + } - switch (expr->kind) { - case expr_t::op_t::INDEX: { - long temp; - read_long(data, temp); - expr->set_index(temp); + switch (kind) { + case VALUE: { + value_t temp; + temp.read(data); + set_value(temp); break; } - case expr_t::op_t::VALUE: { - value_t temp; - read_value(data, temp); - expr->set_value(temp); + case IDENT: { + string temp; + binary::read_string(data, temp); + set_ident(temp); break; } - - case expr_t::op_t::MASK: - if (read_bool(data)) - read_mask(data, expr->as_mask_lval()); + case MASK: { + mask_t temp; + temp.read(data); + set_mask(temp); + break; + } + case INDEX: { + long temp; + binary::read_long(data, temp); + set_index(temp); break; + } default: - if (kind > expr_t::op_t::TERMINALS) - expr->set_right(read_value_expr(data)); + assert(false); break; } - - return expr; -#endif } void expr_t::op_t::write(std::ostream& out) const { -#if 0 - if (! expr) { - write_bool(out, false); - return; - } - - write_bool(out, true); - write_number(out, expr->kind); - - if (expr->kind > expr_t::op_t::TERMINALS) - write_value_expr(out, expr->left()); - - switch (expr->kind) { - case expr_t::op_t::INDEX: - write_long(out, expr->as_index()); - break; - case expr_t::op_t::IDENT: - write_long(out, expr->as_ident()); - break; - case expr_t::op_t::VALUE: - write_value(out, expr->as_value()); - break; + binary::write_long<kind_t>(out, kind); - case expr_t::op_t::MASK: - if (expr->as_mask()) { - write_bool(out, true); - write_mask(out, expr->as_mask()); + if (kind > TERMINALS) { + left()->write(out); + if (right()) { + binary::write_bool(out, true); + right()->write(out); } else { - write_bool(out, false); + binary::write_bool(out, false); } - break; + } else { + switch (kind) { + case VALUE: + as_value().write(out); + break; + case IDENT: + binary::write_string(out, as_ident()); + break; + case MASK: + as_mask().write(out); + break; + case INDEX: + binary::write_long(out, as_index()); + break; - default: - if (expr->kind > expr_t::op_t::TERMINALS) - write_value_expr(out, expr->right()); - break; + case FUNCTION: // jww (2008-08-15): uh oh... + default: + assert(false); + break; + } } -#endif } -#if 0 -class op_predicate : public noncopyable -{ - ptr_op_t op; - - op_predicate(); - -public: - explicit op_predicate(ptr_op_t _op) : op(_op) { - TRACE_CTOR(op_predicate, "ptr_op_t"); - } - ~op_predicate() throw() { - TRACE_DTOR(op_predicate); - } - bool operator()(scope_t& scope) { - return op->calc(scope).to_boolean(); - } -}; - -#endif - } // namespace ledger |