diff options
-rw-r--r-- | src/op.cc | 33 | ||||
-rw-r--r-- | src/parser.cc | 14 |
2 files changed, 41 insertions, 6 deletions
@@ -201,6 +201,20 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * context) result = right()->calc(scope, context); 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: { 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 << ")"; 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: if (left() && left()->print(out, context)) 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_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 LAST: diff --git a/src/parser.cc b/src/parser.cc index 0819e3d8..eeff59f0 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -340,7 +340,7 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in, if (tok.kind == token_t::QUERY) { 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_right(parse_or_expr(in, tflags)); if (! node->right()) @@ -351,13 +351,15 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in, if (next_tok.kind != token_t::COLON) next_tok.expected(':'); - prev = node; - node = new op_t(op_t::O_OR); - node->set_left(prev); - node->set_right(parse_or_expr(in, tflags)); - if (! node->right()) + prev = node->right(); + ptr_op_t subnode = new op_t(op_t::O_COLON); + subnode->set_left(prev); + subnode->set_right(parse_or_expr(in, tflags)); + if (! subnode->right()) throw_(parse_error, tok.symbol << " operator not followed by argument"); + + node->set_right(subnode); } else { push_token(tok); } |