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 visit_table_constructor(self, node):
        self._write("{")

        if len(node.records.contents) + len(node.array.contents) > 0:
            self._end_line()

            self._start_block()

            array = node.array.contents
            records = node.records.contents

            all_records = nodes.RecordsList()
            all_records.contents = array + records

            if len(array) > 0:
                first = array[0].value

                all_records.contents.pop(0)

                if not isinstance(first, nodes.Primitive) \
                  or first.type != first.T_NIL:
                    record = nodes.TableRecord()
                    record.key = nodes.Constant()
                    record.key.type = nodes.Constant.T_INTEGER
                    record.key.value = 0
                    record.value = first

                    all_records.contents.insert(0, record)

            self._visit(all_records)

            self._skip(node.array)
            self._skip(node.records)

            self._end_block()
        else:
            self._skip(node.array)
            self._skip(node.records)

        self._write("}")
Beispiel #3
0
    def visit_table_constructor(self, node):
        self._write("{")

        # These are both delt with in the contents array, no need to visit them separately
        self._skip(node.array)
        self._skip(node.records)

        contents = node.array.contents + node.records.contents

        if len(node.array.contents) > 0:
            # Since we're using array+records in that order, the first
            #  array item is also the first combined item.
            first = contents.pop(0).value

            if not isinstance(first,
                              nodes.Primitive) or first.type != first.T_NIL:
                record = nodes.TableRecord()
                record.key = nodes.Constant()
                record.key.type = nodes.Constant.T_INTEGER
                record.key.value = 0
                record.value = first

                contents.insert(0, record)

        if len(contents) == 1 and False:
            # TODO enable as part of a TdlQ-emulation option
            self._visit(contents[0])
        elif len(contents) > 0:
            self._end_line()

            self._start_block()

            all_records = nodes.RecordsList()
            all_records.contents = contents

            self._visit(all_records)

            self._end_block()

        self._write("}")
Beispiel #4
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 #5
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