Helper to lookup a variable mapped to a slot. If lazy evaluation enabled and ided as a lazy expression, subexpression and slot will be set.
| 711 | // If lazy evaluation enabled and ided as a lazy expression, |
| 712 | // subexpression and slot will be set. |
| 713 | SlotLookupResult LookupSlot(absl::string_view path) { |
| 714 | // If there's a leading dot, it cannot resolve to a local variable. |
| 715 | if (absl::StartsWith(path, ".")) { |
| 716 | return {-1, -1}; |
| 717 | } |
| 718 | if (block_.has_value()) { |
| 719 | const BlockInfo& block = *block_; |
| 720 | if (block.in) { |
| 721 | absl::string_view index_suffix = path; |
| 722 | if (absl::ConsumePrefix(&index_suffix, "@index")) { |
| 723 | size_t index; |
| 724 | if (!absl::SimpleAtoi(index_suffix, &index)) { |
| 725 | SetProgressStatusError( |
| 726 | issue_collector_.AddIssue(RuntimeIssue::CreateError( |
| 727 | absl::InvalidArgumentError("bad @index")))); |
| 728 | return {-1, -1}; |
| 729 | } |
| 730 | if (index >= block.size) { |
| 731 | SetProgressStatusError( |
| 732 | issue_collector_.AddIssue(RuntimeIssue::CreateError( |
| 733 | absl::InvalidArgumentError(absl::StrCat( |
| 734 | "invalid @index greater than number of bindings: ", |
| 735 | index, " >= ", block.size))))); |
| 736 | return {-1, -1}; |
| 737 | } |
| 738 | if (index >= block.current_index) { |
| 739 | SetProgressStatusError( |
| 740 | issue_collector_.AddIssue(RuntimeIssue::CreateError( |
| 741 | absl::InvalidArgumentError(absl::StrCat( |
| 742 | "@index references current or future binding: ", index, |
| 743 | " >= ", block.current_index))))); |
| 744 | return {-1, -1}; |
| 745 | } |
| 746 | return {static_cast<int>(block.index + index), |
| 747 | block.subexpressions[index]}; |
| 748 | } |
| 749 | } |
| 750 | } |
| 751 | if (!comprehension_stack_.empty()) { |
| 752 | for (int i = comprehension_stack_.size() - 1; i >= 0; i--) { |
| 753 | const ComprehensionStackRecord& record = comprehension_stack_[i]; |
| 754 | if (record.iter_var_in_scope && |
| 755 | record.comprehension->iter_var() == path) { |
| 756 | if (record.is_optimizable_bind) { |
| 757 | SetProgressStatusError(issue_collector_.AddIssue( |
| 758 | RuntimeIssue::CreateWarning(absl::InvalidArgumentError( |
| 759 | "Unexpected iter_var access in trivial comprehension")))); |
| 760 | return {-1, -1}; |
| 761 | } |
| 762 | return {static_cast<int>(record.iter_slot), -1}; |
| 763 | } |
| 764 | if (record.iter_var2_in_scope && |
| 765 | record.comprehension->iter_var2() == path) { |
| 766 | return {static_cast<int>(record.iter2_slot), -1}; |
| 767 | } |
| 768 | if (record.accu_var_in_scope && |
| 769 | record.comprehension->accu_var() == path) { |
| 770 | int slot = record.accu_slot; |
nothing calls this directly
no test coverage detected