Better semantics for the ?: ternary operator.
This commit is contained in:
parent
aebfc92a4d
commit
7594639581
2 changed files with 41 additions and 6 deletions
33
src/op.cc
33
src/op.cc
|
|
@ -201,6 +201,20 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context)
|
||||||
result = right()->calc(scope, context);
|
result = right()->calc(scope, context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case O_QUERY:
|
||||||
|
assert(right());
|
||||||
|
assert(right()->kind == O_COLON);
|
||||||
|
|
||||||
|
if (value_t temp = left()->calc(scope, context))
|
||||||
|
result = right()->left()->calc(scope, context);
|
||||||
|
else
|
||||||
|
result = right()->right()->calc(scope, context);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case O_COLON:
|
||||||
|
assert(! "We should never calculate an O_COLON operator");
|
||||||
|
break;
|
||||||
|
|
||||||
case O_COMMA: {
|
case O_COMMA: {
|
||||||
value_t temp(left()->calc(scope, context));
|
value_t temp(left()->calc(scope, context));
|
||||||
|
|
||||||
|
|
@ -379,6 +393,22 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
|
||||||
out << ")";
|
out << ")";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case O_QUERY:
|
||||||
|
if (left() && left()->print(out, context))
|
||||||
|
found = true;
|
||||||
|
out << " ? ";
|
||||||
|
if (has_right() && right()->print(out, context))
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case O_COLON:
|
||||||
|
if (left() && left()->print(out, context))
|
||||||
|
found = true;
|
||||||
|
out << " : ";
|
||||||
|
if (has_right() && right()->print(out, context))
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case O_COMMA:
|
case O_COMMA:
|
||||||
if (left() && left()->print(out, context))
|
if (left() && left()->print(out, context))
|
||||||
found = true;
|
found = true;
|
||||||
|
|
@ -476,6 +506,9 @@ void expr_t::op_t::dump(std::ostream& out, const int depth) const
|
||||||
case O_AND: out << "O_AND"; break;
|
case O_AND: out << "O_AND"; break;
|
||||||
case O_OR: out << "O_OR"; break;
|
case O_OR: out << "O_OR"; break;
|
||||||
|
|
||||||
|
case O_QUERY: out << "O_QUERY"; break;
|
||||||
|
case O_COLON: out << "O_COLON"; break;
|
||||||
|
|
||||||
case O_COMMA: out << "O_COMMA"; break;
|
case O_COMMA: out << "O_COMMA"; break;
|
||||||
|
|
||||||
case LAST:
|
case LAST:
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in,
|
||||||
|
|
||||||
if (tok.kind == token_t::QUERY) {
|
if (tok.kind == token_t::QUERY) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_AND);
|
node = new op_t(op_t::O_QUERY);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_or_expr(in, tflags));
|
node->set_right(parse_or_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
|
|
@ -351,13 +351,15 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in,
|
||||||
if (next_tok.kind != token_t::COLON)
|
if (next_tok.kind != token_t::COLON)
|
||||||
next_tok.expected(':');
|
next_tok.expected(':');
|
||||||
|
|
||||||
prev = node;
|
prev = node->right();
|
||||||
node = new op_t(op_t::O_OR);
|
ptr_op_t subnode = new op_t(op_t::O_COLON);
|
||||||
node->set_left(prev);
|
subnode->set_left(prev);
|
||||||
node->set_right(parse_or_expr(in, tflags));
|
subnode->set_right(parse_or_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! subnode->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
|
|
||||||
|
node->set_right(subnode);
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue