@@ -153,34 +153,18 @@ namespace pl::core::ast {
153153 void ASTNodeRValue::createPatterns (Evaluator *evaluator, std::vector<std::shared_ptr<ptrn::Pattern>> &resultPatterns) const {
154154 [[maybe_unused]] auto context = evaluator->updateRuntime (this );
155155
156- std::vector<std::shared_ptr<ptrn::Pattern>> searchScope;
157156 std::shared_ptr<ptrn::Pattern> currPattern;
158157 i32 scopeIndex = 0 ;
159158 bool iterable = true ;
160159
161- if (!evaluator->isGlobalScope ()) {
162- const auto &globalScope = evaluator->getGlobalScope ().scope ;
163- std::copy (globalScope->begin (), globalScope->end (), std::back_inserter (searchScope));
164- }
165-
166- {
167- const auto &templateParameters = evaluator->getTemplateParameters ();
168- std::copy (templateParameters.begin (), templateParameters.end (), std::back_inserter (searchScope));
169- }
170-
171- {
172- const auto &currScope = evaluator->getScope (0 );
173- std::copy (currScope.scope ->begin (), currScope.scope ->end (), std::back_inserter (searchScope));
174- }
175-
176160 for (const auto &part : this ->getPath ()) {
177161
178162 if (!iterable)
179163 err::E0001 .throwError (" Member access of a non-iterable type." , " Try using a struct-like object or an array instead." , this ->getLocation ());
180164
181165 if (part.index () == 0 ) {
182166 // Variable access
183- auto name = std::get<std::string>(part);
167+ const auto & name = std::get<std::string>(part);
184168
185169 if (name == " parent" ) {
186170 do {
@@ -190,7 +174,6 @@ namespace pl::core::ast {
190174 err::E0003 .throwError (" Cannot access parent of global scope." , {}, this ->getLocation ());
191175 } while (evaluator->getScope (scopeIndex).parent == nullptr );
192176
193- searchScope = *evaluator->getScope (scopeIndex).scope ;
194177 auto currParent = evaluator->getScope (scopeIndex).parent ;
195178
196179 if (currParent == nullptr ) {
@@ -201,8 +184,6 @@ namespace pl::core::ast {
201184
202185 continue ;
203186 } else if (name == " this" ) {
204- searchScope = *evaluator->getScope (scopeIndex).scope ;
205-
206187 auto currParent = evaluator->getScope (0 ).parent ;
207188
208189 if (currParent == nullptr )
@@ -211,22 +192,44 @@ namespace pl::core::ast {
211192 currPattern = currParent;
212193 continue ;
213194 } else {
214- bool found = false ;
215- for (auto iter = searchScope.crbegin (); iter != searchScope.crend (); ++iter) {
216- if ((*iter)->getVariableName () == name) {
217- currPattern = *iter;
218- found = true ;
219- break ;
220- }
195+ using namespace std ::views;
196+ using std::ranges::find;
197+ std::shared_ptr<ptrn::Pattern> pattern;
198+
199+ if (currPattern == nullptr ) {
200+ auto currScope = *evaluator->getScope (0 ).scope | all;
201+ auto templateParameters = evaluator->getTemplateParameters () | all;
202+ auto globalScope = *evaluator->getGlobalScope ().scope | all;
203+ auto allScopes = {globalScope, templateParameters, currScope};
204+ auto searchScopes = allScopes | drop (evaluator->isGlobalScope () ? 1 : 0 );
205+ auto view = searchScopes | join | reverse;
206+ if (auto result = find (view, name, &ptrn::Pattern::getVariableName); result != view.end ())
207+ pattern = *result;
208+ } else if (auto currParent = evaluator->getScope (scopeIndex).parent ; currParent == currPattern) {
209+ auto view = *evaluator->getScope (scopeIndex).scope | reverse;
210+ if (auto result = find (view, name, &ptrn::Pattern::getVariableName); result != view.end ())
211+ pattern = *result;
212+ } else if (auto indexablePattern = dynamic_cast <ptrn::IIndexable *>(currPattern.get ()); indexablePattern != nullptr ) {
213+ auto iota_view = iota ((size_t )0 , indexablePattern->getEntryCount ());
214+ auto view = iota_view | transform (std::bind_front (&ptrn::IIndexable::getEntry, indexablePattern)) | reverse;
215+ if (auto result = find (view, name, &ptrn::Pattern::getVariableName); result != view.end ())
216+ pattern = *result;
217+ } else if (auto iterablePattern = dynamic_cast <ptrn::IIterable *>(currPattern.get ()); iterablePattern != nullptr ) {
218+ auto scope = iterablePattern->getEntries ();
219+ auto view = scope | reverse;
220+ if (auto result = find (view, name, &ptrn::Pattern::getVariableName); result != view.end ())
221+ pattern = *result;
221222 }
222223
223224 if (name == " $" )
224225 err::E0003 .throwError (" Invalid use of '$' operator in rvalue." , {}, this ->getLocation ());
225226 else if (name == " null" )
226227 err::E0003 .throwError (" Invalid use of 'null' keyword in rvalue." , {}, this ->getLocation ());
227228
228- if (!found )
229+ if (pattern == nullptr )
229230 err::E0003 .throwError (fmt::format (" No variable named '{}' found." , name), {}, this ->getLocation ());
231+
232+ currPattern = std::move (pattern);
230233 }
231234 } else {
232235 // Array indexing
@@ -262,9 +265,7 @@ namespace pl::core::ast {
262265
263266 auto indexPattern = currPattern.get ();
264267
265- if (auto iterablePattern = dynamic_cast <ptrn::IIterable *>(indexPattern); iterablePattern != nullptr )
266- searchScope = iterablePattern->getEntries ();
267- else
268+ if (auto iterablePattern = dynamic_cast <ptrn::IIterable *>(indexPattern); iterablePattern == nullptr )
268269 iterable = false ;
269270
270271 }
0 commit comments