示例#1
0
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);
    }
}
示例#2
0
// 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);
    }
}
示例#3
0
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();
}
示例#4
0
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;
}