Cleaned up the value expression code a bit before undertaking the real work of
getting everything back up to what it was (plus the new code written for 3.0).
This commit is contained in:
parent
0c76ac5b8f
commit
e14d7b6e54
11 changed files with 170 additions and 1241 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -10,6 +10,7 @@
|
|||
.svn
|
||||
/.deps
|
||||
/.libs
|
||||
/3.0
|
||||
/AUTHORS
|
||||
/COPYING
|
||||
/ChangeLog
|
||||
|
|
|
|||
46
main.cc
46
main.cc
|
|
@ -45,6 +45,19 @@
|
|||
#include <fdstream.hpp>
|
||||
#endif
|
||||
|
||||
namespace ledger {
|
||||
value_t register_command(expr::call_scope_t& args)
|
||||
{
|
||||
expr::var_t<report_t> report(args, 0);
|
||||
expr::var_t<std::ostream> ostream(args, 1);
|
||||
|
||||
report->transactions_report
|
||||
(xact_handler_ptr(new format_transactions
|
||||
(*ostream, report->session.register_format)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||
char * envp[])
|
||||
{
|
||||
|
|
@ -158,31 +171,29 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
value_expr expr(*arg);
|
||||
|
||||
#if 0
|
||||
expr::context_scope_t doc_scope(report, &temp);
|
||||
|
||||
IF_INFO() {
|
||||
std::cout << "Value expression tree:" << std::endl;
|
||||
expr.dump(std::cout);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Value expression parsed was:" << std::endl;
|
||||
expr.print(std::cout, doc_scope);
|
||||
expr.print(std::cout, report);
|
||||
std::cout << std::endl << std::endl;
|
||||
|
||||
expr.compile(doc_scope);
|
||||
expr.compile(report);
|
||||
|
||||
std::cout << "Value expression after compiling:" << std::endl;
|
||||
expr.dump(std::cout);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Value expression is now:" << std::endl;
|
||||
expr.print(std::cout, doc_scope);
|
||||
expr.print(std::cout, report);
|
||||
std::cout << std::endl << std::endl;
|
||||
|
||||
std::cout << "Result of calculation: ";
|
||||
}
|
||||
|
||||
std::cout << expr.calc(doc_scope).strip_annotations() << std::endl;
|
||||
std::cout << expr.calc(report).strip_annotations() << std::endl;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
@ -218,8 +229,8 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
if (verb == "expr") {
|
||||
value_expr expr(*arg);
|
||||
|
||||
IF_INFO() {
|
||||
#if 0
|
||||
IF_INFO() {
|
||||
*out << "Value expression tree:" << std::endl;
|
||||
expr.dump(*out);
|
||||
*out << std::endl;
|
||||
|
|
@ -227,10 +238,8 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
expr.print(*out, doc_scope);
|
||||
*out << std::endl << std::endl;
|
||||
*out << "Result of calculation: ";
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
*out << expr.calc(doc_scope).strip_annotations() << std::endl;
|
||||
#endif
|
||||
|
||||
|
|
@ -239,14 +248,13 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
|
||||
// Read the command word and create a command object based on it
|
||||
|
||||
expr::function_t command;
|
||||
|
||||
if (verb == "register" || verb == "reg" || verb == "r")
|
||||
report.transactions_report
|
||||
(xact_handler_ptr(new format_transactions(*out, session.register_format)));
|
||||
else if (verb == "balance" || verb == "bal" || verb == "b")
|
||||
report.accounts_report
|
||||
(acct_handler_ptr(new format_accounts(*out, session.balance_format,
|
||||
report.display_predicate)));
|
||||
command = register_command;
|
||||
#if 0
|
||||
else if (verb == "balance" || verb == "bal" || verb == "b")
|
||||
command = balance_command();
|
||||
else if (verb == "print" || verb == "p")
|
||||
command = print_command();
|
||||
else if (verb == "equity")
|
||||
|
|
@ -266,8 +274,8 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
else if (verb == "emacs" || verb == "lisp")
|
||||
command = emacs_command();
|
||||
else if (verb == "xml")
|
||||
command = bind(xml_command, _1);
|
||||
;
|
||||
command = xml_command();
|
||||
#endif
|
||||
else if (verb == "expr")
|
||||
;
|
||||
else if (verb == "xpath")
|
||||
|
|
@ -289,6 +297,9 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
|
||||
expr::call_scope_t command_args(report);
|
||||
|
||||
command_args.push_back(value_t(&report));
|
||||
command_args.push_back(value_t(out));
|
||||
|
||||
for (strings_list::iterator i = arg; i != args.end(); i++)
|
||||
command_args.push_back(value_t(*i, true));
|
||||
|
||||
|
|
@ -297,7 +308,6 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
|||
command(command_args);
|
||||
|
||||
INFO_FINISH(command);
|
||||
#endif
|
||||
|
||||
// Clean up memory, if it matters
|
||||
|
||||
|
|
|
|||
16
option.cc
16
option.cc
|
|
@ -888,25 +888,25 @@ OPT_BEGIN(download, "Q") {
|
|||
} OPT_END(download);
|
||||
|
||||
OPT_BEGIN(quantity, "O") {
|
||||
ledger::amount_expr = "@a";
|
||||
ledger::total_expr = "@O";
|
||||
ledger::amount_expr = "a";
|
||||
ledger::total_expr = "O";
|
||||
} OPT_END(quantity);
|
||||
|
||||
OPT_BEGIN(basis, "B") {
|
||||
ledger::amount_expr = "@b";
|
||||
ledger::total_expr = "@B";
|
||||
ledger::amount_expr = "b";
|
||||
ledger::total_expr = "B";
|
||||
} OPT_END(basis);
|
||||
|
||||
OPT_BEGIN(price, "I") {
|
||||
ledger::amount_expr = "@i";
|
||||
ledger::total_expr = "@I";
|
||||
ledger::amount_expr = "i";
|
||||
ledger::total_expr = "I";
|
||||
} OPT_END(price);
|
||||
|
||||
OPT_BEGIN(market, "V") {
|
||||
report->show_revalued = true;
|
||||
|
||||
ledger::amount_expr = "@v";
|
||||
ledger::total_expr = "@V";
|
||||
ledger::amount_expr = "v";
|
||||
ledger::total_expr = "V";
|
||||
} OPT_END(market);
|
||||
|
||||
namespace {
|
||||
|
|
|
|||
1122
parsexp.cc
1122
parsexp.cc
File diff suppressed because it is too large
Load diff
59
parsexp.h
59
parsexp.h
|
|
@ -95,11 +95,6 @@ private:
|
|||
KW_OR,
|
||||
KW_MOD,
|
||||
|
||||
#if 0
|
||||
PIPE, // |
|
||||
KW_UNION,
|
||||
#endif
|
||||
|
||||
COMMA, // ,
|
||||
|
||||
TOK_EOF,
|
||||
|
|
@ -113,13 +108,6 @@ private:
|
|||
explicit token_t() : kind(UNKNOWN), length(0) {
|
||||
TRACE_CTOR(token_t, "");
|
||||
}
|
||||
#if 0
|
||||
token_t(const token_t& other) {
|
||||
assert(false);
|
||||
TRACE_CTOR(token_t, "copy");
|
||||
*this = other;
|
||||
}
|
||||
#endif
|
||||
~token_t() throw() {
|
||||
TRACE_DTOR(token_t);
|
||||
}
|
||||
|
|
@ -166,29 +154,16 @@ private:
|
|||
assert(&tok == &lookahead);
|
||||
use_lookahead = true;
|
||||
}
|
||||
|
||||
void push_token() const
|
||||
{
|
||||
use_lookahead = true;
|
||||
}
|
||||
|
||||
public:
|
||||
value_expr expr;
|
||||
|
||||
private:
|
||||
ptr_op_t parse_value_term(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
#if 0
|
||||
ptr_op_t parse_predicate_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
ptr_op_t parse_path_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
#endif
|
||||
ptr_op_t parse_unary_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
#if 0
|
||||
ptr_op_t parse_union_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
#endif
|
||||
ptr_op_t parse_mul_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
ptr_op_t parse_add_expr(std::istream& in, scope_t& scope,
|
||||
|
|
@ -204,17 +179,18 @@ private:
|
|||
ptr_op_t parse_value_expr(std::istream& in, scope_t& scope,
|
||||
const flags_t flags) const;
|
||||
|
||||
value_expr& parse_expr(std::istream& in, string& str,
|
||||
scope_t& scope, const flags_t flags) {
|
||||
value_expr parse_expr(std::istream& in, string& str,
|
||||
scope_t& scope, const flags_t flags) {
|
||||
try {
|
||||
ptr_op_t top_node = parse_value_expr(in, scope, flags);
|
||||
expr = value_expr(top_node, str);
|
||||
|
||||
if (use_lookahead) {
|
||||
use_lookahead = false;
|
||||
lookahead.rewind(in);
|
||||
}
|
||||
lookahead.clear();
|
||||
|
||||
return value_expr(top_node, str);
|
||||
}
|
||||
catch (error * err) {
|
||||
err->context.push_back
|
||||
|
|
@ -222,48 +198,37 @@ private:
|
|||
"While parsing value expression:"));
|
||||
throw err;
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
public:
|
||||
parser_t() : use_lookahead(false) {}
|
||||
|
||||
value_expr& parse(std::istream& in,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
value_expr parse(std::istream& in,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
{
|
||||
return parse_expr(in, empty_string, *global_scope, flags);
|
||||
}
|
||||
|
||||
value_expr& parse(std::istream& in, scope_t& scope,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
value_expr parse(std::istream& in, scope_t& scope,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
{
|
||||
return parse_expr(in, empty_string, scope, flags);
|
||||
}
|
||||
|
||||
value_expr& parse(string& str, const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
value_expr parse(string& str, const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
{
|
||||
std::istringstream stream(str);
|
||||
return parse_expr(stream, str, *global_scope, flags);
|
||||
}
|
||||
|
||||
value_expr& parse(string& str, scope_t& scope,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
value_expr parse(string& str, scope_t& scope,
|
||||
const flags_t flags = EXPR_PARSE_RELAXED)
|
||||
{
|
||||
std::istringstream stream(str);
|
||||
return parse_expr(stream, str, scope, flags);
|
||||
}
|
||||
};
|
||||
|
||||
void dump(std::ostream& out, const ptr_op_t node, const int depth = 0);
|
||||
|
||||
bool print(std::ostream& out,
|
||||
const ptr_op_t node,
|
||||
const bool relaxed = true,
|
||||
const ptr_op_t node_to_find = NULL,
|
||||
unsigned long * start_pos = NULL,
|
||||
unsigned long * end_pos = NULL);
|
||||
|
||||
} // namespace expr
|
||||
} // namespace ledger
|
||||
|
||||
|
|
|
|||
4
report.h
4
report.h
|
|
@ -168,8 +168,8 @@ public:
|
|||
eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)");
|
||||
#endif
|
||||
|
||||
value_expr::amount_expr.reset(new value_expr("@a"));
|
||||
value_expr::total_expr.reset(new value_expr("@O"));
|
||||
value_expr::amount_expr.reset(new value_expr("a"));
|
||||
value_expr::total_expr.reset(new value_expr("O"));
|
||||
}
|
||||
|
||||
virtual ~report_t() {
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@ session_t::session_t()
|
|||
equity_format
|
||||
("\n%D %Y%C%P\n%/ %-34W %12t\n"),
|
||||
plot_amount_format
|
||||
("%D %(@S(@t))\n"),
|
||||
("%D %(S(t))\n"),
|
||||
plot_total_format
|
||||
("%D %(@S(@T))\n"),
|
||||
("%D %(S(T))\n"),
|
||||
write_hdr_format
|
||||
("%d %Y%C%P\n"),
|
||||
write_xact_format
|
||||
|
|
|
|||
25
valexpr.cc
25
valexpr.cc
|
|
@ -163,26 +163,17 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
value_t get_amount(scope_t& scope)
|
||||
{
|
||||
assert("I can't get the amount!");
|
||||
}
|
||||
|
||||
ptr_op_t symbol_scope_t::lookup(const string& name)
|
||||
{
|
||||
switch (name[0]) {
|
||||
#if 0
|
||||
case 'l':
|
||||
if (name == "last")
|
||||
return WRAP_FUNCTOR(bind(xpath_fn_last, _1));
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (name == "position")
|
||||
return WRAP_FUNCTOR(bind(xpath_fn_position, _1));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (name == "text")
|
||||
return WRAP_FUNCTOR(bind(xpath_fn_text, _1));
|
||||
else if (name == "type")
|
||||
return WRAP_FUNCTOR(bind(xpath_fn_type, _1));
|
||||
#endif
|
||||
case 'a':
|
||||
if (name[1] == '\0' || name == "amount")
|
||||
return WRAP_FUNCTOR(bind(get_amount, _1));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
32
valexpr.h
32
valexpr.h
|
|
@ -449,6 +449,7 @@ public:
|
|||
O_DEF,
|
||||
O_REF,
|
||||
O_ARG,
|
||||
O_LOOKUP,
|
||||
|
||||
LAST
|
||||
};
|
||||
|
|
@ -902,6 +903,37 @@ public:
|
|||
return temp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void compile(scope_t& scope) {
|
||||
if (ptr.get())
|
||||
ptr = ptr->compile(scope);
|
||||
}
|
||||
|
||||
value_t calc(scope_t& scope) const {
|
||||
if (ptr.get())
|
||||
return ptr->calc(scope);
|
||||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
static value_t eval(const string& _expr, scope_t& scope) {
|
||||
return xpath_t(_expr).calc(scope);
|
||||
}
|
||||
|
||||
path_iterator_t find_all(scope_t& scope) {
|
||||
return path_iterator_t(*this, scope);
|
||||
}
|
||||
|
||||
void print(std::ostream& out, scope_t& scope) const {
|
||||
op_t::print_context_t context(scope);
|
||||
print(out, context);
|
||||
}
|
||||
|
||||
void dump(std::ostream& out) const {
|
||||
if (ptr)
|
||||
ptr->dump(out, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
friend bool print_value_expr(std::ostream& out,
|
||||
const expr::ptr_op_t node,
|
||||
const expr::ptr_op_t node_to_find,
|
||||
|
|
|
|||
97
value.cc
97
value.cc
|
|
@ -1482,8 +1482,8 @@ value_t& value_t::add(const amount_t& amount, const optional<amount_t>& tcost)
|
|||
return *this;
|
||||
}
|
||||
|
||||
void value_t::print(std::ostream& out, const int first_width,
|
||||
const int latter_width) const
|
||||
void value_t::dump(std::ostream& out, const int first_width,
|
||||
const int latter_width) const
|
||||
{
|
||||
switch (type()) {
|
||||
case VOID:
|
||||
|
|
@ -1523,7 +1523,7 @@ void value_t::print(std::ostream& out, const int first_width,
|
|||
else
|
||||
out << ", ";
|
||||
|
||||
value.print(out, first_width, latter_width);
|
||||
value.dump(out, first_width, latter_width);
|
||||
}
|
||||
out << ')';
|
||||
break;
|
||||
|
|
@ -1541,6 +1541,66 @@ void value_t::print(std::ostream& out, const int first_width,
|
|||
}
|
||||
}
|
||||
|
||||
void value_t::print(std::ostream& out, const bool relaxed) const
|
||||
{
|
||||
switch (type()) {
|
||||
case VOID:
|
||||
out << "";
|
||||
break;
|
||||
|
||||
case BOOLEAN:
|
||||
if (as_boolean())
|
||||
out << "true";
|
||||
else
|
||||
out << "false";
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
out << as_long();
|
||||
break;
|
||||
|
||||
case AMOUNT:
|
||||
if (! relaxed)
|
||||
out << '{';
|
||||
out << as_amount();
|
||||
if (! relaxed)
|
||||
out << '}';
|
||||
break;
|
||||
|
||||
case BALANCE:
|
||||
case BALANCE_PAIR:
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
case DATETIME:
|
||||
out << '[' << format_datetime(as_datetime()) << ']';
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
out << '"' << as_string() << '"';
|
||||
break;
|
||||
|
||||
case POINTER:
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
case SEQUENCE: {
|
||||
out << '(';
|
||||
bool first = true;
|
||||
foreach (const value_t& value, as_sequence()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out << ", ";
|
||||
|
||||
value.print(out, relaxed);
|
||||
}
|
||||
out << ')';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool value_t::valid() const
|
||||
{
|
||||
switch (type()) {
|
||||
|
|
@ -1561,38 +1621,9 @@ void value_context::describe(std::ostream& out) const throw()
|
|||
if (! desc.empty())
|
||||
out << desc << std::endl;
|
||||
|
||||
const balance_t * ptr = NULL;
|
||||
|
||||
out << std::right;
|
||||
out.width(20);
|
||||
|
||||
switch (bal.type()) {
|
||||
case value_t::BOOLEAN:
|
||||
out << (bal.as_boolean() ? "true" : "false");
|
||||
break;
|
||||
case value_t::INTEGER:
|
||||
out << bal.as_long();
|
||||
break;
|
||||
case value_t::DATETIME:
|
||||
out << bal.as_datetime();
|
||||
break;
|
||||
case value_t::AMOUNT:
|
||||
out << bal.as_amount();
|
||||
break;
|
||||
case value_t::BALANCE:
|
||||
ptr = &bal.as_balance();
|
||||
// fall through...
|
||||
|
||||
case value_t::BALANCE_PAIR:
|
||||
if (! ptr)
|
||||
ptr = &bal.as_balance_pair().quantity();
|
||||
|
||||
ptr->print(out, 20);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
bal.print(out);
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
|||
5
value.h
5
value.h
|
|
@ -832,8 +832,9 @@ public:
|
|||
/**
|
||||
* Printing methods.
|
||||
*/
|
||||
void print(std::ostream& out, const int first_width,
|
||||
const int latter_width = -1) const;
|
||||
void dump(std::ostream& out, const int first_width,
|
||||
const int latter_width = -1) const;
|
||||
void print(std::ostream& out, const bool relaxed = true) const;
|
||||
|
||||
/**
|
||||
* Debugging methods.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue