void append_state_placeholders_if_needed(Branch* branch) { if (!has_state_input(branch)) append_state_input(branch); if (!has_state_output(branch)) append_state_output(branch); }
void for_loop_fix_state_input(Branch* contents) { // This function will look at the state access inside for-loop contents. // If there's state, the default building functions will have created // terms that look like this: // // input() :state -> unpack_state -> pack_state -> output() :state // // We want each loop iteration to have its own state container. So we'll // insert pack/unpack_state_list_n terms so that each iteration accesses // state from a list. The result will look like: // // input() :state -> unpack_state_list_n(index) -> unpack_state -> pack_state // -> pack_state_list_n(index) -> output() :state // First insert the unpack_state_list_n call Term* stateInput = find_state_input(contents); // Nothing to do if there's no state input if (stateInput == NULL) return; // Nothing to do if unpack_state_list_n term already exists if (find_user_with_function(stateInput, FUNCS.unpack_state_list_n) != NULL) return; Term* unpackState = find_user_with_function(stateInput, FUNCS.unpack_state); ca_assert(unpackState != NULL); Term* index = for_loop_find_index(contents); Term* unpackStateList = apply(contents, FUNCS.unpack_state_list_n, TermList(stateInput, index)); transfer_users(stateInput, unpackStateList); move_before(unpackStateList, unpackState); set_input(unpackState, 0, unpackStateList); // Now insert the pack_state_list_n call Term* stateResult = find_open_state_result(contents, contents->length()); Term* packStateList = apply(contents, FUNCS.pack_state_list_n, TermList(stateInput, stateResult, index)); packStateList->setBoolProp("final", true); move_after(packStateList, stateResult); // Make sure the state output uses this result Term* stateOutput = append_state_output(contents); set_input(stateOutput, 0, packStateList); }
Term* find_or_create_state_container(Branch* branch) { Term* existing = find_active_state_container(branch); if (existing != NULL) return existing; // None yet, insert one Term* input = append_state_input(branch); // Add a final pack_state call too Term* packState = append_final_pack_state(branch); // And the state output append_state_output(branch); return input; }