Added ; as a sequencing operator in valexprs

This commit is contained in:
John Wiegley 2009-03-03 16:05:04 -04:00
parent 098e3b0043
commit e2c30cf6e4
5 changed files with 58 additions and 2 deletions

View file

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

View file

@ -109,6 +109,7 @@ public:
O_COLON,
O_CONS,
O_SEQ,
O_DEFINE,
O_LOOKUP,

View file

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

View file

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

View file

@ -96,6 +96,7 @@ struct expr_t::token_t : public noncopyable
DOT, // .
COMMA, // ,
SEMI, // ;
TOK_EOF,
UNKNOWN