Removed some dead code and updated the binary streaming code for op_t and
value_t.
This commit is contained in:
parent
650527bef8
commit
891d7b87c8
6 changed files with 85 additions and 690 deletions
18
src/binary.h
18
src/binary.h
|
|
@ -148,26 +148,30 @@ void read_long(const char *& data, T& num)
|
|||
{
|
||||
read_guard(data, 0x2001);
|
||||
|
||||
unsigned char len;
|
||||
uint_least8_t len;
|
||||
read_number_nocheck(data, len);
|
||||
|
||||
num = 0;
|
||||
unsigned char temp;
|
||||
num = static_cast<T>(0);
|
||||
uint_least8_t temp;
|
||||
if (len > 3) {
|
||||
read_number_nocheck(data, temp);
|
||||
num |= static_cast<unsigned long>(temp) << 24;
|
||||
num = static_cast<T>(static_cast<uint_least32_t>(num) |
|
||||
(static_cast<uint_least32_t>(temp) << 24));
|
||||
}
|
||||
if (len > 2) {
|
||||
read_number_nocheck(data, temp);
|
||||
num |= static_cast<unsigned long>(temp) << 16;
|
||||
num = static_cast<T>(static_cast<uint_least32_t>(num) |
|
||||
(static_cast<uint_least32_t>(temp) << 16));
|
||||
}
|
||||
if (len > 1) {
|
||||
read_number_nocheck(data, temp);
|
||||
num |= static_cast<unsigned long>(temp) << 8;
|
||||
num = static_cast<T>(static_cast<uint_least32_t>(num) |
|
||||
(static_cast<uint_least32_t>(temp) << 8));
|
||||
}
|
||||
|
||||
read_number_nocheck(data, temp);
|
||||
num |= static_cast<unsigned long>(temp);
|
||||
num = static_cast<T>(static_cast<uint_least32_t>(num) |
|
||||
static_cast<uint_least32_t>(temp));
|
||||
|
||||
read_guard(data, 0x2002);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,13 +38,14 @@ namespace ledger {
|
|||
|
||||
class mask_t
|
||||
{
|
||||
mask_t();
|
||||
|
||||
public:
|
||||
boost::regex expr;
|
||||
|
||||
explicit mask_t(const string& pattern);
|
||||
|
||||
mask_t() : expr() {
|
||||
TRACE_CTOR(mask_t, "");
|
||||
}
|
||||
mask_t(const mask_t& m) : expr(m.expr) {
|
||||
TRACE_CTOR(mask_t, "copy");
|
||||
}
|
||||
|
|
|
|||
721
src/op.cc
721
src/op.cc
|
|
@ -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);
|
||||
if (kind > TERMINALS) {
|
||||
set_left(new expr_t::op_t());
|
||||
left()->read(data);
|
||||
|
||||
expr_t::ptr_op_t expr = new expr_t::op_t(kind);
|
||||
|
||||
if (kind > expr_t::op_t::TERMINALS)
|
||||
expr->set_left(read_value_expr(data));
|
||||
|
||||
switch (expr->kind) {
|
||||
case expr_t::op_t::INDEX: {
|
||||
long temp;
|
||||
read_long(data, temp);
|
||||
expr->set_index(temp);
|
||||
break;
|
||||
if (binary::read_bool(data)) {
|
||||
set_right(new expr_t::op_t());
|
||||
right()->read(data);
|
||||
}
|
||||
}
|
||||
case expr_t::op_t::VALUE: {
|
||||
|
||||
switch (kind) {
|
||||
case VALUE: {
|
||||
value_t temp;
|
||||
read_value(data, temp);
|
||||
expr->set_value(temp);
|
||||
temp.read(data);
|
||||
set_value(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
case expr_t::op_t::MASK:
|
||||
if (read_bool(data))
|
||||
read_mask(data, expr->as_mask_lval());
|
||||
case IDENT: {
|
||||
string temp;
|
||||
binary::read_string(data, temp);
|
||||
set_ident(temp);
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
binary::write_long<kind_t>(out, kind);
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
|
|
|||
7
src/op.h
7
src/op.h
|
|
@ -42,8 +42,6 @@ class expr_t::op_t : public noncopyable
|
|||
friend class expr_t;
|
||||
friend class expr_t::parser_t;
|
||||
|
||||
op_t();
|
||||
|
||||
public:
|
||||
typedef expr_t::ptr_op_t ptr_op_t;
|
||||
|
||||
|
|
@ -106,11 +104,16 @@ public:
|
|||
|
||||
OPERATORS,
|
||||
|
||||
UNKNOWN,
|
||||
|
||||
LAST
|
||||
};
|
||||
|
||||
kind_t kind;
|
||||
|
||||
explicit op_t() : refc(0), kind(UNKNOWN) {
|
||||
TRACE_CTOR(op_t, "");
|
||||
}
|
||||
explicit op_t(const kind_t _kind) : refc(0), kind(_kind) {
|
||||
TRACE_CTOR(op_t, "const kind_t");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ public:
|
|||
void clean_xacts(entry_t& entry);
|
||||
|
||||
void clean_all() {
|
||||
clear_xacts();
|
||||
clear_accounts();
|
||||
clean_xacts();
|
||||
clean_accounts();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
20
src/value.cc
20
src/value.cc
|
|
@ -1706,19 +1706,13 @@ void value_t::read(const char *& data)
|
|||
set_boolean(binary::read_bool(data));
|
||||
break;
|
||||
case INTEGER:
|
||||
set_long(binary::read_long<unsigned long>(data));
|
||||
set_long(binary::read_long<long>(data));
|
||||
break;
|
||||
case DATETIME:
|
||||
#if 0
|
||||
// jww (2008-04-22): I need to record and read a datetime_t directly
|
||||
set_datetime(read_long<unsigned long>(data));
|
||||
#endif
|
||||
set_datetime(parse_datetime(binary::read_string(data)));
|
||||
break;
|
||||
case DATE:
|
||||
#if 0
|
||||
// jww (2008-04-22): I need to record and read a date_t directly
|
||||
set_date(read_long<unsigned long>(data));
|
||||
#endif
|
||||
set_date(parse_date(binary::read_string(data)));
|
||||
break;
|
||||
case AMOUNT: {
|
||||
amount_t temp;
|
||||
|
|
@ -1745,14 +1739,10 @@ void value_t::write(std::ostream& out) const
|
|||
binary::write_long(out, as_long());
|
||||
break;
|
||||
case DATETIME:
|
||||
#if 0
|
||||
binary::write_number(out, as_datetime());
|
||||
#endif
|
||||
binary::write_string(out, format_datetime(as_datetime()));
|
||||
break;
|
||||
case DATE:
|
||||
#if 0
|
||||
binary::write_number(out, as_date());
|
||||
#endif
|
||||
binary::write_string(out, format_date(as_date()));
|
||||
break;
|
||||
case AMOUNT:
|
||||
as_amount().write(out);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue