summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-07-21 20:41:42 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-07-21 20:41:42 -0400
commitaa4f0d4364783ed5cbc97972755c7fd6b0da3cf0 (patch)
tree51c223e4f7dc4226831ae15330d424ff610a018f
parent8601a2a8bfd63b54a8c65d34ad021cbe2270d201 (diff)
downloadfork-ledger-aa4f0d4364783ed5cbc97972755c7fd6b0da3cf0.tar.gz
fork-ledger-aa4f0d4364783ed5cbc97972755c7fd6b0da3cf0.tar.bz2
fork-ledger-aa4f0d4364783ed5cbc97972755c7fd6b0da3cf0.zip
Added the var_t helper class, which can be seen in the beginning
implementation of register_command in main.cc.
-rw-r--r--main.cc23
-rw-r--r--option.cc30
-rw-r--r--report.cc2
-rw-r--r--valexpr.cc32
-rw-r--r--valexpr.h68
-rw-r--r--value.cc22
-rw-r--r--value.h4
7 files changed, 84 insertions, 97 deletions
diff --git a/main.cc b/main.cc
index 81567661..76517668 100644
--- a/main.cc
+++ b/main.cc
@@ -45,6 +45,17 @@
#include <fdstream.hpp>
#endif
+namespace ledger {
+ value_t register_command(expr::call_scope_t& args)
+ {
+ expr::var_t<std::ostream> ostream(args, "ostream");
+
+ *ostream << "This (will be) the register command.\n";
+
+ return true;
+ }
+}
+
static int read_and_report(ledger::report_t& report, int argc, char * argv[],
char * envp[])
{
@@ -109,9 +120,9 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
expr::function_t command;
-#if 0
if (verb == "register" || verb == "reg" || verb == "r")
- command = register_command();
+ command = register_command;
+#if 0
else if (verb == "balance" || verb == "bal" || verb == "b")
command = balance_command();
else if (verb == "print" || verb == "p")
@@ -132,12 +143,8 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
command = csv_command();
else if (verb == "emacs" || verb == "lisp")
command = emacs_command();
- else
-#endif
- if (verb == "xml")
-#if 0
+ else if (verb == "xml")
command = bind(xml_command, _1);
-#else
;
#endif
else if (verb == "expr")
@@ -297,7 +304,7 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
// Create an argument scope containing the report command's
// arguments, and then invoke the command.
- expr::call_scope_t command_args(*expr::global_scope);
+ expr::call_scope_t command_args(report);
for (strings_list::iterator i = arg; i != args.end(); i++)
command_args.push_back(value_t(*i, true));
diff --git a/option.cc b/option.cc
index 9f40f3d3..93b561f9 100644
--- a/option.cc
+++ b/option.cc
@@ -215,32 +215,12 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
process_option(o.get<0>()->as_function(), scope, value);
}
}
-#if 0
+ }
}
-//////////////////////////////////////////////////////////////////////
-
-namespace ledger {
-
-config_t * config = NULL;
-report_t * report = NULL;
-
-static void show_version(std::ostream& out)
-{
- out << "Ledger " << ledger::version << ", the command-line accounting tool";
- out << "\n\nCopyright (c) 2003-2008, John Wiegley. All rights reserved.\n\n\
-This program is made available under the terms of the BSD Public License.\n\
-See LICENSE file included with the distribution for details and disclaimer.\n";
- out << "\n(modules: gmp, pcre";
-#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
- out << ", xml";
-#endif
-#ifdef HAVE_LIBOFX
- out << ", ofx";
-#endif
- out << ")\n";
-}
+} // namespace ledger
+#if 0
void option_full_help(std::ostream& out)
{
out << "usage: ledger [options] COMMAND [ACCT REGEX]... [-- [PAYEE REGEX]...]\n\n\
@@ -948,8 +928,6 @@ namespace {
commodity->add_price(datetime_t::now, price);
commodity->history()->bogus_time = datetime_t::now;
}
-#endif
}
}
-
-} // namespace ledger
+#endif
diff --git a/report.cc b/report.cc
index f04e0327..8d2776e4 100644
--- a/report.cc
+++ b/report.cc
@@ -57,9 +57,9 @@ value_t report_t::abbrev(expr::call_scope_t& args)
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
string str = args[0].as_string();
+#if 0
long wid = args[1];
-#if 0
elision_style_t style = session.elision_style;
if (args.size() == 3)
style = static_cast<elision_style_t>(args[2].as_long());
diff --git a/valexpr.cc b/valexpr.cc
index 2bd1c7cf..8b92e0af 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -77,6 +77,14 @@ void scope_t::define(const string& name, const value_t& val) {
define(name, op_t::wrap_value(val));
}
+value_t scope_t::resolve(const string& name) {
+ ptr_op_t definition = lookup(name);
+ if (definition)
+ return definition->calc(*this);
+ else
+ return value_t();
+}
+
void symbol_scope_t::define(const string& name, ptr_op_t def)
{
DEBUG("ledger.xpath.syms", "Defining '" << name << "' = " << def);
@@ -817,10 +825,10 @@ void valexpr_context::describe(std::ostream& out) const throw()
#endif
}
-#if 0
-xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
+ptr_op_t op_t::compile(scope_t& scope)
{
switch (kind) {
+#if 0
case VAR_NAME:
case FUNC_NAME:
if (ptr_op_t def = scope.lookup(as_string())) {
@@ -833,6 +841,7 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
#endif
}
return this;
+#endif
default:
break;
@@ -856,14 +865,17 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
}
-value_t xpath_t::op_t::calc(scope_t& scope)
+value_t op_t::calc(scope_t& scope)
{
+#if 0
bool find_all_nodes = false;
+#endif
switch (kind) {
case VALUE:
return as_value();
+#if 0
case VAR_NAME:
case FUNC_NAME:
if (ptr_op_t reference = compile(scope)) {
@@ -873,6 +885,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
<< " named '" << as_string() << "'");
}
break;
+#endif
case FUNCTION:
// This should never be evaluated directly; it only appears as the
@@ -880,6 +893,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
assert(false);
break;
+#if 0
case O_CALL: {
call_scope_t call_args(scope);
@@ -901,6 +915,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
return func->as_function()(call_args);
}
+#endif
case ARG_INDEX: {
call_scope_t& args(CALL_SCOPE(scope));
@@ -912,6 +927,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
break;
}
+#if 0
case O_FIND:
case O_RFIND:
return select_nodes(scope, left()->calc(scope), right(), kind == O_RFIND);
@@ -997,6 +1013,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
return *value;
break;
+#endif
case O_NEQ:
return left()->calc(scope) != right()->calc(scope);
@@ -1033,14 +1050,16 @@ value_t xpath_t::op_t::calc(scope_t& scope)
case O_OR:
return left()->calc(scope) || right()->calc(scope);
- case O_COMMA:
- case O_UNION: {
+#if 0
+ case O_UNION:
+#endif
+ case O_COMMA: {
value_t result(left()->calc(scope));
ptr_op_t next = right();
while (next) {
ptr_op_t value_op;
- if (next->kind == O_COMMA || next->kind == O_UNION) {
+ if (next->kind == O_COMMA /* || next->kind == O_UNION */) {
value_op = next->left();
next = next->right();
} else {
@@ -1061,7 +1080,6 @@ value_t xpath_t::op_t::calc(scope_t& scope)
return NULL_VALUE;
}
-#endif
} // namespace expr
diff --git a/valexpr.h b/valexpr.h
index 608b1306..45f44b2e 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -152,13 +152,7 @@ public:
virtual void define(const string& name, ptr_op_t def) = 0;
void define(const string& name, const value_t& val);
virtual ptr_op_t lookup(const string& name) = 0;
- value_t resolve(const string& name) {
-#if 0
- return lookup(name)->calc(*this);
-#else
- return value_t();
-#endif
- }
+ value_t resolve(const string& name);
virtual optional<scope_t&> find_scope(const type_t _type,
bool skip_this = false) = 0;
@@ -273,10 +267,12 @@ public:
return args;
}
- value_t& operator[](const int index) {
+ value_t& operator[](const unsigned int index) {
+ // jww (2008-07-21): exception here if it's out of bounds
return args[index];
}
- const value_t& operator[](const int index) const {
+ const value_t& operator[](const unsigned int index) const {
+ // jww (2008-07-21): exception here if it's out of bounds
return args[index];
}
@@ -292,6 +288,21 @@ public:
}
};
+template <typename T>
+struct var_t
+{
+ T * value;
+
+ // jww (2008-07-21): Give a good exception here if we can't find "name"
+ var_t(scope_t& scope, const string& name)
+ : value(scope.resolve(name).template as_pointer<T>()) {}
+ var_t(call_scope_t& scope, const unsigned int idx)
+ : value(scope[idx].template as_pointer<T>()) {}
+
+ T& operator *() { return *value; }
+ T * operator->() { return value; }
+};
+
class context_scope_t : public child_scope_t
{
public:
@@ -748,40 +759,6 @@ inline ptr_op_t op_t::wrap_functor(const function_t& fobj) {
return temp;
}
-#if 0
-class xpath_t
-{
-public:
-public:
- void parse(const string& _expr, flags_t _flags = XPATH_PARSE_RELAXED) {
- expr = _expr;
- flags = _flags;
- ptr = parse_expr(_expr, _flags);
- }
- void parse(std::istream& in, flags_t _flags = XPATH_PARSE_RELAXED) {
- expr = "";
- flags = _flags;
- ptr = parse_expr(in, _flags);
- }
-
- 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);
- }
-
-};
-#endif
-
} // namespace expr
//////////////////////////////////////////////////////////////////////
@@ -826,11 +803,6 @@ public:
return ptr;
}
-#if 0
- const expr::op_t& operator*() const throw() {
- return *ptr;
- }
-#endif
const expr::ptr_op_t operator->() const throw() {
return ptr;
}
diff --git a/value.cc b/value.cc
index 16091e47..87b5f59a 100644
--- a/value.cc
+++ b/value.cc
@@ -1413,19 +1413,31 @@ void value_t::print(std::ostream& out, const int first_width,
{
switch (type()) {
case VOID:
- out << "NULL";
+ out << "VOID";
break;
case BOOLEAN:
+ out << const_cast<value_t&>(*this).as_boolean_lval();
+ break;
+
case DATETIME:
+ out << const_cast<value_t&>(*this).as_datetime_lval();
+ break;
+
case INTEGER:
+ out << const_cast<value_t&>(*this).as_long_lval();
+ break;
+
case AMOUNT:
+ out << const_cast<value_t&>(*this).as_amount_lval();
+ break;
+
case STRING:
+ out << const_cast<value_t&>(*this).as_string_lval();
+ break;
+
case POINTER:
- // jww (2007-05-14): I need a version of this print just for XPath
- // expression, since amounts and strings need to be output with
- // special syntax.
- out << *this;
+ out << boost::unsafe_any_cast<void *>(&const_cast<value_t&>(*this).as_any_pointer_lval());
break;
case SEQUENCE: {
diff --git a/value.h b/value.h
index 8bb9c8d7..e5418995 100644
--- a/value.h
+++ b/value.h
@@ -610,7 +610,7 @@ public:
return *(boost::any *) storage->data;
}
template <typename T>
- T *& as_pointer_lval() {
+ T * as_pointer_lval() {
assert(is_pointer());
_dup();
return any_cast<T *>(*(boost::any *) storage->data);
@@ -652,7 +652,7 @@ public:
*/
bool to_boolean() const;
long to_long() const;
- datetime_t to_datetime() const;
+ datetime_t to_datetime() const;
amount_t to_amount() const;
balance_t to_balance() const;
balance_pair_t to_balance_pair() const;