Beispiel #1
0
def insert_table_record(constructor, key, value):
    array = constructor.array.contents
    records = constructor.records.contents

    if isinstance(key, nodes.MULTRES):
        assert len(records) == 0 or\
            isinstance(records[-1], nodes.TableRecord)

        records.append(value)
        return

    while isinstance(key, nodes.Constant) and\
            key.type == key.T_INTEGER and\
            key.value >= 0:
        index = key.value

        if index == 1 and len(array) == 0:
            record = nodes.ArrayRecord()
            record.value = nodes.Primitive()
            record.value.type = nodes.Primitive.T_NIL

            array.append(record)

        if (index > len(array)):
            break

        record = nodes.ArrayRecord()
        record.value = value

        if len(array) == 0 or index == len(array):
            array.append(record)
        else:
            array[index] = record

        return

    record = nodes.TableRecord()
    record.key = key
    record.value = value

    if len(records) == 0:
        records.append(record)
        return

    last = records[-1]

    if isinstance(last, (nodes.FunctionCall, nodes.Vararg)):
        records.insert(-1, record)
    else:
        records.append(record)
Beispiel #2
0
def _build_table_copy(state, slot):
    node = nodes.TableConstructor()

    table = state.constants.complex_constants[slot]

    i = 0

    for value in table.array:
        record = nodes.ArrayRecord()
        record.value = _build_table_record_item(value)

        node.array.contents.append(record)

        i += 1

    for key, value in table.dictionary:
        record = nodes.TableRecord()
        record.key = _build_table_record_item(key)
        record.value = _build_table_record_item(value)

        node.records.contents.append(record)

    return node
Beispiel #3
0
def insert_table_record(constructor,
                        key,
                        value,
                        replace,
                        allow_duplicates=True):
    array = constructor.array.contents
    records = constructor.records.contents

    if isinstance(key, nodes.MULTRES):
        assert len(records) == 0 \
               or isinstance(records[-1], nodes.TableRecord)

        records.append(value)
        return True

    while isinstance(key, nodes.Constant) \
            and key.type == key.T_INTEGER \
            and key.value >= 0:
        index = key.value

        if index == 1 and len(array) == 0:
            record = nodes.ArrayRecord()
            record.value = nodes.Primitive()
            record.value.type = nodes.Primitive.T_NIL

            array.append(record)

        if index > len(array):
            break

        record = nodes.ArrayRecord()
        record.value = value

        if len(array) == 0 or index == len(array):
            array.append(record)
            return True
        elif replace:
            array[index] = record
            return True
        else:
            current_value = array[index].value
            if isinstance(current_value, nodes.Primitive
                          ) and current_value.type == nodes.Primitive.T_NIL:
                array[index] = record
                return True
            return False

    # Check for record duplicates
    # This isn't nearly as important as duplicate protection with arrays, since both values
    # end up in the table to the user can make sense of what happened. Nonetheless, we should still
    # reject stuff like this.
    if not allow_duplicates:
        for rec in records:
            if isinstance(rec, nodes.TableRecord):
                if is_equal(rec.key, key, strict=False):
                    return False

    record = nodes.TableRecord()
    record.key = key
    record.value = value

    if len(records) == 0:
        records.append(record)
        return True

    last = records[-1]

    if isinstance(last, (nodes.FunctionCall, nodes.Vararg)):
        records.insert(-1, record)
    else:
        records.append(record)

    return True