示例#1
0
void list_names_that_must_be_looped(Block* contents, Value* names)
{
    // Find all names within 'contents' that must be looped. A name must be looped when
    // a term inside the loop binds a name that was already used outside the loop.

    Value namesMap;
    set_hashtable(&namesMap);

    for (BlockIteratorFlat it(contents); it; ++it) {
        Term* term = it.current();

        if (has_empty_name(term))
            continue;

        Value termVal;
        termVal.set_term(contents->owningTerm);
        Term* outsideName = find_name_at(&termVal, term_name(term));

        // Don't look at names outside the major block.
        if (outsideName != NULL && !is_under_same_major_block(term, outsideName))
            outsideName = NULL;

        if (outsideName != NULL)
            set_bool(hashtable_insert(&namesMap, term_name(term)), true);
    }

    hashtable_get_keys(&namesMap, names);
    list_sort(names, NULL, NULL);
}
示例#2
0
void trace_accessor_chain(Term* accessor, TermList* chainResult)
{
    Term* bottomAccessor = accessor;

    chainResult->resize(0);

    while (true) {
        chainResult->append(accessor);

        // Stop when we find a named term.
        if (!has_empty_name(accessor))
            break;

        if (accessor->function == FUNCS.get_index
                || accessor->function == FUNCS.get_field
                || is_copying_call(accessor)
                || accessor->function == FUNCS.dynamic_method
                || is_subroutine(accessor->function)) {

            // Continue the trace upward.
            accessor = accessor->input(0);
            continue;
        }

        // Accessor search can't continue past this term.
        break;
    }

    chainResult->reverse();
}
示例#3
0
void Term__name(VM* vm)
{
    Term* t = as_term_ref(vm->input(0));
    if (t == NULL)
        return vm->throw_str("NULL term");
    if (has_empty_name(t))
        set_string(vm->output(), "");
    else
        copy(term_name(t), vm->output());
}
示例#4
0
void Block::bindName(Term* term, Value* name)
{
    if (!has_empty_name(term) && !equals(&term->nameValue, name)) {
        internal_error(std::string("term already has a name: ") + term->nameStr());
    }

    if (!is_null(name))
        names.bind(term, as_cstring(name));

    copy(name, &term->nameValue);
    update_unique_name(term);
}
示例#5
0
bool is_considered_config(Term* term)
{
    if (term == NULL) return false;
    if (has_empty_name(term)) return false;
    if (!is_value(term)) return false;
    if (is_declared_state(term)) return false;
    if (is_hidden(term)) return false;
    if (is_function(term)) return false;
    if (is_type(term)) return false;

    return true;
}
示例#6
0
Term* rebind_possible_accessor(Branch* branch, Term* accessor, Term* result)
{
    // Check if this isn't a recognized accessor.
    if (!has_empty_name(accessor)) {
        // Just create a named copy of 'result'.
        return apply(branch, FUNCS.copy, TermList(result), accessor->nameSymbol);
    }

    TermList accessorChain;
    trace_accessor_chain(accessor, &accessorChain);

    Term* head = accessorChain[0];

    // Create the selector
    Term* selector = write_selector_for_accessor_chain(branch, &accessorChain);

    Term* set = apply(branch, FUNCS.set_with_selector,
            TermList(head, selector, result), head->nameSymbol);

    change_declared_type(set, declared_type(head));
    return set;
}
示例#7
0
void Block::removeNameBinding(Term* term)
{
    if (!has_empty_name(term) && names[term->name()] == term)
        names.remove(term->name());
}