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:
John Wiegley 2008-07-27 20:37:21 -04:00
parent 0c76ac5b8f
commit e14d7b6e54
11 changed files with 170 additions and 1241 deletions

1
.gitignore vendored
View file

@ -10,6 +10,7 @@
.svn
/.deps
/.libs
/3.0
/AUTHORS
/COPYING
/ChangeLog

46
main.cc
View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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() {

View file

@ -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

View file

@ -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;
}

View file

@ -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,

View file

@ -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;
}

View file

@ -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.