summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--journal.cc37
-rw-r--r--journal.h4
-rw-r--r--main.cc10
-rw-r--r--valexpr.cc54
-rw-r--r--valexpr.h37
5 files changed, 94 insertions, 48 deletions
diff --git a/journal.cc b/journal.cc
index 7fcb4dda..e7f41679 100644
--- a/journal.cc
+++ b/journal.cc
@@ -32,6 +32,7 @@
#include "journal.h"
#include "utils.h"
#include "valexpr.h"
+#include "format.h"
#include "mask.h"
namespace ledger {
@@ -639,42 +640,6 @@ bool journal_t::valid() const
return true;
}
-void print_entry(std::ostream& out, const entry_base_t& entry_base,
- const string& prefix)
-{
- string print_format;
-
- if (dynamic_cast<const entry_t *>(&entry_base)) {
- print_format = (prefix + "%D %X%C%P\n" +
- prefix + " %-34A %12o\n%/" +
- prefix + " %-34A %12o\n");
- }
- else if (const auto_entry_t * entry =
- dynamic_cast<const auto_entry_t *>(&entry_base)) {
- out << "= " << entry->predicate.predicate.expr << '\n';
- print_format = prefix + " %-34A %12o\n";
- }
- else if (const period_entry_t * entry =
- dynamic_cast<const period_entry_t *>(&entry_base)) {
- out << "~ " << entry->period_string << '\n';
- print_format = prefix + " %-34A %12o\n";
- }
- else {
- assert(false);
- }
-
-#if 0
- format_entries formatter(out, print_format);
- walk_transactions(const_cast<transactions_list&>(entry_base.transactions),
- formatter);
- formatter.flush();
-
- clear_transaction_xdata cleaner;
- walk_transactions(const_cast<transactions_list&>(entry_base.transactions),
- cleaner);
-#endif
-}
-
void entry_context::describe(std::ostream& out) const throw()
{
if (! desc.empty())
diff --git a/journal.h b/journal.h
index 2f34b2d1..c009f047 100644
--- a/journal.h
+++ b/journal.h
@@ -252,7 +252,9 @@ class auto_entry_t : public entry_base_t
public:
item_predicate<transaction_t> predicate;
- auto_entry_t();
+ auto_entry_t() {
+ TRACE_CTOR(auto_entry_t, "");
+ }
auto_entry_t(const string& _predicate)
: predicate(_predicate)
{
diff --git a/main.cc b/main.cc
index 01b8eb97..cd22e58b 100644
--- a/main.cc
+++ b/main.cc
@@ -266,12 +266,11 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
// Are we handling the expr commands? Do so now.
- expr::context_scope_t doc_scope(report, &xml_document);
-
if (verb == "expr") {
value_expr expr(*arg);
IF_INFO() {
+#if 0
*out << "Value expression tree:" << std::endl;
expr.dump(*out);
*out << std::endl;
@@ -279,9 +278,12 @@ 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
return 0;
}
@@ -289,13 +291,13 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
// Apply transforms to the hierarchical document structure
INFO_START(transforms, "Applied transforms");
- report.apply_transforms(doc_scope);
+ report.apply_transforms(*expr::global_scope);
INFO_FINISH(transforms);
// Create an argument scope containing the report command's
// arguments, and then invoke the command.
- xml::xpath_t::call_scope_t command_args(doc_scope);
+ expr::call_scope_t command_args(*expr::global_scope);
for (strings_list::iterator i = arg; i != args.end(); i++)
command_args.push_back(value_t(*i, true));
diff --git a/valexpr.cc b/valexpr.cc
index 5e0a1037..1f183a00 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -41,6 +41,29 @@ bool compute_amount(ptr_op_t expr, amount_t& amt,
return true;
}
+void scope_t::define(const string& name, const value_t& val) {
+ define(name, op_t::wrap_value(val));
+}
+
+void symbol_scope_t::define(const string& name, ptr_op_t def)
+{
+ DEBUG("ledger.xpath.syms", "Defining '" << name << "' = " << def);
+
+ std::pair<symbol_map::iterator, bool> result
+ = symbols.insert(symbol_map::value_type(name, def));
+ if (! result.second) {
+ symbol_map::iterator i = symbols.find(name);
+ assert(i != symbols.end());
+ symbols.erase(i);
+
+ std::pair<symbol_map::iterator, bool> result2
+ = symbols.insert(symbol_map::value_type(name, def));
+ if (! result2.second)
+ throw_(compile_error,
+ "Redefinition of '" << name << "' in same scope");
+ }
+}
+
namespace {
int count_leaves(ptr_op_t expr)
{
@@ -98,6 +121,37 @@ namespace {
}
}
+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
+ break;
+ }
+
+ symbol_map::const_iterator i = symbols.find(name);
+ if (i != symbols.end())
+ return (*i).second;
+
+ return child_scope_t::lookup(name);
+}
+
+
void op_t::compute(value_t& result, const details_t& details,
ptr_op_t context) const
{
diff --git a/valexpr.h b/valexpr.h
index 62302a87..20629c55 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -15,6 +15,10 @@ class account_t;
namespace expr {
+DECLARE_EXCEPTION(error, parse_error);
+DECLARE_EXCEPTION(error, compile_error);
+DECLARE_EXCEPTION(error, calc_error);
+
#if 0
struct context_t
{
@@ -642,9 +646,12 @@ bool compute_amount(const ptr_op_t expr, amount_t& amt,
#define PARSE_VALEXPR_NO_MIGRATE 0x04
#define PARSE_VALEXPR_NO_REDUCE 0x08
+ptr_op_t parse_boolean_expr(std::istream& in, scope_t * scope,
+ const short flags);
+
ptr_op_t parse_value_expr(std::istream& in,
- scope_t * scope = NULL,
- const short flags = PARSE_VALEXPR_RELAXED);
+ scope_t * scope = NULL,
+ const short flags = PARSE_VALEXPR_RELAXED);
inline ptr_op_t
parse_value_expr(const string& str,
@@ -743,6 +750,25 @@ scope_t::find_scope<context_scope_t>(bool skip_this) {
#define CONTEXT_SCOPE(scope_ref) \
FIND_SCOPE(context_scope_t, scope_ref)
+inline ptr_op_t op_t::new_node(kind_t _kind, ptr_op_t _left, ptr_op_t _right) {
+ ptr_op_t node(new op_t(_kind));
+ node->set_left(_left);
+ node->set_right(_right);
+ return node;
+}
+
+inline ptr_op_t op_t::wrap_value(const value_t& val) {
+ ptr_op_t temp(new op_t(op_t::VALUE));
+ temp->set_value(val);
+ return temp;
+}
+
+inline ptr_op_t op_t::wrap_functor(const function_t& fobj) {
+ ptr_op_t temp(new op_t(op_t::FUNCTION));
+ temp->set_function(fobj);
+ return temp;
+}
+
} // namespace expr
//////////////////////////////////////////////////////////////////////
@@ -866,15 +892,12 @@ inline value_t compute_total(const details_t& details = details_t()) {
return total_expr->compute(details);
}
-expr::ptr_op_t parse_boolean_expr(std::istream& in, expr::scope_t * scope,
- const short flags);
-
inline void parse_value_definition(const string& str,
expr::scope_t * scope = NULL) {
std::istringstream def(str);
value_expr expr
- (parse_boolean_expr(def, scope ? scope : expr::global_scope.get(),
- PARSE_VALEXPR_RELAXED));
+ (expr::parse_boolean_expr(def, scope ? scope : expr::global_scope.get(),
+ PARSE_VALEXPR_RELAXED));
}
//////////////////////////////////////////////////////////////////////