Exemple #1
0
void insert_looped_placeholders(Block* contents)
{
    Value names;
    list_names_that_must_be_looped(contents, &names);

    for (ListIterator it(&names); it; ++it) {
        Term* inputPlaceholder = append_input_placeholder(contents);
        Value* name = it.value();
        rename(inputPlaceholder, name);
        Value owningTermVal;
        owningTermVal.set_term(contents->owningTerm);
        Term* outsideTerm = find_name_at(&owningTermVal, name);
        Term* innerResult = find_local_name(contents, name);
        Term* outputPlaceholder = append_output_placeholder(contents, innerResult);
        rename(outputPlaceholder, name);

        set_inputs(inputPlaceholder, TermList(outsideTerm, outputPlaceholder));

        for (BlockInputIterator it(contents); it; ++it) {
            Term* term = it.currentTerm();
            if (it.currentInput() == outsideTerm && term != inputPlaceholder)
                set_input(term, it.currentInputIndex(), inputPlaceholder);
        }
    }
}
Exemple #2
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);
}
Exemple #3
0
void add_implicit_placeholders(Term* forTerm)
{
    Branch* contents = nested_contents(forTerm);
    std::string listName = forTerm->input(0)->name;
    Term* iterator = for_loop_get_iterator(contents);
    std::string iteratorName = iterator->name;

    std::vector<std::string> reboundNames;
    list_names_that_this_branch_rebinds(contents, reboundNames);

    int inputIndex = 1;

    for (size_t i=0; i < reboundNames.size(); i++) {
        std::string const& name = reboundNames[i];
        if (name == listName)
            continue;
        if (name == iteratorName)
            continue;

        Term* original = find_name_at(forTerm, name.c_str());

        // The name might not be found, for certain parser errors.
        if (original == NULL)
            continue;

        Term* result = contents->get(name);

        // Create input_placeholder
        Term* input = apply(contents, FUNCS.input, TermList(), name_from_string(name));
        Type* type = find_common_type(original->type, result->type);
        change_declared_type(input, type);
        contents->move(input, inputIndex);

        set_input(forTerm, inputIndex, original);

        // Repoint terms to use our new input_placeholder
        for (BranchIterator it(contents); it.unfinished(); it.advance())
            remap_pointers_quick(*it, original, input);

        // Create output_placeholder
        Term* term = apply(contents, FUNCS.output, TermList(result), name_from_string(name));

        // Move output into the correct output slot
        contents->move(term, contents->length() - 1 - inputIndex);

        inputIndex++;
    }
}
Exemple #4
0
Term* if_block_add_output_for_name(Term* ifCall, const char* name)
{
    // Fix the new output placeholders to have the correct name and input.
    Branch* mainBranch = nested_contents(ifCall);
    int outputCount = count_output_placeholders(mainBranch);
    Term* outputPlaceholder = if_block_append_output(ifCall);
    rename(outputPlaceholder, name);

    for (CaseIterator it(mainBranch); it.unfinished(); it.advance()) {
        Branch* caseContents = nested_contents(it.current());
        Term* casePlaceholder = get_output_placeholder(caseContents, outputCount);
        ca_assert(casePlaceholder != NULL);
        ca_assert(casePlaceholder->name == "");
        rename(casePlaceholder, name);
        set_input(casePlaceholder, 0, find_name_at(casePlaceholder, name));
        respecialize_type(casePlaceholder);
    }
    return outputPlaceholder;
}