Commit ea411f84 by Ian Lance Taylor

compiler: Permit "for range x" clauses.

Fixes Issue 8370.

From-SVN: r216051
parent 3369b919
......@@ -3836,6 +3836,12 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
this->unget_token(Token::make_identifier_token(identifier, is_exported,
location));
}
else if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
{
Typed_identifier_list til;
this->range_clause_decl(&til, p_range_clause);
return NULL;
}
Expression* exp = this->expression(PRECEDENCE_NORMAL, true,
may_be_composite_lit,
......@@ -5278,7 +5284,7 @@ Parse::for_clause(Expression** cond, Block** post)
}
}
// RangeClause = IdentifierList ( "=" | ":=" ) "range" Expression .
// RangeClause = [ IdentifierList ( "=" | ":=" ) ] "range" Expression .
// This is the := version. It is called with a list of identifiers.
......@@ -5291,7 +5297,6 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
p_range_clause->found = true;
go_assert(til->size() >= 1);
if (til->size() > 2)
error_at(this->location(), "too many variables for range clause");
......@@ -5300,6 +5305,9 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
NULL);
p_range_clause->range = expr;
if (til->empty())
return;
bool any_new = false;
const Typed_identifier* pti = &til->front();
......@@ -5347,6 +5355,9 @@ Parse::range_clause_expr(const Expression_list* vals,
p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false,
NULL, NULL);
if (vals->empty())
return;
p_range_clause->index = vals->front();
if (vals->size() == 1)
p_range_clause->value = NULL;
......
......@@ -5305,8 +5305,12 @@ Statement::make_for_statement(Block* init, Expression* cond, Block* post,
int
For_range_statement::do_traverse(Traverse* traverse)
{
if (this->traverse_expression(traverse, &this->index_var_) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
if (this->index_var_ != NULL)
{
if (this->traverse_expression(traverse, &this->index_var_)
== TRAVERSE_EXIT)
return TRAVERSE_EXIT;
}
if (this->value_var_ != NULL)
{
if (this->traverse_expression(traverse, &this->value_var_)
......@@ -5434,25 +5438,27 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
if (iter_init != NULL)
body->add_statement(Statement::make_block_statement(iter_init, loc));
Statement* assign;
Expression* index_ref = Expression::make_temporary_reference(index_temp, loc);
if (this->value_var_ == NULL)
if (this->index_var_ != NULL)
{
assign = Statement::make_assignment(this->index_var_, index_ref, loc);
}
else
{
Expression_list* lhs = new Expression_list();
lhs->push_back(this->index_var_);
lhs->push_back(this->value_var_);
Statement* assign;
Expression* index_ref =
Expression::make_temporary_reference(index_temp, loc);
if (this->value_var_ == NULL)
assign = Statement::make_assignment(this->index_var_, index_ref, loc);
else
{
Expression_list* lhs = new Expression_list();
lhs->push_back(this->index_var_);
lhs->push_back(this->value_var_);
Expression_list* rhs = new Expression_list();
rhs->push_back(index_ref);
rhs->push_back(Expression::make_temporary_reference(value_temp, loc));
Expression_list* rhs = new Expression_list();
rhs->push_back(index_ref);
rhs->push_back(Expression::make_temporary_reference(value_temp, loc));
assign = Statement::make_tuple_assignment(lhs, rhs, loc);
assign = Statement::make_tuple_assignment(lhs, rhs, loc);
}
body->add_statement(assign);
}
body->add_statement(assign);
body->add_statement(Statement::make_block_statement(this->statements_, loc));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment