Changed the way that bare masks are parsed. There is still some coupling

here, albeit just through flag values.  It needs to be changed, though.
This commit is contained in:
John Wiegley 2008-08-02 17:07:04 -04:00
parent e52a6a9bd8
commit 7b3c8c03c5
5 changed files with 50 additions and 55 deletions

12
mask.h
View file

@ -36,17 +36,25 @@
namespace ledger {
class mask_t
class mask_t : public supports_flags<>
{
mask_t();
public:
#define MASK_SHORT_ACCOUNT 0x01
#define MASK_CODE 0x02
#define MASK_COMMODITY 0x04
#define MASK_PAYEE 0x08
#define MASK_NOTE 0x10
#define MASK_ACCOUNT 0x20
bool exclude;
boost::regex expr;
explicit mask_t(const string& pattern);
mask_t(const mask_t& m) : exclude(m.exclude), expr(m.expr) {
mask_t(const mask_t& m)
: supports_flags<>(), exclude(m.exclude), expr(m.expr) {
TRACE_CTOR(mask_t, "copy");
}
~mask_t() throw() {

32
op.cc
View file

@ -647,6 +647,34 @@ expr_t::ptr_op_t expr_t::op_t::compile(scope_t& scope)
}
return this;
case MASK: {
ptr_op_t match = new op_t(op_t::O_MATCH);
match->set_right(this);
// jww (2008-08-02): Coupling!
ptr_op_t ident = new op_t(op_t::IDENT);
switch (as_mask().flags()) {
case MASK_SHORT_ACCOUNT:
ident->set_ident("account_base");
break;
case MASK_CODE:
ident->set_ident("code");
break;
case MASK_PAYEE:
ident->set_ident("payee");
break;
case MASK_NOTE:
ident->set_ident("note");
break;
case MASK_ACCOUNT:
ident->set_ident("account");
break;
}
match->set_left(ident->compile(scope));
return match;
}
default:
break;
}
@ -720,8 +748,8 @@ value_t expr_t::op_t::calc(scope_t& scope)
}
case O_MATCH:
assert(left()->is_mask());
return left()->as_mask().match(right()->calc(scope).to_string());
assert(right()->is_mask());
return right()->as_mask().match(left()->calc(scope).to_string());
case INDEX: {
const call_scope_t& args(downcast<const call_scope_t>(scope));

View file

@ -47,42 +47,11 @@ expr_t::parser_t::parse_value_term(std::istream& in,
node->set_value(tok.value);
break;
case token_t::MASK: {
// A /mask/ is just a shorthand for calling match().
node = new op_t(op_t::O_MATCH);
ptr_op_t mask = new op_t(op_t::MASK);
mask->set_mask(tok.value.as_string());
ptr_op_t ident = new op_t(op_t::IDENT);
node->set_left(mask);
node->set_right(ident);
switch (tok.flags()) {
case TOKEN_SHORT_ACCOUNT_MASK:
ident->set_ident("account_base");
break;
case TOKEN_CODE_MASK:
ident->set_ident("code");
break;
#if 0
case TOKEN_COMMODITY_MASK:
ident->set_ident("commodity");
break;
#endif
case TOKEN_PAYEE_MASK:
ident->set_ident("payee");
break;
case TOKEN_NOTE_MASK:
ident->set_ident("note");
break;
case TOKEN_ACCOUNT_MASK:
ident->set_ident("account");
break;
}
case token_t::MASK:
node = new op_t(op_t::MASK);
node->set_mask(tok.value.as_string());
node->as_mask_lval().add_flags(tok.flags());
break;
}
case token_t::IDENT: {
#if 0
@ -296,9 +265,6 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
break;
case token_t::MATCH:
kind = op_t::O_MATCH;
assert(node->kind == op_t::O_MATCH);
node = node->left();
assert(node->kind == op_t::MASK);
break;
case token_t::LESS:
kind = op_t::O_LT;

View file

@ -285,17 +285,17 @@ void expr_t::token_t::next(std::istream& in, const unsigned int pflags)
length++;
if (short_account_mask)
set_flags(TOKEN_SHORT_ACCOUNT_MASK);
set_flags(MASK_SHORT_ACCOUNT);
else if (code_mask)
set_flags(TOKEN_CODE_MASK);
set_flags(MASK_CODE);
else if (commodity_mask)
set_flags(TOKEN_COMMODITY_MASK);
set_flags(MASK_COMMODITY);
else if (payee_mask)
set_flags(TOKEN_PAYEE_MASK);
set_flags(MASK_PAYEE);
else if (note_mask)
set_flags(TOKEN_NOTE_MASK);
set_flags(MASK_NOTE);
else
set_flags(TOKEN_ACCOUNT_MASK);
set_flags(MASK_ACCOUNT);
kind = MASK;
value.set_string(buf);

View file

@ -38,13 +38,6 @@ namespace ledger {
struct expr_t::token_t : public noncopyable, public supports_flags<>
{
#define TOKEN_SHORT_ACCOUNT_MASK 0x01
#define TOKEN_CODE_MASK 0x02
#define TOKEN_COMMODITY_MASK 0x04
#define TOKEN_PAYEE_MASK 0x08
#define TOKEN_NOTE_MASK 0x10
#define TOKEN_ACCOUNT_MASK 0x20
enum kind_t {
VALUE, // any kind of literal value
IDENT, // [A-Za-z_][-A-Za-z0-9_:]*