diff options
author | John Wiegley <johnw@newartisans.com> | 2009-03-03 16:05:04 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-03-03 16:05:04 -0400 |
commit | e2c30cf6e4e8c0d38f129e3e209954bf1bfbe602 (patch) | |
tree | 118ab3ef92756dd208ece3c35d4b8ba4d6d47271 | |
parent | 098e3b0043c275cfe195be1c592baf5716ab73e5 (diff) | |
download | fork-ledger-e2c30cf6e4e8c0d38f129e3e209954bf1bfbe602.tar.gz fork-ledger-e2c30cf6e4e8c0d38f129e3e209954bf1bfbe602.tar.bz2 fork-ledger-e2c30cf6e4e8c0d38f129e3e209954bf1bfbe602.zip |
Added ; as a sequencing operator in valexprs
-rw-r--r-- | src/op.cc | 46 | ||||
-rw-r--r-- | src/op.h | 1 | ||||
-rw-r--r-- | src/parser.cc | 7 | ||||
-rw-r--r-- | src/token.cc | 5 | ||||
-rw-r--r-- | src/token.h | 1 |
5 files changed, 58 insertions, 2 deletions
@@ -294,6 +294,25 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus) } break; + case O_SEQ: { + left()->calc(scope, locus); + assert(has_right()); + + ptr_op_t next = right(); + while (next) { + ptr_op_t value_op; + if (next->kind == O_SEQ) { + value_op = next->left(); + next = next->right(); + } else { + value_op = next; + next = NULL; + } + result = value_op->calc(scope, locus); + } + break; + } + case LAST: default: assert(false); @@ -331,6 +350,26 @@ namespace { } return found; } + + bool print_seq(std::ostream& out, const expr_t::const_ptr_op_t op, + const expr_t::op_t::context_t& context) + { + bool found = false; + + assert(op->left()); + if (op->left()->print(out, context)) + found = true; + + assert(op->has_right()); + out << "; "; + + if (op->right()->kind == expr_t::op_t::O_CONS) + found = print_cons(out, op->right(), context); + else if (op->right()->print(out, context)) + found = true; + + return found; + } } bool expr_t::op_t::print(std::ostream& out, const context_t& context) const @@ -495,6 +534,12 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const out << ")"; break; + case O_SEQ: + out << "("; + found = print_seq(out, this, context); + out << ")"; + break; + case O_DEFINE: if (left() && left()->print(out, context)) found = true; @@ -606,6 +651,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const case O_COLON: out << "O_COLON"; break; case O_CONS: out << "O_CONS"; break; + case O_SEQ: out << "O_SEQ"; break; case LAST: default: @@ -109,6 +109,7 @@ public: O_COLON, O_CONS, + O_SEQ, O_DEFINE, O_LOOKUP, diff --git a/src/parser.cc b/src/parser.cc index 15cd4fc6..4b0c1b54 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -441,14 +441,17 @@ expr_t::parser_t::parse_value_expr(std::istream& in, if (node && ! tflags.has_flags(PARSE_SINGLE)) { token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT)); - if (tok.kind == token_t::COMMA) { + if (tok.kind == token_t::COMMA || tok.kind == token_t::SEMI) { + bool comma_op = tok.kind == token_t::COMMA; + ptr_op_t prev(node); - node = new op_t(op_t::O_CONS); + node = new op_t(comma_op ? op_t::O_CONS : op_t::O_SEQ); node->set_left(prev); node->set_right(parse_value_expr(in, tflags)); if (! node->right()) throw_(parse_error, _("%1 operator not followed by argument") << tok.symbol); + tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT)); } diff --git a/src/token.cc b/src/token.cc index 11fda7d7..deaa777e 100644 --- a/src/token.cc +++ b/src/token.cc @@ -368,6 +368,11 @@ void expr_t::token_t::next(std::istream& in, const uint_least8_t pflags) kind = COMMA; break; + case ';': + in.get(c); + kind = SEMI; + break; + default: { istream_pos_type pos = in.tellg(); diff --git a/src/token.h b/src/token.h index 7b5eec11..a9b75dd4 100644 --- a/src/token.h +++ b/src/token.h @@ -96,6 +96,7 @@ struct expr_t::token_t : public noncopyable DOT, // . COMMA, // , + SEMI, // ; TOK_EOF, UNKNOWN |