Пример #1
0
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;
}
Пример #2
0
Term* run_name_search(NameSearch* params)
{
    stat_increment(NameSearch);

    if (is_null(&params->name) || string_equals(&params->name, ""))
        return NULL;

    Block* block = params->block;

    if (block == NULL)
        return NULL;

    int position = 0;
    
    if (is_symbol(&params->position) && as_symbol(&params->position) == s_last)
        position = block->length();
    else
        position = as_int(&params->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, &params->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, &params->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, &params->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, &params->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, &params->name);
    parentSearch.lookupType = params->lookupType;
    parentSearch.ordinal = -1;
    parentSearch.searchParent = true;
    return run_name_search(&parentSearch);
}