mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +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
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user