mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:20:13 +01:00
For loop for arrays (#1753)
Co-authored-by: m new <michael.burzan@outlook.de> Co-authored-by: Geoff Romer <gromer@google.com> Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
m new
Geoff Romer
Richard Smith
parent
2c921efe36
commit
f754373786
@@ -265,6 +265,12 @@ message WhileStatement {
|
||||
optional BlockStatement body = 2;
|
||||
}
|
||||
|
||||
message ForStatement {
|
||||
optional BindingPattern var_decl = 1;
|
||||
optional Expression target = 2;
|
||||
optional BlockStatement body = 3;
|
||||
}
|
||||
|
||||
message MatchClause {
|
||||
optional Pattern pattern = 1;
|
||||
optional Statement statement = 2;
|
||||
@@ -306,6 +312,7 @@ message Statement {
|
||||
AwaitStatement await_statement = 12;
|
||||
BreakStatement break_statement = 13;
|
||||
ContinueStatement continue_statement = 14;
|
||||
ForStatement for_statement = 15;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -586,6 +586,16 @@ static auto StatementToCarbon(const Fuzzing::Statement& statement,
|
||||
BlockStatementToCarbon(while_statement.body(), out);
|
||||
break;
|
||||
}
|
||||
case Fuzzing::Statement::kForStatement: {
|
||||
const auto& for_statement = statement.for_statement();
|
||||
out << "for (";
|
||||
BindingPatternToCarbon(for_statement.var_decl(), out);
|
||||
out << " in ";
|
||||
ExpressionToCarbon(for_statement.target(), out);
|
||||
out << ") ";
|
||||
BlockStatementToCarbon(for_statement.body(), out);
|
||||
break;
|
||||
}
|
||||
|
||||
case Fuzzing::Statement::kMatch: {
|
||||
const auto& match = statement.match();
|
||||
|
||||
@@ -40,6 +40,7 @@ abstract class Statement : AstNode;
|
||||
class Continuation : Statement;
|
||||
class Run : Statement;
|
||||
class Await : Statement;
|
||||
class For : Statement;
|
||||
abstract class Expression : AstNode;
|
||||
class BoolTypeLiteral : Expression;
|
||||
class BoolLiteral : Expression;
|
||||
|
||||
@@ -42,6 +42,13 @@ void Statement::PrintDepth(int depth, llvm::raw_ostream& out) const {
|
||||
while_stmt.body().PrintDepth(depth - 1, out);
|
||||
break;
|
||||
}
|
||||
case StatementKind::For: {
|
||||
const auto& for_stmt = cast<For>(*this);
|
||||
out << "for (" << for_stmt.variable_declaration() << " in "
|
||||
<< for_stmt.loop_target() << ")\n";
|
||||
for_stmt.body().PrintDepth(depth - 1, out);
|
||||
break;
|
||||
}
|
||||
case StatementKind::Break:
|
||||
out << "break;";
|
||||
break;
|
||||
|
||||
@@ -298,6 +298,38 @@ class While : public Statement {
|
||||
Nonnull<Block*> body_;
|
||||
};
|
||||
|
||||
class For : public Statement {
|
||||
public:
|
||||
For(SourceLocation source_loc, Nonnull<BindingPattern*> variable_declaration,
|
||||
Nonnull<Expression*> loop_target, Nonnull<Block*> body)
|
||||
: Statement(AstNodeKind::For, source_loc),
|
||||
variable_declaration_(variable_declaration),
|
||||
loop_target_(loop_target),
|
||||
body_(body) {}
|
||||
|
||||
static auto classof(const AstNode* node) -> bool {
|
||||
return InheritsFromFor(node->kind());
|
||||
}
|
||||
|
||||
auto variable_declaration() const -> const BindingPattern& {
|
||||
return *variable_declaration_;
|
||||
}
|
||||
auto variable_declaration() -> BindingPattern& {
|
||||
return *variable_declaration_;
|
||||
}
|
||||
|
||||
auto loop_target() const -> const Expression& { return *loop_target_; }
|
||||
auto loop_target() -> Expression& { return *loop_target_; }
|
||||
|
||||
auto body() const -> const Block& { return *body_; }
|
||||
auto body() -> Block& { return *body_; }
|
||||
|
||||
private:
|
||||
Nonnull<BindingPattern*> variable_declaration_;
|
||||
Nonnull<Expression*> loop_target_;
|
||||
Nonnull<Block*> body_;
|
||||
};
|
||||
|
||||
class Break : public Statement {
|
||||
public:
|
||||
explicit Break(SourceLocation source_loc)
|
||||
|
||||
@@ -521,6 +521,16 @@ static auto StatementToProto(const Statement& statement) -> Fuzzing::Statement {
|
||||
// Initializes with the default value; there's nothing to set.
|
||||
statement_proto.mutable_continue_statement();
|
||||
break;
|
||||
|
||||
case StatementKind::For: {
|
||||
const auto& for_stmt = cast<For>(statement);
|
||||
auto* for_proto = statement_proto.mutable_for_statement();
|
||||
*for_proto->mutable_var_decl() =
|
||||
BindingPatternToProto(for_stmt.variable_declaration());
|
||||
*for_proto->mutable_target() = ExpressionToProto(for_stmt.loop_target());
|
||||
*for_proto->mutable_body() = BlockStatementToProto(for_stmt.body());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return statement_proto;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,10 @@ class Action {
|
||||
auto results() const -> const std::vector<Nonnull<const Value*>>& {
|
||||
return results_;
|
||||
}
|
||||
|
||||
void ReplaceResult(std::size_t index, Nonnull<const Value*> value) {
|
||||
CARBON_CHECK(index < results_.size());
|
||||
results_[index] = value;
|
||||
}
|
||||
// Appends `result` to `results`.
|
||||
void AddResult(Nonnull<const Value*> result) { results_.push_back(result); }
|
||||
|
||||
|
||||
@@ -1505,7 +1505,78 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
}
|
||||
}
|
||||
}
|
||||
case StatementKind::For: {
|
||||
constexpr int TargetVarPosInResult = 0;
|
||||
constexpr int CurrentIndexPosInResult = 1;
|
||||
constexpr int EndIndexPosInResult = 2;
|
||||
constexpr int LoopVarPosInResult = 3;
|
||||
if (act.pos() == 0) {
|
||||
return todo_.Spawn(
|
||||
std::make_unique<ExpressionAction>(&cast<For>(stmt).loop_target()));
|
||||
}
|
||||
if (act.pos() == 1) {
|
||||
Nonnull<const TupleValue*> source_array =
|
||||
cast<const TupleValue>(act.results()[TargetVarPosInResult]);
|
||||
|
||||
auto end_index = static_cast<int>(source_array->elements().size());
|
||||
if (end_index == 0) {
|
||||
return todo_.FinishAction();
|
||||
}
|
||||
act.AddResult(arena_->New<IntValue>(0));
|
||||
act.AddResult(arena_->New<IntValue>(end_index));
|
||||
return todo_.Spawn(std::make_unique<PatternAction>(
|
||||
&cast<For>(stmt).variable_declaration()));
|
||||
}
|
||||
if (act.pos() == 2) {
|
||||
Nonnull<const BindingPlaceholderValue*> loop_var =
|
||||
cast<const BindingPlaceholderValue>(
|
||||
act.results()[LoopVarPosInResult]);
|
||||
Nonnull<const TupleValue*> source_array =
|
||||
cast<const TupleValue>(act.results()[TargetVarPosInResult]);
|
||||
|
||||
auto start_index =
|
||||
cast<IntValue>(act.results()[CurrentIndexPosInResult])->value();
|
||||
todo_.Initialize(*(loop_var->value_node()),
|
||||
source_array->elements()[start_index]);
|
||||
act.ReplaceResult(CurrentIndexPosInResult,
|
||||
arena_->New<IntValue>(start_index + 1));
|
||||
return todo_.Spawn(
|
||||
std::make_unique<StatementAction>(&cast<For>(stmt).body()));
|
||||
}
|
||||
if (act.pos() >= 3) {
|
||||
auto current_index =
|
||||
cast<IntValue>(act.results()[CurrentIndexPosInResult])->value();
|
||||
auto end_index =
|
||||
cast<IntValue>(act.results()[EndIndexPosInResult])->value();
|
||||
|
||||
if (current_index < end_index) {
|
||||
Nonnull<const TupleValue*> source_array =
|
||||
cast<const TupleValue>(act.results()[TargetVarPosInResult]);
|
||||
Nonnull<const BindingPlaceholderValue*> loop_var =
|
||||
cast<const BindingPlaceholderValue>(
|
||||
act.results()[LoopVarPosInResult]);
|
||||
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> assigned_array_element,
|
||||
todo_.ValueOfNode(*(loop_var->value_node()), stmt.source_loc()));
|
||||
|
||||
auto lvalue = cast<LValue>(assigned_array_element);
|
||||
CARBON_RETURN_IF_ERROR(heap_.Write(
|
||||
lvalue->address(), source_array->elements()[current_index],
|
||||
stmt.source_loc()));
|
||||
|
||||
act.ReplaceResult(CurrentIndexPosInResult,
|
||||
arena_->New<IntValue>(current_index + 1));
|
||||
return todo_.Spawn(
|
||||
std::make_unique<StatementAction>(&cast<For>(stmt).body()));
|
||||
}
|
||||
}
|
||||
return todo_.FinishAction();
|
||||
}
|
||||
case StatementKind::While:
|
||||
// TODO: Rewrite While to use ReplaceResult to store condition result.
|
||||
// This will remove the inconsistency between the while and for
|
||||
// loops.
|
||||
if (act.pos() % 2 == 0) {
|
||||
// { { (while (e) s) :: C, E, F} :: S, H}
|
||||
// -> { { e :: (while ([]) s) :: C, E, F} :: S, H}
|
||||
|
||||
@@ -106,6 +106,11 @@ static auto ResolveControlFlow(Nonnull<Statement*> statement,
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::For: {
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(&cast<For>(*statement).body(),
|
||||
statement, function));
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::While:
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(&cast<While>(*statement).body(),
|
||||
statement, function));
|
||||
|
||||
@@ -413,6 +413,18 @@ static auto ResolveNames(Statement& statement, StaticScope& enclosing_scope)
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(while_stmt.body(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case StatementKind::For: {
|
||||
StaticScope statement_scope;
|
||||
statement_scope.AddParent(&enclosing_scope);
|
||||
auto& for_stmt = cast<For>(statement);
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(for_stmt.loop_target(), statement_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(for_stmt.variable_declaration(), statement_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(for_stmt.body(), statement_scope));
|
||||
|
||||
break;
|
||||
}
|
||||
case StatementKind::Match: {
|
||||
auto& match = cast<Match>(statement);
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(match.expression(), enclosing_scope));
|
||||
|
||||
@@ -196,6 +196,7 @@ static auto ResolveUnformed(
|
||||
case StatementKind::Continuation:
|
||||
case StatementKind::Run:
|
||||
case StatementKind::Await:
|
||||
case StatementKind::For:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2965,6 +2965,29 @@ auto TypeChecker::TypeCheckStmt(Nonnull<Statement*> s,
|
||||
CARBON_RETURN_IF_ERROR(TypeCheckStmt(&while_stmt.body(), impl_scope));
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::For: {
|
||||
auto& for_stmt = cast<For>(*s);
|
||||
ImplScope inner_impl_scope;
|
||||
inner_impl_scope.AddParent(&impl_scope);
|
||||
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
TypeCheckExp(&for_stmt.loop_target(), inner_impl_scope));
|
||||
|
||||
const Value& rhs = for_stmt.loop_target().static_type();
|
||||
if (rhs.kind() == Value::Kind::StaticArrayType) {
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
TypeCheckPattern(&for_stmt.variable_declaration(),
|
||||
&cast<StaticArrayType>(rhs).element_type(),
|
||||
inner_impl_scope, ValueCategory::Var));
|
||||
|
||||
} else {
|
||||
return CompilationError(for_stmt.source_loc())
|
||||
<< "expected array type after in, found value of type " << rhs;
|
||||
}
|
||||
|
||||
CARBON_RETURN_IF_ERROR(TypeCheckStmt(&for_stmt.body(), inner_impl_scope));
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::Break:
|
||||
case StatementKind::Continue:
|
||||
return Success();
|
||||
@@ -3163,6 +3186,7 @@ auto TypeChecker::ExpectReturnOnAllPaths(
|
||||
case StatementKind::Assign:
|
||||
case StatementKind::ExpressionStatement:
|
||||
case StatementKind::While:
|
||||
case StatementKind::For:
|
||||
case StatementKind::Break:
|
||||
case StatementKind::Continue:
|
||||
case StatementKind::VariableDefinition:
|
||||
|
||||
@@ -64,6 +64,7 @@ EXTERNAL "external"
|
||||
FALSE "false"
|
||||
FN "fn"
|
||||
FN_TYPE "__Fn"
|
||||
FOR "for"
|
||||
FORALL "forall"
|
||||
GREATER ">"
|
||||
GREATER_EQUAL ">="
|
||||
@@ -71,6 +72,7 @@ GREATER_GREATER ">>"
|
||||
IF "if"
|
||||
IMPL "impl"
|
||||
IMPORT "import"
|
||||
IN "in"
|
||||
INTERFACE "interface"
|
||||
IS "is"
|
||||
LEFT_CURLY_BRACE "{"
|
||||
@@ -165,6 +167,7 @@ operand_start [(A-Za-z0-9_\"]
|
||||
{FN_TYPE} { return CARBON_SIMPLE_TOKEN(FN_TYPE); }
|
||||
{FN} { return CARBON_SIMPLE_TOKEN(FN); }
|
||||
{FORALL} { return CARBON_SIMPLE_TOKEN(FORALL); }
|
||||
{FOR} { return CARBON_SIMPLE_TOKEN(FOR); }
|
||||
{GREATER_EQUAL} { return CARBON_SIMPLE_TOKEN(GREATER_EQUAL); }
|
||||
{GREATER_GREATER} { return CARBON_SIMPLE_TOKEN(GREATER_GREATER); }
|
||||
{GREATER} { return CARBON_SIMPLE_TOKEN(GREATER); }
|
||||
@@ -172,6 +175,7 @@ operand_start [(A-Za-z0-9_\"]
|
||||
{IMPL} { return CARBON_SIMPLE_TOKEN(IMPL); }
|
||||
{IMPORT} { return CARBON_SIMPLE_TOKEN(IMPORT); }
|
||||
{INTERFACE} { return CARBON_SIMPLE_TOKEN(INTERFACE); }
|
||||
{IN} { return CARBON_SIMPLE_TOKEN(IN); }
|
||||
{IS} { return CARBON_SIMPLE_TOKEN(IS); }
|
||||
{LEFT_CURLY_BRACE} { return CARBON_SIMPLE_TOKEN(LEFT_CURLY_BRACE); }
|
||||
{LEFT_PARENTHESIS} { return CARBON_SIMPLE_TOKEN(LEFT_PARENTHESIS); }
|
||||
|
||||
@@ -228,6 +228,7 @@
|
||||
FALSE
|
||||
FN
|
||||
FN_TYPE
|
||||
FOR
|
||||
FORALL
|
||||
GREATER
|
||||
GREATER_EQUAL
|
||||
@@ -235,6 +236,7 @@
|
||||
IF
|
||||
IMPL
|
||||
IMPORT
|
||||
IN
|
||||
INTERFACE
|
||||
IS
|
||||
LEFT_CURLY_BRACE
|
||||
@@ -934,6 +936,8 @@ statement:
|
||||
{ $$ = arena->New<Run>(context.source_loc(), $2); }
|
||||
| AWAIT SEMICOLON
|
||||
{ $$ = arena->New<Await>(context.source_loc()); }
|
||||
| FOR LEFT_PARENTHESIS variable_declaration IN type_expression RIGHT_PARENTHESIS block
|
||||
{ $$ = arena->New<For>(context.source_loc(), $3, $5, $7); }
|
||||
;
|
||||
if_statement:
|
||||
IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS block optional_else
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ package ExplorerTest api;
|
||||
|
||||
fn Main() -> i32 {
|
||||
// error
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_missing_var.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting MINUS or PLUS
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_missing_var.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting EQUAL or SEMICOLON
|
||||
x : i32;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ fn Main() -> i32 {
|
||||
// Error: can't use keyword `Self` as the name of a variable.
|
||||
// TODO: Current error message is unclear, better would be to say
|
||||
// something like: unexpected `Self`, expecting identifier
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_var_named_self.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting MINUS or PLUS
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_var_named_self.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting EQUAL or SEMICOLON
|
||||
var Self : i32 = 0;
|
||||
return Self;
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: result: 8
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
|
||||
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 4] = (0, 1,2,3);
|
||||
var count : i32 = 0;
|
||||
for( x: i32 in ar){
|
||||
Print("HALLO WELT ", x);
|
||||
count = count +1;
|
||||
}
|
||||
for( x: i32 in ar){
|
||||
Print("HALLO WELT ", x);
|
||||
count = count +1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: HALLO WELT
|
||||
// CHECK: result: 4
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
|
||||
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 4] = (0, 1,2,3);
|
||||
var count : i32 = 0;
|
||||
for( x: auto in ar){
|
||||
Print("HALLO WELT ", x);
|
||||
count = count +1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: result: 3
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
|
||||
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 4] = (0, 1,2,3);
|
||||
var count : i32 = 0;
|
||||
for( x: i32 in ar){
|
||||
count = count +x;
|
||||
if( x == 2){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: result: 4
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
|
||||
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 4] = (0, 1,2,3);
|
||||
var count : i32 = 0;
|
||||
for( x: i32 in ar){
|
||||
if( x == 2){
|
||||
continue;
|
||||
}
|
||||
count = count +x;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: result: 0
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 0] = () ;
|
||||
var count : i32 = 0;
|
||||
for( x: i32 in ar ){
|
||||
count = 2;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// RUN: %{explorer} %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s
|
||||
// RUN: %{explorer} --parser_debug --trace_file=- %s 2>&1 | \
|
||||
// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes %s
|
||||
// AUTOUPDATE: %{explorer} %s
|
||||
// CHECK: result: 20
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
fn Main() -> i32 {
|
||||
var ar: [i32; 4] = (0, 1,2,3);
|
||||
var count : i32 = 0;
|
||||
for( x: i32 in ar){
|
||||
count = count +1;
|
||||
for( x: i32 in ar){
|
||||
count = count +1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ package ExplorerTest api;
|
||||
|
||||
fn Main() -> i32 {
|
||||
// Error: Can't use keyword `Self` as the name of a local.
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_local_named_self.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting MINUS or PLUS
|
||||
// CHECK: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_local_named_self.carbon:[[@LINE+1]]: syntax error, unexpected COLON, expecting EQUAL
|
||||
let Self: auto = 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user