static void list_inputs_to_pack_state(Block* block, int position, TermList* output) { output->clear(); if (block->stateType == NULL) return; for (int i=0; i < compound_type_get_field_count(block->stateType); i++) { const char* fieldName = compound_type_get_field_name(block->stateType, i); Term* result = find_output_term_for_state_field(block, fieldName, position); output->append(result); } }
// Write a list of terms to 'output' corresponding to the list of state outputs at this // position in the branch. Useful for populating a list of inputs for pack_state. static void get_list_of_state_outputs(Branch* branch, int position, TermList* output) { output->clear(); if (branch->stateType == NULL) return; for (int i=0; i < compound_type_get_field_count(branch->stateType); i++) { const char* fieldName = compound_type_get_field_name(branch->stateType, i); Term* result = find_output_term_for_state_field(branch, fieldName, position); output->append(result); } }
std::string compound_type_to_string(caValue* value) { Type* type = value->value_type; std::stringstream out; out << "{"; for (int i=0; i < compound_type_get_field_count(type); i++) { if (i != 0) out << ", "; const char* name = compound_type_get_field_name(type, i); out << name; out << ": "; out << to_string(list_get(value, i)); } out << "}"; return out.str(); }
bool branch_state_type_is_out_of_date(Branch* branch) { // Alloc an array that tracks, for each field in the existing stateType, // whether we have found a corresponding term for that field. bool* typeFieldFound = NULL; int existingFieldCount = 0; if (branch->stateType != NULL) { existingFieldCount = compound_type_get_field_count(branch->stateType); size_t size = sizeof(bool) * existingFieldCount; typeFieldFound = (bool*) malloc(size); memset(typeFieldFound, 0, size); } // Walk through every term and check whether every unpack_state call is already // mentioned in the state type. for (int i=0; i < branch->length(); i++) { Term* term = branch->get(i); if (term == NULL) continue; if (term->function != FUNCS.unpack_state) continue; // Found an unpack_state call Term* identifyingTerm = term->input(1); // If the branch doesn't yet have a stateType then that's an update. if (branch->stateType == NULL) goto return_true; // Look for the field name int fieldIndex = list_find_field_index_by_name(branch->stateType, unique_name(identifyingTerm)); // If the name isn't found then that's an update if (fieldIndex == -1) goto return_true; // If the type doesn't match then that's an update if (compound_type_get_field_type(branch->stateType, fieldIndex) != declared_type(term)) goto return_true; // Record this field index as 'found' typeFieldFound[fieldIndex] = true; } // If there were any fields in the type that weren't found in the branch, then // that's an update. if (typeFieldFound != NULL) { for (int i=0; i < existingFieldCount; i++) { if (!typeFieldFound[i]) goto return_true; } } // No reason to update, return false. free(typeFieldFound); return false; return_true: free(typeFieldFound); return true; }