Renamed O_COMMA to O_CONS, and changed semantics

In the old scheme, nested values would simply flatten and concatenate,
so that '((1, 2), 3) = (1, 2, 3)'.  Now sublists are preserved, so that
sequences may be passed as arguments to functions.
This commit is contained in:
John Wiegley 2009-02-23 15:04:07 -04:00
parent 9a44b8a547
commit e919f53c99
4 changed files with 52 additions and 30 deletions

View file

@ -39,7 +39,7 @@ namespace {
void push_sort_value(std::list<sort_value_t>& sort_values,
expr_t::ptr_op_t node, T * scope)
{
if (node->kind == expr_t::op_t::O_COMMA) {
if (node->kind == expr_t::op_t::O_CONS) {
push_sort_value(sort_values, node->left(), scope);
push_sort_value(sort_values, node->right(), scope);
}

View file

@ -137,7 +137,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
sym;
sym = sym->has_right() ? sym->right() : NULL) {
ptr_op_t varname = sym;
if (sym->kind == O_COMMA)
if (sym->kind == O_CONS)
varname = sym->left();
if (! varname->is_ident())
@ -269,25 +269,30 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus)
assert(! "We should never calculate an O_COLON operator");
break;
case O_COMMA: {
value_t temp(left()->calc(scope, locus));
case O_CONS:
result = left()->calc(scope, locus);
DEBUG("op.cons", "car = " << result);
ptr_op_t next = right();
while (next) {
ptr_op_t value_op;
if (next->kind == O_COMMA) {
value_op = next->left();
next = next->right();
} else {
value_op = next;
next = NULL;
if (has_right()) {
value_t temp;
temp.push_back(result);
ptr_op_t next = right();
while (next) {
ptr_op_t value_op;
if (next->kind == O_CONS) {
value_op = next->left();
next = next->right();
} else {
value_op = next;
next = NULL;
}
temp.push_back(value_op->calc(scope, locus));
DEBUG("op.cons", "temp now = " << temp);
}
temp.push_back(value_op->calc(scope, locus));
result = temp;
}
result = temp;
break;
}
case LAST:
default:
@ -463,12 +468,19 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
found = true;
break;
case O_COMMA:
if (left() && left()->print(out, context))
found = true;
out << ", ";
if (has_right() && right()->print(out, context))
case O_CONS:
if (has_right()) {
out << "(";
if (left() && left()->print(out, context))
found = true;
out << ", ";
if (has_right() && right()->print(out, context))
found = true;
out << ")";
}
else if (left() && left()->print(out, context)) {
found = true;
}
break;
case O_DEFINE:
@ -490,10 +502,19 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
case O_CALL:
if (left() && left()->print(out, context))
found = true;
out << "(";
if (has_right() && right()->print(out, context))
found = true;
out << ")";
if (has_right()) {
if (right()->kind == O_CONS) {
if (right()->print(out, context))
found = true;
} else {
out << "(";
if (has_right() && right()->print(out, context))
found = true;
out << ")";
}
} else {
out << "()";
}
break;
case O_MATCH:
@ -572,7 +593,7 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const
case O_QUERY: out << "O_QUERY"; break;
case O_COLON: out << "O_COLON"; break;
case O_COMMA: out << "O_COMMA"; break;
case O_CONS: out << "O_CONS"; break;
case LAST:
default:

View file

@ -108,7 +108,7 @@ public:
O_QUERY,
O_COLON,
O_COMMA,
O_CONS,
O_DEFINE,
O_LOOKUP,

View file

@ -69,7 +69,8 @@ expr_t::parser_t::parse_value_term(std::istream& in,
}
case token_t::LPAREN:
node = parse_value_expr(in, tflags.plus_flags(PARSE_PARTIAL).minus_flags(PARSE_SINGLE));
node = parse_value_expr(in, tflags.plus_flags(PARSE_PARTIAL)
.minus_flags(PARSE_SINGLE));
tok = next_token(in, tflags);
if (tok.kind != token_t::RPAREN)
tok.expected(')');
@ -399,7 +400,7 @@ expr_t::parser_t::parse_value_expr(std::istream& in,
if (tok.kind == token_t::COMMA) {
ptr_op_t prev(node);
node = new op_t(op_t::O_COMMA);
node = new op_t(op_t::O_CONS);
node->set_left(prev);
node->set_right(parse_value_expr(in, tflags));
if (! node->right())