Exemple #1
0
ListData* list_remove_index(ListData* original, int index)
{
    ca_assert(index < original->count);
    ListData* result = list_touch(original);

    for (int i=index; i < result->count - 1; i++)
        swap(&result->items[i], &result->items[i+1]);
    set_null(&result->items[result->count - 1]);
    result->count--;
    return result;
}
Exemple #2
0
void compound_type_append_field(Type* type, Type* fieldType, const char* fieldName)
{
    ca_assert(list_get_parameter_type(&type->parameter) == name_StructType);

    list_touch(&type->parameter);
    caValue* types = list_get(&type->parameter, 0);
    caValue* names = list_get(&type->parameter, 1);

    set_type(list_append(types), fieldType);
    set_string(list_append(names), fieldName);
}
Exemple #3
0
void list_remove_and_replace_with_last_element(ListData** data, int index)
{
    *data = list_touch(*data);
    ca_assert(index < (*data)->count);

    set_null(&(*data)->items[index]);

    int lastElement = (*data)->count - 1;
    if (index < lastElement)
        swap(&(*data)->items[index], &(*data)->items[lastElement]);

    (*data)->count--;
}
Exemple #4
0
caValue* list_append(ListData** dataPtr)
{
    if (*dataPtr == NULL) {
        *dataPtr = allocate_empty_list(1);
    } else {
        *dataPtr = list_touch(*dataPtr);
        
        if ((*dataPtr)->count == (*dataPtr)->capacity)
            *dataPtr = list_double_capacity(*dataPtr);
    }

    ListData* data = *dataPtr;
    data->count++;
    return &data->items[data->count - 1];
}
Exemple #5
0
void list_remove_nulls(ListData** dataPtr)
{
    if (*dataPtr == NULL)
        return;

    *dataPtr = list_touch(*dataPtr);
    ListData* data = *dataPtr;

    int numRemoved = 0;
    for (int i=0; i < data->count; i++) {
        if (is_null(&data->items[i]))
            numRemoved++;
        else
            swap(&data->items[i - numRemoved], &data->items[i]);
    }
    *dataPtr = list_resize(*dataPtr, data->count - numRemoved);
}
Exemple #6
0
ListData* list_resize(ListData* original, int newLength)
{
    // Check if 'original' is an empty list.
    if (original == NULL) {

        // If newLength is 0 then no change.
        if (newLength == 0)
            return NULL;

        // Create a new empty list.
        ListData* result = allocate_empty_list(newLength);
        result->count = newLength;
        return result;
    }

    // Special case: if newLength is 0 then return an empty list.
    if (newLength == 0) {
        list_decref(original);
        return NULL;
    }

    // Check if the new length is the same as the old length.
    if (original->count == newLength)
        return original;

    // Increase capacity if necessary.
    if (newLength > original->capacity) {
        ListData* result = list_increase_capacity(original, newLength);
        result->count = newLength;
        return result;
    }

    // At this point the capacity is good, we need to modify list->count, and
    // discard some rightmost elements.
    ListData* result = list_touch(original);

    // Set rightmost elements to null, if we are shrinking.
    for (int i=newLength; i < result->count; i++)
        set_null(&result->items[i]);

    result->count = newLength;

    return result;
}
Exemple #7
0
    void tv_cast(CastResult* result, caValue* value, Type* type, bool checkOnly)
    {
        if (!is_list(value)) {
            result->success = false;
            return;
        }

        int sourceLength = list_length(value);

        // If the requested type doesn't have a specific size restriction, then
        // the input data is fine as-is.
        if (!list_type_has_specific_size(&type->parameter)) {
            if (!checkOnly)
                value->value_type = type;
            return;
        }

        List& destTypes = *List::checkCast(list_get_type_list_from_type(type));

        // Check for correct number of elements.
        if (sourceLength != destTypes.length()) {
            result->success = false;
            return;
        }

        if (!checkOnly) {
            INCREMENT_STAT(Touch_ListCast);
            list_touch(value);
            value->value_type = type;
        }

        for (int i=0; i < sourceLength; i++) {
            caValue* sourceElement = list_get(value, i);
            Type* expectedType = as_type(destTypes[i]);

            INCREMENT_STAT(Cast_ListCastElement);
            cast(result, sourceElement, expectedType, checkOnly);

            if (!result->success)
                return;
        }
    }
Exemple #8
0
void for_loop_finish_iteration(Stack* stack, bool enableLoopOutput)
{
    INCREMENT_STAT(LoopFinishIteration);

    Frame* frame = top_frame(stack);
    Branch* contents = frame->branch;

    // Find list length
    caValue* listInput = get_frame_register(frame, 0);

    // Increment the loop index
    caValue* index = get_top_register(stack, for_loop_find_index(contents));
    set_int(index, as_int(index) + 1);

    // Preserve list output
    if (enableLoopOutput && frame->exitType != name_Discard) {
        caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));

        Term* outputPlaceholder = get_output_placeholder(contents, 0);
        caValue* outputList = get_frame_register(frame, outputPlaceholder);
        caValue* outputValue = find_stack_value_for_term(stack, outputPlaceholder->input(0), 0);

        if (!is_list(outputList))
            set_list(outputList);
        list_touch(outputList);
        copy(outputValue, list_get(outputList, as_int(outputIndex)));

        INCREMENT_STAT(LoopWriteOutput);

        // Advance output index
        set_int(outputIndex, as_int(outputIndex) + 1);
    }

    // Check if we are finished
    if (as_int(index) >= list_length(listInput)
            || frame->exitType == name_Break
            || frame->exitType == name_Return) {

        // Possibly truncate output list, in case any elements were discarded.
        if (enableLoopOutput) {
            caValue* outputIndex = get_frame_register(frame, for_loop_find_output_index(contents));
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            list_resize(outputList, as_int(outputIndex));
        } else {
            Term* outputPlaceholder = get_output_placeholder(contents, 0);
            caValue* outputList = get_frame_register(frame, outputPlaceholder);
            set_list(outputList, 0);
        }
        
        finish_frame(stack);
        return;
    }

    // If we're not finished yet, copy rebound outputs back to inputs.
    for (int i=1;; i++) {
        Term* input = get_input_placeholder(contents, i);
        if (input == NULL)
            break;
        Term* output = get_output_placeholder(contents, i);
        copy(get_frame_register(frame, output),
            get_frame_register(frame, input));

        INCREMENT_STAT(Copy_LoopCopyRebound);
    }

    // Return to start of loop body
    frame->pc = 0;
    frame->nextPc = 0;
    frame->exitType = name_None;
}
Exemple #9
0
void
List::set(int index, caValue* value)
{
    list_touch(this);
    copy(value, list_get(this, index));
}
Exemple #10
0
 void tv_touch(caValue* value)
 {
     ca_assert(is_list(value));
     ListData* data = (ListData*) get_pointer(value);
     set_pointer(value, list_touch(data));
 }
Exemple #11
0
 void tv_set_index(caValue* value, int index, caValue* element)
 {
     ca_assert(is_list(value));
     list_touch(value);
     copy(element, list_get(value, index));
 }
Exemple #12
0
void list_touch(caValue* list)
{
    list->value_data.ptr = (ListData*) list_touch((ListData*) list->value_data.ptr);
}