Exemplo n.º 1
0
Type* find_common_type(Type* type1, Type* type2)
{
    if (type1 == NULL)
        return type2;

    if (type1 == type2)
        return type1;

    if (type1 == TYPES.any || type2 == TYPES.any)
        return TYPES.any;

    if (is_list_based_type(type1) && is_list_based_type(type2))
        return TYPES.list;

    return TYPES.any;
}
Exemplo n.º 2
0
Type* find_common_type(Type* type1, Type* type2)
{
    if (type1 == NULL)
        return type2;

    if (type1 == type2)
        return type1;

    if (type1 == &ANY_T || type2 == &ANY_T)
        return &ANY_T;

    if (is_list_based_type(type1) && is_list_based_type(type2))
        return &LIST_T;

    return &ANY_T;
}
Exemplo n.º 3
0
Type* get_field_specializeType(Term* caller)
{
    Type* head = caller->input(0)->type;

    for (int nameIndex=1; nameIndex < caller->numInputs(); nameIndex++) {

        // Abort if input type is not correct
        if (!is_string(term_value(caller->input(1))))
            return TYPES.any;

        if (!is_list_based_type(head))
            return TYPES.any;

        Value* name = term_value(caller->input(1));

        int fieldIndex = list_find_field_index_by_name(head, name);

        if (fieldIndex == -1)
            return TYPES.any;

        head = as_type(get_index(list_get_type_list_from_type(head),fieldIndex));
    }

    return head;
}
Exemplo n.º 4
0
    void tv_static_type_query(Type* type, StaticTypeQuery* query)
    {
        Term* subject = query->subject;
        Type* subjectType = query->subjectType;

        // If the type doesn't have a specific size, then accept any list.
        if (!list_type_has_specific_size(&type->parameter)) {
            if (is_list_based_type(subjectType))
                return query->succeed();
            else
                return query->fail();
        }

        caValue* expectedElementTypes = list_get_type_list_from_type(type);

        // Special case when looking at a call to list(); look at inputs instead of
        // looking at the result.
        if (subject && subject->function == FUNCS.list)
        {
            if (subject->numInputs() != circa_count(expectedElementTypes))
                return query->fail();

            for (int i=0; i < circa_count(expectedElementTypes); i++)
                if (!circa::term_output_always_satisfies_type(
                            subject->input(i), as_type(circa_index(expectedElementTypes, i))))
                    return query->fail();

            return query->succeed();
        }

        // Look at the subject's type.
        if (!list_type_has_specific_size(&subjectType->parameter))
            return query->fail();

        caValue* subjectElementTypes = list_get_type_list_from_type(subjectType);

        bool anyUnableToDetermine = false;

        for (int i=0; i < circa_count(expectedElementTypes); i++) {
            if (i >= circa_count(subjectElementTypes))
                return query->fail();

            StaticTypeQuery::Result result = run_static_type_query(
                    as_type(circa_index(expectedElementTypes,i)),
                    as_type(circa_index(subjectElementTypes,i)));

            // If any of these fail, then fail.
            if (result == StaticTypeQuery::FAIL)
                return query->fail();

            if (result == StaticTypeQuery::UNABLE_TO_DETERMINE)
                anyUnableToDetermine = true;
        }

        if (anyUnableToDetermine)
            return query->unableToDetermine();
        else
            return query->succeed();
    }
Exemplo n.º 5
0
int list_find_field_index_by_name(Type* listType, const char* name)
{
    if (!is_list_based_type(listType))
        return -1;

    caValue* names = list_get_name_list_from_type(listType);
    if (names == NULL)
        return -1;

    for (int i=0; i < circa_count(names); i++)
        if (string_eq(circa_index(names, i), name))
            return i;

    // Not found
    return -1;
}
Exemplo n.º 6
0
caValue* list_get_name_list_from_type(Type* type)
{
    ca_assert(is_list_based_type(type));
    caValue* parameter = &type->parameter;

    switch (list_get_parameter_type(parameter)) {
    case name_StructType:
        return list_get(parameter, 1);
    case name_AnonStructType:
    case name_Untyped:
    case name_UniformListType:
    case name_Invalid:
        return NULL;
    }
    ca_assert(false);
    return NULL;
}
Exemplo n.º 7
0
Type* find_common_type(caValue* list)
{
    if (list_length(list) == 0)
        return TYPES.any;

    // Check if every type in this list is the same.
    bool all_equal = true;
    for (int i=1; i < list_length(list); i++) {
        if (as_type(list_get(list,0)) != as_type(list_get(list,i))) {
            all_equal = false;
            break;
        }
    }

    if (all_equal)
        return as_type(list_get(list,0));

    // Special case, allow ints to go into floats
    bool all_are_ints_or_floats = true;
    for (int i=0; i < list_length(list); i++) {
        if ((as_type(list_get(list,i)) != TYPES.int_type)
                && (as_type(list_get(list,i)) != TYPES.float_type)) {
            all_are_ints_or_floats = false;
            break;
        }
    }

    if (all_are_ints_or_floats)
        return TYPES.float_type;

    // Another special case, if all types are lists then use List
    bool all_are_lists = true;
    for (int i=0; i < list_length(list); i++) {
        if (!is_list_based_type(as_type(list_get(list,i))))
            all_are_lists = false;
    }

    if (all_are_lists)
        return TYPES.list;

    // Otherwise give up
    return TYPES.any;
}
Exemplo n.º 8
0
bool list_equals(caValue* left, caValue* right)
{
    ca_assert(is_list(left));

    if (!is_list_based_type(right->value_type))
        return false;

    // Shortcut: lists are equal if they have the same address.
    if (left->value_data.ptr == right->value_data.ptr)
        return true;

    int leftCount = list_length(left);

    // Not equal if lengths differ.
    if (leftCount != list_length(right))
        return false;

    // Check every element.
    for (int i=0; i < leftCount; i++) {
        if (!equals(list_get(left, i), list_get(right, i)))
            return false;
    }

#if 0
    // Sneaky optimization. We just verified that 'left' and 'right' are deeply
    // equal, so no one will notice if they actually use the same data.
    //
    // TODO: This optimization can't be turned on as long as integers and numbers can
    // compare equal. Ditto for lists that have equal contents but different type tags.
    // 
    // The best thing to do is probably have this function return two types of equality:
    // 'loose' and 'exact'. We can do the sneaky optimization iff there is exact equality.
    //
    // Also, don't forget to preserve the type tag for 'right'.
    //
    set_null(right);
    list_copy(left, right);
#endif

    return true;
}
Exemplo n.º 9
0
Type* list_get_repeated_type_from_type(Type* type)
{
    ca_assert(is_list_based_type(type));
    return as_type(&type->parameter);
}