示例#1
0
void block_update_pack_state_calls(Block* block)
{
    if (block->stateType == NULL) {
        // No state type, make sure there's no pack_state call.
        // TODO: Handle this case properly (should search and destroy an existing pack_state call)
        return;
    }

    int stateOutputIndex = block->length() - 1 - find_state_output(block)->index;

    for (int i=0; i < block->length(); i++) {
        Term* term = block->get(i);
        if (term == NULL)
            continue;

        if (term->function == FUNCS.pack_state) {
            // Update the inputs for this pack_state call
            TermList inputs;
            list_inputs_to_pack_state(block, i, &inputs);
            set_inputs(term, inputs);
        }

        else if (should_have_preceeding_pack_state(term)) {
            // Check if we need to insert a pack_state call
            Term* existing = term->input(stateOutputIndex);

            if (existing == NULL || existing->function != FUNCS.pack_state) {
                TermList inputs;
                list_inputs_to_pack_state(block, i, &inputs);
                if (inputs.length() != 0) {
                    Term* pack_state = apply(block, FUNCS.pack_state, inputs);
                    move_before(pack_state, term);

                    // Only set as an input for a non-minor block.
                    if (term->nestedContents == NULL || !is_minor_block(term->nestedContents)) {
                        set_input(term, stateOutputIndex, pack_state);
                        set_input_hidden(term, stateOutputIndex, true);
                        set_input_implicit(term, stateOutputIndex, true);
                    }

                    // Advance i to compensate for the term just added
                    i++;
                }
            }
        }
    }
}
示例#2
0
void update_derived_inputs_for_exit_point(Term* term)
{
    // Make sure that this exit point includes every block output as an input.
    // The intermediate value might be different at this location.

    Block* block = find_block_that_exit_point_will_reach(term);
    
    for (int i=0;; i++) {
        Term* inputResult = get_output_placeholder(block, i);
        if (inputResult == NULL)
            break;

        // Don't touch input if it's explicit.
        if (i < term->numInputs() && !is_input_implicit(term, i))
            continue;

        Term* intermediateValue = find_intermediate_result_for_output(term, inputResult);

        set_input(term, i, intermediateValue);
        set_input_implicit(term, i, true);
        set_input_hidden(term, i, true);
    }
}