Added the var_t helper class, which can be seen in the beginning

implementation of register_command in main.cc.
This commit is contained in:
John Wiegley 2008-07-21 20:41:42 -04:00
parent 8601a2a8bf
commit aa4f0d4364
7 changed files with 86 additions and 99 deletions

23
main.cc
View file

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

View file

@ -215,32 +215,12 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
process_option(o.get<0>()->as_function(), scope, value);
}
}
}
}
} // namespace ledger
#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";
}
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

View file

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

View file

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

View file

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

View file

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

View file

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