summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-03-03 16:05:04 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-03-03 16:05:04 -0400
commite2c30cf6e4e8c0d38f129e3e209954bf1bfbe602 (patch)
tree118ab3ef92756dd208ece3c35d4b8ba4d6d47271
parent098e3b0043c275cfe195be1c592baf5716ab73e5 (diff)
downloadfork-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.cc46
-rw-r--r--src/op.h1
-rw-r--r--src/parser.cc7
-rw-r--r--src/token.cc5
-rw-r--r--src/token.h1
5 files changed, 58 insertions, 2 deletions
diff --git a/src/op.cc b/src/op.cc
index 902d370a..d44fa2ab 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -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:
diff --git a/src/op.h b/src/op.h
index ea787d8c..2960c297 100644
--- a/src/op.h
+++ b/src/op.h
@@ -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