Term* loop_find_iterator_value(Block* block) { for (int i=0; i < block->length(); i++) { Term* term = block->get(i); if (term->boolProp(s_iterator_value, false)) return term; } return NULL; }
Term* run_name_search(NameSearch* params) { stat_increment(NameSearch); if (is_null(¶ms->name) || string_equals(¶ms->name, "")) return NULL; Block* block = params->block; if (block == NULL) return NULL; int position = 0; if (is_symbol(¶ms->position) && as_symbol(¶ms->position) == s_last) position = block->length(); else position = as_int(¶ms->position); if (position > block->length()) position = block->length(); // Look for an exact match. for (int i = position - 1; i >= 0; i--) { stat_increment(NameSearchStep); Term* term = block->get(i); if (term == NULL) continue; if (equals(&term->nameValue, ¶ms->name) && fits_lookup_type(term, params->lookupType) && (params->ordinal == -1 || term->uniqueOrdinal == params->ordinal)) return term; // If this term exposes its names, then search inside the nested block. // (Deprecated, I think). if (term->nestedContents != NULL && exposes_nested_names(term)) { NameSearch nestedSearch; nestedSearch.block = term->nestedContents; set_value(&nestedSearch.name, ¶ms->name); set_symbol(&nestedSearch.position, s_last); nestedSearch.ordinal = -1; nestedSearch.lookupType = params->lookupType; nestedSearch.searchParent = false; Term* found = run_name_search(&nestedSearch); if (found != NULL) return found; } #if 0 // Check for an 'import' statement. If found, continue this search in the designated module. if (term->function == FUNCS.require && term->boolProp(s_Syntax_Import, false)) { Block* module = find_module_for_require_statement(term); if (module != NULL) { NameSearch moduleSearch; moduleSearch.block = module; set_value(&moduleSearch.name, ¶ms->name); set_symbol(&moduleSearch.position, s_last); moduleSearch.ordinal = -1; moduleSearch.lookupType = params->lookupType; moduleSearch.searchParent = false; Term* found = run_name_search(&moduleSearch); if (found != NULL) return found; } } #endif } // Did not find in the local block. Possibly continue this search upwards. if (!params->searchParent) return NULL; // Possibly take this search to the builtins block. if ((get_parent_block(block) == NULL) || is_module(block)) { NameSearch builtinsSearch; builtinsSearch.block = find_builtins_block(block); set_value(&builtinsSearch.name, ¶ms->name); set_symbol(&builtinsSearch.position, s_last); builtinsSearch.lookupType = params->lookupType; builtinsSearch.ordinal = -1; builtinsSearch.searchParent = false; return run_name_search(&builtinsSearch); } // Search parent // The choice of position is a little weird. For regular name searches, // we start at the parent term's position (ie, search all the terms that // came before the parent). // // For a LookupFunction search, start at the bottom of the branch. It's okay // for a term to use a function that occurs after the term. NameSearch parentSearch; Term* parentTerm = block->owningTerm; if (parentTerm == NULL) return NULL; parentSearch.block = parentTerm->owningBlock; if (params->lookupType == s_LookupFunction) set_symbol(&parentSearch.position, s_last); else set_int(&parentSearch.position, parentTerm->index + 1); set_value(&parentSearch.name, ¶ms->name); parentSearch.lookupType = params->lookupType; parentSearch.ordinal = -1; parentSearch.searchParent = true; return run_name_search(&parentSearch); }