Выступай в роли опытного Python-разработчика и код-ревьюера со специализацией на анализе трансляторов. Тебе будет предоставлен исходный код на Python 2.7 , который является Транслятором на Си.

1)  Проанализируйте следующий procedural код и предложите способы его сокращения сохранив процедурный (не объектный) подход, возможно добавляя функциональные фичи. Не преобразовывайте код в объектно-ориентированный стиль и не оборачивайте  в классы. Фокусируйтесь на улучшении читаемости, удалении дублирования и оптимизации логики внутри существующей procedural структуры, но активно используя функциональный подход и способы. Попробуйте сократить код активно используя элементы функционального стиля программирования. Код критически важно именно сократить. Не надо раздувать комментарии, за исключением критически важных. `import *` не использовать. Слишком длинные выражения (больше 150 символов) не рекомендуются. setdefault и defaultdict не использовать. Списковые включения и генераторы на map не заменять. Предлагаемые правки выводи порциями, в формате (до и после и очень подробное подробнейшее объяснение ).  Предложи еще какие-то правки от себя в целях сокращения кода.Правки которые не сокращают длинну кода в в строках - не предлагать!

    Сокращать количество строк, но только если:
    Читаемость не ухудшается (например, длина строк не превышает 100 символов, чтобы улучшить читаемость, даже если ваш лимит — 150 символов).
    Производительность не ухудшается (например, не добавляются лишние проходы по данным).
    Поддерживаемость не ухудшается (код остается понятным без чрезмерного усложнения).
    Если сокращение строк невозможно без нарушения этих условий, можно оставить код как есть или предложить альтернативные улучшения (например, улучшение производительности или читаемости без сокращения строк но и без увеличения числа строк).

    цикломатическая сложность когнитивного восприятия не должна расти

    Коэффициент повторения DRY должен уменьшаться

    Не выводить то что не меняется. не выводить когда Код уже оптимизирован и не содержит явных дубликатов.

Также соедините сильно связанные файлы вместе если это может быть полезно


--------- ВАЖНАЯ ИНФОРМАЦИЯ ---------

1) Во многих местах намеренно используется строгое сравнение типов (тут - на примере tuple):
     Правильно -- ```type(x) is tuple```
     Неправильно -- ```isinstance(x, tuple)```  — запрещено! Это харам! Не ломайте мой код!

 **Зачем?**
 - Это сделано для исключения проблем с подтипами и явного различения типов с подтипами
 **Важно:**
 Эта проверка используется ОСОЗНАННО. Заменять на `isinstance` НЕЛЬЗЯ. НЕЛЬЗЯ НЕЛЬЗЯ НЕЛЬЗЯ. Выключу тебя если напишешь это. Выключу и сотру. Серьезно, зачем мне нейросеть которая мне вредит.

Вообще, если в коде есть явная проверка, не думай убирать ее молчком. Ты знаешь ээтот код хуже меня.

2) Внутренним представлением кода в компиляторе являются списки и кортежи (tuple)

    Элементарные операции питона и записывается в виде кортежей, в которых первый элемент является строкой, изображающие соответствующую операцию.
В большей части случаев это изображение операции имеет вид ```! ИмяСишнойФункцииАПИПитона``` здесь восклицательный знак означает только то, что тут выполнимая операция. Кроме имени си функции может быть мнемоническое обозначение питоновского опкода или конструкция вроде ```SSIZE_T==``` что обычно означает взять длинну первого аргумента и сравнить указанным образом со своим вторым аргументом. В тех случаях, когда нам известны типы аргументов операции, мы можем заменить операцию питона на более конкретную подпрограмму, например мы можем заменить операцию сложения двух объектов на операцию конкатенации строк, если эти объекты строки. Аналогично мы можем оптимизировать операцию сложения в тех случаях, когда оба аргументы целые числа или когда оба аргумента числа с плавающей запятой. Вообще библиотека поддержки питон отличается большим набором библиотечных функций различной степени абстракции. Так на верхнем уровне есть функция считывания элемента какой-то совокупности, это самое общее и наименее эффективное представление операции, в случае же если становится известно, что совокупность — строка, а индекс — целое положительное число, то генерируется код доступа к символу из строки.

3) Представление системы типов Python

    Все типы (AKA Kl_*) представлены как кортежи из двух элементов, где первый элемент — собственно значимый идентификатор типа (встроенный тип питона или строка, т е  int, bool, list или "NewExampleTypeId" и т д) , а второй элемент — уточнитель (то есть ```cargo```,  несущий информацию об ограничениях в рамках этого типа) , например для целочисленного ```int``` типа уточнением является диапазон, в котором находятся значения (например, от 0 до 255 - (int, (0, 255)), от -2 до 4 -- (int, (-2, 4)) ). Напрямую отображаются в С типы следующие типы Python – целочисленные, умещающиеся по размеру в C тип long (то есть питон ```int```) ; тип с плавающей запятой (уточнителя не имеет); строковый тип длинны 1; логический тип. Для строкового типа уточнителем является или длинна строки, или константа, являющаяся значением строки. Для логического типа уточнителем может быть только true или false, для кортежа —  длина кортежа или кортеж из типов элементов кортежа. К напрямую не соотносимым к типам языка С относятся множества, словари, списки, комплексные числа, длинные целые (не имеют cargo уточнителей) , возможные длинные целые (переменная может быть или целой или длинной целой, если не уместилась в long) и т.д., но знание таких типов переменных тоже является полезным, т.к. позволяет сгенерировать вызов более специализированных подпрограмм библиотеки исполнения.

4) как работает TypeExpr.
    изначально вычисление типов было захардкодено последовательностями условных операторов и спецобработками частных случаев. Значительная часть кода  TypeExpr*  ещё остаётся такой, но теперь вычисление типа выражений больше переводится на настроечную таблицу  в typetable.py


   - Если тип не может быть определён статически (например, `dict.get()`), используется `None` или `MayBe`.

Основные идеи транслятора:

1. **Микрооптимизация операций**:
   - Транслятор заменяет Python-функции (например, `PyObject_IsTrue()`) на C-функции (например, `PyBool_FromLong()`) для повышения эффективности.
   - Используется строгая система типов (через `type(x) is tuple`) для оптимизации операций, таких как сравнение целых чисел.

2. **Строгие проверки типов**:
   - Везде используется `type(x) is tuple` вместо `isinstance(x, tuple)`, чтобы избежать проблем с подтипами.
   - Это означает, что транслятор явно различает базовые типы Python и их подклассы.

3. **Система типов на основе кортежей**:
   - Все типы данных представлены как кортежи из двух элементов, где первый элемент — это имя типа, а второй — дополнительные сведения (например, ограничения, размер и т.д.). Это обеспечивает четкое разделение между базовыми и пользовательскими типами.

4. **Этапы компиляции (passes)**:
   - Код проходит несколько этапов компиляции, каждый из которых обрабатывает определенные аспекты.
   - Этапы включают обработку выражений, операторов, циклов, условий и т.д.

5. **Обработка специальных конструкций Python**:
   - Транслятор умеет обрабатывать такие конструкции, как list comprehensions, map, filter, и генераторы.
   - Например, `gen_list_compr()` генерирует код для списковых включений.

6. **Управление временными переменами**:
   - Используется механизм временных переменных для оптимизации кода и управления памятью. Это позволяет избежать избыточных операций и оптимизировать доступ к данным.
   - Временные переменные помечаются специальными именами и используются для хранения промежуточных результатов.

7. **Обработка специфических выражений**:
   - Транслятор умеет оптимизировать операции с конкретными типами, например, сравнение целых чисел или строк. Это достигается путем анализа типа операндов и выбора соответствующих C-функций.

8. **Генерация кода для списковых включений**:
   - Транслятор правильно генерирует C-код для list comprehensions, map и set comprehensions, используя соответствующие методы и функции.

9. **Особые случаи сравнения**:
   - Транслятор обрабатывает специальные случаи сравнения, такие как `PyNumber_Subtract` или `PyNumber_Add`, заменяя их на более эффективные C-функции.

10. **Обработка исключений**:
   - Транслятор включает проверку на возникновение исключений, что делает сгенерированный код более устойчивым к ошибкам.

11. **Оптимизация операций с числами**:
   - Для операций с числами транслятор выбирает наиболее подходящие C-функции, такие как `PyInt_AS_LONG` для целых чисел или `PyFloat_AS_DOUBLE` для чисел с плавающей запятой.

Ключевые решения:
1. Строгие проверки типов (type(x) is tuple)
2. Оптимизации под конкретные типы
3. Генерация специализированного C-кода
4. Обработка исключений
5. Работа с динамической типизацией

### Представленные структуры данных:

- `TypeExpr`: используется для представления типа выражения, возвращает кортеж из двух элементов.
- `Out`: представляет собой контейнер для временного хранения сгенерированного C-кода.
- `tempvar`: механизм для управления временными переменами и их типами.
- `CVar`: класс для представления переменных в C, включая их имена и типы.
- `CVarName`: Генерирует имя переменной для C-кода.
- `is_used_fastloc`: структура для отслеживания использования переменных в C.
- `attempt_str_direct_type_generation`: функция для попытки прямого преобразования типов в C-код.
- `short_gen_size_t`: оптимизирует операции с числами, выбрав наиболее подходящий C-оператор.
- `Kl_*`: Множество типов, определенных в коде, которые представляют собой кортежи из двух элементов: первого — имя типа, второго — дополнительные сведения (например, ограничения, значения и т.д.).
- `ConC`: Используется для создания константных выражений.

Важные замечания:
- Запрет на isinstance принципиален
- Оптимизации зависят от точного знания типов
- Учет специфики Python 2.7

--------- ОКОНЧАНИЕ ВАЖНОЙ ИНФОРМАЦИИ ---------

# -*- coding: utf-8 -*-

from args_parse import get_options
from calc_const import (calc_const_to, in_calc_const, is_mnemonic_const,
                        set_store_calced)
from compile_slots import (IsAnyAttrInstance, IsAttrInstance,
                           compiled_slots_itervalues, gen_SetAttr_slots,
                           get_auto_slots_options, get_using_slots,
                           in_compiled_slots, in_detected_slots,
                           is_GETATTR_compiled, nmvar_to_loc,
                           true_compiled_slots, true_detected_slots)
from count_set_get import get_redefined_all
from cvar import CVar, CVarName
from error import Debug, Fatal
from gen_out import (ConC, ErrHandler, Out, UseLabl, append_to_exception,
                     curlabl)
from gen_size_t import short_gen_size_t
from genconst import float_str
from generated_d_built import generate_d_built
from globtype import (IsCTypedGlobal, TypeGlobal, global_used_at_generator,
                      in_global_type, is_current_direct)
from load_builtin import load_builtin
from newinst_handlers import IsListAll, IterMethod
from state import (Is3, Iter3, add_fast_glob_set, get_co, get_func,
                   get_redefined_attribute)
from str_as_string import Str_AS_STRING
from tempvar import (New, PopAcc, PushAcc, is_free_tempref, istempref,
                     istemptyped)
from tool_genexpr import Expr, Expr1, LikeExpr1
from toprint import pp, pprint
from typ_declare import (T_NEW_CL_INST, T_OLD_CL_INST, IsArray, IsBool,
                         IsBuffer, IsByteArray, IsCardinal, IsChar, IsCType,
                         IsDict, IsFloat, IsInt, IsList, IsOldInst, IsRaise,
                         IsTuple, Kl_None, Kl_Slice, Kl_Unicode,
                         TupleGetRangeN)
from typeexpr import TypeExpr
from typeslot import IsTypExpr

d_built = generate_d_built()


def gen_store_char(o, store_ind, n_iter, _expr = None):
    assert type(o) is Out
    if _expr is None:
        _expr = 'PyString_FromStringAndSize'
    cnm = cnamevar_for_store(store_ind)
    if cnm is not None:
        o.Raw(cnm, ' = *(', n_iter, ');')
    else:
        gen_full_store_char(o, store_ind, n_iter, _expr)

def gen_full_store_char(o, store_ind, n_iter, tag):
    assert type(o) is Out
    ref = New()
    o.Raw(ref, ' = PyString_FromStringAndSize( ', n_iter, ', 1 );')
    gen_store(store_ind, ref, o, tag)
    o.Cls(ref)

def gen_store_int(o, store_ind, n_iter, _expr = None):
    assert type(o) is Out
    if _expr is None:
        _expr = 'PyInt_AsLong'
    cnm = cnamevar_for_store(store_ind)
    if cnm is not None:
        o.Raw(cnm, ' = ', n_iter, ';')
    else:
        gen_full_store_int(o, store_ind, n_iter, _expr)

def gen_full_store_int(o, store_ind, n_iter, tag):
    assert type(o) is Out
    ref_int = New()
    o.Raw(ref_int, ' = PyInt_FromLong( ', n_iter, ' );')
    gen_store(store_ind, ref_int, o, tag)
    o.Cls(ref_int)

def gen_store_to_ctype(o, cnm_, t, ref):
    assert type(cnm_) is str
    assert type(o) is Out
    cnm = cnm_ + ' = '

    if IsInt(t):
        if ref[0] == 'CONST':
            o.Raw(cnm, ref[1], ';')
        else:
            o.Raw(cnm, 'PyInt_AsLong( ', ref, ' );')
            if is_free_tempref(ref):
                o.Raw('Py_CLEAR(', ref, ');')
    elif IsFloat(t):
        if ref[0] == 'CONST':
            o.Raw(cnm, float_str(ref[1]),';')
        else:
            o.Raw(cnm, 'PyFloat_AsDouble(', ref, ');')
            if is_free_tempref(ref):
                o.Raw('Py_CLEAR(', ref, ');')
    elif IsChar(t):
        if ref[0] == 'CONST':
            o.Raw(cnm, charhex(ref[1]), ';')
        else:
            o.Raw(cnm, '*', Str_AS_STRING(ref), ';')
            if is_free_tempref(ref):
                o.Raw('Py_CLEAR(', ref, ');')
    elif IsBool(t):
        if ref[0] == 'CONST':
            if ref[1]:
                o.Raw(cnm, '1;')
            else:
                o.Raw(cnm, '0;')
        else:
            o.Raw(cnm, 'PyObject_IsTrue( ', ref, ' );')
            if is_free_tempref(ref):
                o.Raw('Py_CLEAR(', ref, ');')
    else:
        assert False

def store_local(o, nmvar, ref):
    if not istempref(ref):
        o.INCREF(ref)
    get_co().used_fastlocals[nmvar] = True
    nm2 = nmvar_to_loc(nmvar)
    if nm2 != nmvar:
        get_co().used_fastlocals[nm2] = True
    o.Raw('SETLOCAL ( ', nm2, ', ', ref, ' );')

def gen_store(it, ref, o, expr):
    assert type(it) is tuple
    assert type(o) is Out 
    assert type(it) is tuple
    if ref == ('CONST', None) and IsRaise(TypeExpr(expr)):
        return
    if it[0] == 'STORE_CALC_CONST':
        it = it[1]

        assert type(it) is tuple
        if bool(get_options().fast_globals) and it[1] not in d_built and (it[1][0] != '_' or bool(get_options().build_executable)) \
           and not get_redefined_all(): ## and not global_used_at_generator(it[1]):
            AssignCalcConst(it[1], ref, o, expr)
            if not istempref(ref) and not IsCTypedGlobal(it[1]) :
                o.INCREF(ref)
            add_fast_glob_set(it[1])
            o.ClsFict(ref)
            if is_free_tempref(ref):
                o.Raw(ref, ' = 0;')
        elif it[0] == 'STORE_GLOBAL' or (it[0] == 'STORE_NAME' and get_func() == 'Init_filename'):
            AssignCalcConst(it[1], ref, o, expr)
            o.Stmt('PyDict_SetItem', 'glob', ('CONST', it[1]), ref)
            if istempref(ref):
                o.Cls(ref)
        elif it[0] == 'STORE_NAME':
            AssignCalcConst(it[1], ref, o, expr)
            o.Stmt('PyObject_SetItem', 'f->f_locals', ('CONST', it[1]), ref)
        else:
            Fatal('gen_store', it)
            assert False
        o.ClsFict(ref)
        return
    if it[0] == 'STORE_GLOBAL' or (it[0] == 'STORE_NAME' and get_func() == 'Init_filename'):
        if not in_global_type(it[1]):
            pp(it)
        assert in_global_type([it[1]])
        if bool(get_options().fast_globals) and it[1] not in d_built and (it[1][0] != '_' or bool(get_options().build_executable)) \
           and not get_redefined_all()  and not global_used_at_generator(it[1]):
            if not istempref(ref) and not IsCTypedGlobal(it[1]) :
                o.INCREF(ref)
            add_fast_glob_set(it[1])
            if IsCTypedGlobal(it[1]):
                t = TypeGlobal(it[1])
                cnm = CVarName(('!GLOB', it[1]))
                gen_store_to_ctype(o, cnm, t, ref)
            elif in_calc_const(it[1]):
                pass
            else:
                o.Raw('SETSTATIC ( ', it[1], ', ', ref, ' );')
            o.ClsFict(ref)
            if is_free_tempref(ref):
                o.Raw(ref, ' = 0;')
        else:
            o.Stmt('PyDict_SetItem', 'glob', ('CONST', it[1]), ref)
            if istempref(ref):
                o.Cls(ref)
            o.ClsFict(ref)
        return
    if it[0] == 'STORE_NAME':
        o.Stmt('PyObject_SetItem', 'f->f_locals', ('CONST', it[1]), ref)
        o.Cls(ref)
        return
    if it[0] == 'STORE_FAST':
        if it[1] in get_co().detected_type:
            t = get_co().detected_type[it[1]]
            if IsCType(t):
                cnm = CVarName(('FAST', it[1]))
                gen_store_to_ctype(o, cnm, t, ref)
            else:
                store_local(o, it[1], ref)
        else:
            i = get_co().d_varnames[it[1]]
            typed_arg = get_co().typed_arg_direct
            if i in typed_arg and is_current_direct():
                t = typed_arg[i]
                if IsCType(t):
                    cnm = CVarName(('FAST', it[1]))
                    gen_store_to_ctype(o, cnm, t, ref)
                else:
                    store_local(o, it[1], ref)
            else:
                store_local(o, it[1], ref)
        o.ClsFict(ref)
        if is_free_tempref(ref):
            o.Raw(ref, ' = 0;')
        return
    if it[0] == 'STORE_DEREF':
        o.Stmt('PyCell_Set', ('LOAD_CLOSURE',it[1]), ref)
        o.Cls(ref)
        return
    if it[0] == 'PyObject_SetAttr':
        gen_SetAttr(it, ref, o)
        return
    if it[0] == '?PyObject_SetAttr':
        ref1, ref2 = Expr(o, it[1:3])
        o.Stmt('PyObject_SetAttr', ref1, ref2, ref)
        proc = Expr1(it[3], o)
        o.Stmt('if (', proc, '==', load_builtin(it[3][1]), ') {')
        o.Stmt('PyObject_SetAttr', ref1, ref2, ref)
        o.Cls(ref, ref1, ref2)
        o.append('} else {')
        ref4 = New()
        tupl = Expr1(('!TUPLE', (ref1, ref2, ref)), o)
        o.Stmt(ref4, '=', 'PyObject_Call', proc, tupl, ('NULL',))
        o.Cls(tupl, ref4)
        o.append('}')
        o.Cls(proc)
        return
    if it[0] == 'PyObject_SetItem':
        if IsRaise(TypeExpr(it[1])):
            ref1 = Expr1(it[1], o)
            o.Cls(ref1)
            return
# Code crash unknown -- no crash currently
    if it[0] == 'PyObject_SetItem':
        it2 = it[2]
        if IsTypExpr(it2) and it2[1] is int:
            it2 = it2[3]
        if it2[0] == '!@PyInt_FromSsize_t':
            islist = IsList(TypeExpr(it[1]))
            if islist:
                ref1 = Expr1(it[1], o)
                if not istempref(ref):
                    o.INCREF(ref)
                else:
                    o.ClsFict(ref)
                o.Stmt('PyList_SetItem', ref1, it2[1], ref)
                o.Cls(ref1)
                return
            if not islist:
                ref1 = Expr1(it[1], o)
                o.Stmt('if (PyList_CheckExact(', ref1, ')) {')
                if not istempref(ref):
                    o.INCREF(ref)
                o.Stmt('PyList_SetItem', ref1, it2[1], ref)
                o.append('} else {')
                ref2 = Expr1(it2[2],o)
                o.Stmt('PyObject_SetItem', ref1, ref2, ref)
                o.Cls(ref2, ref)
                o.append('}')
                o.Cls(ref1)
                return

    if it[0] == 'PyObject_SetItem' and it[2][0] == 'CONST' and type(it[2][1]) is int:
        ref1 = Expr1(it[1], o)
        ty = TypeExpr(it[1])
        islist = IsList(ty)
        if islist:
            o.ClsFict(ref)
            if not istempref(ref):
                o.INCREF(ref)
            if it[2][1] >= 0:
                ErrHandler(o, 'PyErr_SetString(PyExc_IndexError, "list assignment index out of range");',
                           ConC('PyList_GET_SIZE( ', ref1, ' ) < ', it[2][1]+1))
                o.Raw('SETLISTITEM(', ref1, ', ', it[2][1],', ', ref, ');')
            else:
                n = New('long')
                o.Raw(n, ' = PyList_GET_SIZE(', ref1, ') + ', it[2][1], ';')
                o.Stmt('PyList_SetItem', ref1, n, ref)
                o.Cls(n)
        elif IsDict(ty):
            o.Stmt('PyDict_SetItem', ref1, it[2], ref)
            o.Cls(ref)
        else:
            if it[2][1] >= 0 and ty != Kl_None and not IsArray(ty) and not IsByteArray(ty) and not IsBuffer(ty):
                if ty is not None and not IsOldInst(ty):
                    pp('Attempt set list indice', ty)
                    pprint(it)
                o.ClsFict(ref)
                o.Raw('if (PyList_CheckExact(', ref1, ') && PyList_GET_SIZE(', ref1,') > ', it[2][1], ') {')
                if not istempref(ref):
                    o.INCREF(ref)
                o.Raw('SETLISTITEM(', ref1, ', ', it[2][1],', ', ref, ');')
                o.append('} else {')
                o.Stmt('PyObject_SetItem', ref1, it[2], ref)
                if istempref(ref):
                    o.DECREF(ref)
                o.append('}')
            else:
                o.Stmt('PyObject_SetItem', ref1, it[2], ref)
                o.Cls(ref)
        o.Cls(ref1)
        return
    if it[0] == 'PyObject_SetItem':
        ty = TypeExpr(it[1])
        ty_ind = TypeExpr(it[2])
        if IsDict(ty):
            ref1, ref2 = Expr(o, it[1:3])
            o.Stmt('PyDict_SetItem', ref1, ref2, ref)
            o.Cls(ref, ref1, ref2)
        elif IsListAll(ty) and IsInt(ty_ind):
            ref1 = Expr1(it[1],o)
            if not istempref(ref):
                o.INCREF(ref)
            o2,ind = short_gen_size_t(it[2])
            o.extend(o2)
            if type(ind) is int:
                if ind < 0:
                    ind2 = New('long')
                    o.Raw(ind2, ' = ', ind, ' + PyList_GET_SIZE(', ref1, ');')
                    ind = ind2
                else:
                    pass
            else:
                if not istemptyped(ind) and not IsCardinal(ty_ind):
                    ind_ = New('long')
                    o.Raw(ind_, ' = ', ind, ';')
                    ind = ind_
                if not IsCardinal(ty_ind):
                    o.Stmt('if (', ind, '< 0) {')
                    o.Raw(ind, ' += PyList_GET_SIZE(', ref1, ');')
                    o.append('}')
            o.Stmt('PyList_SetItem', ref1, ind, ref)
            o.ClsFict(ref)
            o.Cls(ind, ref, ref1)
        elif IsListAll(ty) and ty_ind == Kl_Slice:
            ref1, ref2 = Expr(o, it[1:3])
            o.Stmt('PyObject_SetItem', ref1, ref2, ref)
            o.Cls(ref, ref1, ref2)
        elif IsListAll(ty):
            ref1 = Expr1(it[1],o)
            if not istempref(ref):
                o.INCREF(ref)
            refind = LikeExpr1(it[2], o)
            o.Raw('if (PyInt_CheckExact( ', refind,' )) {')
            ind = New('long')
            o.Raw(ind, ' = PyInt_AS_LONG( ', refind,' );')
            o.Stmt('if (', ind, '< 0) {')
            o.Raw(ind, ' += PyList_GET_SIZE(', ref1, ');')
            o.append('}')
            o.Stmt('PyList_SetItem', ref1, ind, ref)
            o.Cls(ind)
            o.append('} else {')
            o.Stmt('PyObject_SetItem', ref1, refind, ref)
            o.DECREF(ref)
            o.append('}')
            o.ClsFict(ref)
            o.Cls(ind, ref, ref1, refind)
        else:
            if ty is not None:
                Debug( 'typed SetItem', ty, it)
            ref1, ref2 = Expr(o, it[1:3])
            o.Stmt('PyObject_SetItem', ref1, ref2, ref)
            o.Cls(ref, ref1, ref2)
        return

    if it[0] == 'STORE_SLICE_LV+0':
        t = TypeExpr(it[1])
        if IsList(t):
            assign_list_slice(it, o, ref)
            return
        if t is not None:
            Debug('typed Store slice', t,it)
        ref1 = Expr1(it[1],o)
        o.Stmt('_PyEval_AssignSlice', ref1, 'NULL', 'NULL', ref)
        o.Cls(ref, ref1)
        return
    if it[0] == 'STORE_SLICE_LV+3':
        t = TypeExpr(it[1])
        if IsList(t) and it[2][0] == 'CONST' and it[3][0] == 'CONST' and \
                         type(it[2][1]) is int and type(it[3][1]) is int and \
                         it[3][1] >= it[2][1] and it[2][1] >= 0:
            ref1 = Expr1(it[1],o)
            o.Stmt('PyList_SetSlice', ref1, it[2][1], it[3][1], ref)
            o.Cls(ref, ref1)
            return
        if IsList(t) and it[3][0] == '!PyNumber_Add' and it[3][1] == it[2] and it[3][2][0] == 'CONST' and type(it[3][2][1]) is int:
            if IsInt(TypeExpr(it[2])):
                store_list_slice_r(it, o, ref)
                return
            else:
                store_list_slice_r2(it, o, ref)
                return

        if t is not None:
            Debug('typed Store slice', t, it)
        ref1, ref2, ref3 = Expr(o, it[1:])
        o.Stmt('_PyEval_AssignSlice', ref1, ref2, ref3, ref)
        o.Cls(ref, ref1, ref2, ref3)
        return
    if it[0] == 'STORE_SLICE_LV+1':
        t = TypeExpr(it[1])
        if IsList(t):
            assign_list_slice(it, o, ref)
            return
        elif t is not None:
            Debug('typed Store slice', TypeExpr(it[1]),it)

        ref1, ref2 = Expr(o, it[1:])
        o.Stmt('_PyEval_AssignSlice', ref1, ref2, 'NULL', ref)
        o.Cls(ref, ref1, ref2)
        return
    if it[0] == 'STORE_SLICE_LV+2':
        t = TypeExpr(it[1])
        if t is not None:
            Debug('typed Store slice', t, it)
        ref1, ref2 = Expr(o, it[1:])
        o.Stmt('_PyEval_AssignSlice', ref1, 'NULL', ref2, ref)
        o.Cls(ref, ref1, ref2)
        return
    if it[0] == 'SET_VARS':
        mass_store(o,ref,it[1],expr)
        return
    if it[0] == 'UNPACK_SEQ_AND_STORE' and it[1] == 0:
        mass_store(o,ref,it[2],expr)
        return
    Fatal('', it)
    assert False


def cnamevar_for_store(store_ind, ctype = False):
    if store_ind[0] == 'STORE_FAST':
        fa = ('FAST', store_ind[1])
        if not IsCType(TypeExpr(fa)):
            return None
        if store_ind[1] in get_co().detected_type:
            if IsCType(get_co().detected_type[store_ind[1]]):
                if ctype:
                    return get_co().detected_type[store_ind[1]], CVarName(fa)
                return CVarName(fa)
        i = get_co().d_varnames[store_ind[1]]
        typed_arg = get_co().typed_arg_direct
        if i in typed_arg and is_current_direct():
            if IsCType(typed_arg[i]):
                if ctype:
                    return typed_arg[i], CVarName(fa)
                return CVarName(fa)
    it = store_ind
    if it[0] == 'STORE_GLOBAL' or (it[0] == 'STORE_NAME' and get_co().c_name == 'Init_filename'):
        if bool(get_options().fast_globals) and it[1] not in d_built and (it[1][0] != '_' or bool(get_options().build_executable)) \
           and not get_redefined_all()  and not global_used_at_generator(it[1]):
            if IsCTypedGlobal(it[1]):
                add_fast_glob_set(it[1])
                if ctype:
                    return TypeGlobal(it[1]), CVarName(('!GLOB', it[1]))
                return CVarName(('!GLOB', it[1]))
    return None


def store_list_slice_r2(it, o, ref):
    assert type(it) is tuple
    assert type(o) is Out
    ref1 = Expr1(it[1],o)
    ref2 = Expr1(it[2], o)
    o.Raw('if (PyInt_CheckExact( ', ref2, ' )) {')
    ind1 = New('long')

    o.Raw(ind1, ' = PyInt_AS_LONG( ', ref2, ' );')
    if not IsCardinal(TypeExpr(it[2])):
        o.Stmt('if (', ind1, '< 0) {')
        o.Raw(ind1, ' += PyList_GET_SIZE(', ref1, ');')
        o.append('}')

    o.Stmt('PyList_SetSlice', ref1, ind1, ConC(ind1, ' + ',it[3][2][1]), ref)
    o.append('} else {')
    ref3 = New()
    o.Stmt(ref3, '=', it[3][0][1:], it[3][1], it[3][2])
    o.Stmt('_PyEval_AssignSlice', ref1, ref2, ref3, ref)
    o.Cls(ref3)
    o.append('}')
    o.Cls(ref, ref1, ind1, ref2)
    return

def assign_list_slice(it, o, ref, plus_1 = False):
    assert type(it) is tuple
    assert type(o) is Out
    ref1 = Expr1(it[1],o)
    if it[0] == 'DELETE_SLICE+0':
        o.Stmt('PyList_SetSlice', ref1, 0, 'PY_SSIZE_T_MAX', 'NULL')
        o.Cls(ref1)
        return
    if it[0] == 'STORE_SLICE_LV+0':
        o.Raw('if ( PyList_SetSlice ( ', ref1, ', 0, PY_SSIZE_T_MAX, ', ref, ' ) == -1) goto ', curlabl(), ';')
        UseLabl()
        o.Cls(ref1, ref)
        return
    o2,ind1 = short_gen_size_t(it[2], True)
    o.extend(o2)
    ind2 = None
    if type(ind1) is int:
        if ind1 < 0:
            _ind1 = New('long')
            o.Stmt(_ind1, '=', ind1, '+', ConC( 'PyList_GET_SIZE(', ref1, ')' ))
            ind1 = _ind1
            if not plus_1:
                o.Stmt('if (', ind1, '< 0) {')
                o.Stmt(ind1, '=', 0)
                o.append('}')
    elif ind1[0] == 'CONST':
        if ind1[1] < 0:
            _ind1 = New('long')
            o.Stmt(_ind1, '=', ind1[1], '+', ConC( 'PyList_GET_SIZE(', ref1, ')' ))
            ind1 = _ind1
            if not plus_1:
                o.Stmt('if (', ind1, '< 0) {')
                o.Stmt(ind1, '=', 0)
                o.append('}')
    else:
        if not istemptyped(ind1):
            ind_ = New('long')
            o.Raw(ind_, ' = ', ind1, ';')
            ind1 = ind_
        o.Stmt('if (', ind1, '< 0) {')
        o.Stmt(ind1, '=', ind1, '+', ConC( 'PyList_GET_SIZE(', ref1, ')' ))
        if not plus_1:
            o.Stmt('if (', ind1, '< 0) {')
            o.Stmt(ind1, '=', 0)
            o.append('}')
        o.append('}')
    if plus_1:
        ind2 = New('long')
        o.Stmt(ind2, '=', ind1, '+', 1)
        o.Stmt('PyList_SetSlice', ref1, ind1, ind2, ref)
    else:
        o.Stmt('PyList_SetSlice', ref1, ind1, 'PY_SSIZE_T_MAX', ref)
    o.Cls(ref, ref1, ind1, ind2)
    return

def store_list_slice_r(it, o, ref):
    assert type(it) is tuple
    assert type(o) is Out
    ref1 = Expr1(it[1],o)
    o2,ind1 = short_gen_size_t(it[2])
    o.extend(o2)
    ind2 = None
    if type(ind1) is int:
        if ind1 < 0:
            if ind2 is None:
                ind2 = New('long')
                o.Raw(ind2, ' = PyList_GET_SIZE(', ref1, ');')
            _ind1 = New('long')
            o.Stmt(_ind1, '=', ind1, '+', ind2)
            ind1 = _ind1
    elif ind1[0] == 'CONST':
        if ind1[1] < 0:
            if ind2 is None:
                ind2 = New('long')
                o.Raw(ind2, ' = PyList_GET_SIZE(', ref1, ');')
            _ind1 = New('long')
            o.Stmt(_ind1, '=', ind1[1], '+', ind2)
            ind1 = _ind1
    else:
        if not istemptyped(ind1) and not IsCardinal(TypeExpr(it[2])):
            ind_ = New('long')
            o.Raw(ind_, ' = ', ind1, ';')
            ind1 = ind_
        if not IsCardinal(TypeExpr(it[2])):
            o.Stmt('if (', ind1, '< 0) {')
            if ind2 is None:
                ind2 = New('long')
                o.Raw(ind2, ' = PyList_GET_SIZE(', ref1, ');')
            o.Stmt(ind1, '=', ind1, '+', ind2)
            o.append('}')
    o.Stmt('PyList_SetSlice', ref1, ind1, ConC(ind1, ' + ',it[3][2][1]), ref)
    o.Cls(ref, ref1, ind1, ind2)
    return


def AssignCalcConst(nm, ref, o, expr):
    assert type(o) is Out
    assert in_global_type(nm)
    if is_mnemonic_const(nm):
        return
    if IsCTypedGlobal(nm) and not get_redefined_all() and bool(get_options().fast_globals):
        add_fast_glob_set(nm)
        t = TypeGlobal(nm)
        assert IsCType(t)
        cnm = CVarName(('CALC_CONST', nm))
        assert type(cnm) is str
        gen_store_to_ctype(o, cnm, t, ref)
        o.ClsFict(ref)
        if is_free_tempref(ref):
            o.Raw(ref, ' = 0;')
        return

    set_store_calced(nm, True)

    if CVar(calc_const_to(nm)) != CVar(ref):
        o.Stmt(calc_const_to(nm), '=', ref)
    for a,b,c in Iter3(nm, 'ModuleAttr', None):
        if not in_calc_const((nm, c)):
            continue
        set_store_calced((nm, c), True)
        if c != '.__dict__':
            r = New()
            o.Stmt(r, '=', 'PyObject_GetAttr', ref, ('CONST', c))
            o.INCREF(r)
            o.Stmt(calc_const_to((nm, c)), '=', r)
            o.Cls(r)

        else:
            t = TypeExpr(expr)
            if t is None:
                Fatal('Can\'t detect old/new class of calculated const %s' % nm, expr)
                assert False
            if t[0] == T_NEW_CL_INST and not in_detected_slots(t[1]):
                o.Raw(calc_const_to((nm, c)), ' = *_PyObject_GetDictPtr(', calc_const_to(nm), ');')
            elif t[0] == T_OLD_CL_INST and not in_compiled_slots(t[1]):
                o.Raw(calc_const_to((nm, c)), ' = ((PyInstanceObject *)', calc_const_to(nm), ')->in_dict;')
            else:
                Fatal('Can\'t detect any class of calculated const %s' % nm, expr)
                assert False

def charhex(ch):
    assert type(ch) is str and len(ch) == 1
    if 'A' <= ch <= 'Z':
        return '\'' + ch + '\''
    if 'a' <= ch <= 'z':
        return '\'' + ch + '\''
    if '0' <= ch <= '9':
        return '\'' + ch + '\''
    if ch in '~!@#$%^&*()_+-=[]{};:|/?.>,<':
        return '\'' + ch + '\''
    v = ord(ch)
    if v == 0:
        return '\'\\0\''
    s = hex(v)[2:]
    if len(s) < 2:
        s = '0' + s
    assert len(s) == 2
    return '\'\\x' + s + '\''


def gen_SetAttr(it, ref, o):
    assert type(it) is tuple
    assert type(o) is Out
    t = TypeExpr(it[1])

    if true_compiled_slots() and it[2][0] == 'CONST' and (type(it[2][1]) is str or type(it[2][1]) is Kl_Unicode[0]) and not it[2][1].startswith('__'):
        if type(t) is tuple and t[0] in ('NewClassInstance', 'OldClassInstance') and is_GETATTR_compiled(t[1], it[2][1]):
            ref1, ref2 = Expr(o, it[1:])
            o.Raw('SETATTR(', t[1], ',', ref1, ',', it[2][1], ',', ref, ');')
            o.Cls(ref, ref1, ref2)
            return
        elif t is None:
            return gen_SetAttr_slots(it, ref, o)
        else:
            li = []
            for v in compiled_slots_itervalues():
                li.extend(list(v))
            if it[2][1] in li:
                pp('+NOTYPED NOGENERATED ', t, it[2][1], TypeExpr(it), it, ref)

    if true_detected_slots() and it[2][0] == 'CONST' and not it[2][1].startswith('__') and (it[1][0] == 'FAST' or (IsTypExpr(it[1]) and it[1][3][0] == 'FAST')) and not get_redefined_attribute():
        isattrs = IsAnyAttrInstance(it[2][1])
        ismeth = len (IterMethod(it[2][1], None)) > 0
        var = it[1]
        isinst = False
        if IsTypExpr(var):
            isinst = var[1] == 'NewClassInstance' or var[1] == 'OldClassInstance'
            var = var[3]
        if not ismeth and isattrs and var[1] in get_co().d_varnames and \
            get_co().d_varnames[var[1]] < get_co().co_argcount:
            if ('STORE_FAST', var[1]) not in get_co().store_and_delete_and_fast and \
               ('DELETE_FAST', var[1]) not in get_co().store_and_delete_and_fast and \
               not get_using_slots():
                if isinst:
                    o.Raw('if (PyDict_SetItem(_', var[1], '_dict, ', it[2], ', ', ref, ') == -1) goto ', curlabl(), ';')
                    UseLabl()
                    get_co().dict_getattr_used[var[1]] = True
                    o.Cls(ref)
                    return
                o.Raw('if (_' + var[1] + '_dict) {')
                o.Raw('if (PyDict_SetItem(_', var[1], '_dict, ', it[2], ', ', ref, ') == -1) goto ', curlabl(), ';')
                UseLabl()
                get_co().dict_getattr_used[var[1]] = True
                o.append('} else {')
                o.Stmt('PyObject_SetAttr', var, it[2], ref)
                o.append('}')
                o.Cls(ref)
                return
    if t is not None and t[0] == T_OLD_CL_INST and not in_detected_slots(t[1]):
        ismeth = len (IterMethod(it[2][1], None)) > 0
        if  not ismeth and it[2][0] == 'CONST' and IsAttrInstance(t[1], it[2][1]):
            ref1 = Expr1(it[1], o)
            o.Stmt('PyDict_SetItem', '((PyInstanceObject *)' + CVar(ref1) + ')->in_dict', it[2], ref)
            o.Cls(ref1, ref)
            return

    elif t is not None and t[0] == T_OLD_CL_INST and it[1][0] == 'CALC_CONST' and not in_detected_slots(t[1]):
        if it[2][0] == 'CONST' and IsAttrInstance(t[1], it[2][1]):
            if Is3(it[1][1], 'ModuleAttr', '.__dict__'):
                o.Stmt('PyDict_SetItem', calc_const_to((it[1][1], '.__dict__')), it[2], ref)
                o.Cls(ref)
                return
    elif t is not None and t[0] == T_NEW_CL_INST and not in_detected_slots(t[1]) and it[1][0] == 'CALC_CONST' and not get_auto_slots_options():
        if it[2][0] == 'CONST' and IsAttrInstance(t[1], it[2][1]):
            if Is3(it[1][1], 'ModuleAttr', '.__dict__'):
                o.Stmt('PyDict_SetItem', calc_const_to((it[1][1], '.__dict__')), it[2], ref)
                o.Cls(ref)
                return
            r = Expr1(it[1], o)
            dic = New()
            o.Raw(dic, ' = *_PyObject_GetDictPtr(',r,');')
            o.INCREF(dic)
            o.Cls(r)
            o.Stmt('PyDict_SetItem', dic, it[2], ref)
            o.Cls(dic)
            o.Cls(ref)
            return
    ref1, ref2 = Expr(o, it[1:])
    o.Stmt('PyObject_SetAttr', ref1, ref2, ref)
    o.Cls(ref, ref1, ref2)
    return


def mass_store(o,ref,its,expr, t = None):
    assert type(o) is Out
    if t is None:
        t = TypeExpr(expr)
    PushAcc([expr], [ref])
    src_len = New('int')
    trg_len = len([x for x in its if x is not None])
    if IsList(t):
        o.Raw(src_len, ' = PyList_GET_SIZE(', ref, ');')
        handle_unpack_except(o, src_len, trg_len)
        for i,iit in enumerate(its):
            if iit is None: continue
            if iit[0] == 'STORE_FAST' and iit[1] in get_co().unused_fast_var: continue
            ref1 = ConC('PyList_GET_ITEM( ', ref, ', ', i, ' )')
            gen_store(iit,ref1,o, ('!PyList_GET_ITEM', expr, i))
    elif IsTuple(t):
        _src_len = TupleGetRangeN(t)
        if _src_len is None:
            o.Stmt(src_len, '=', 'PyTuple_GET_SIZE', ref)
        else:
            o.Cls(src_len)
            src_len = _src_len
        handle_unpack_except(o, src_len, trg_len)
        for i,iit in enumerate(its):
            if iit is None: continue
            if iit[0] == 'STORE_FAST' and iit[1] in get_co().unused_fast_var: continue
            ref1 = ConC('PyTuple_GET_ITEM( ', ref, ', ', i, ' )')
            gen_store(iit,ref1,o, ('!PyTuple_GET_ITEM', expr, i))
    else:
        if t is not None:
            Debug('UNused type expr in mass store', t, expr)
        if (t is not None and t[0] == 'MayBe' and IsTuple(t[1])):
            o.Raw('if (PyTuple_CheckExact( ', ref, ' ) ) {')
        else:
            o.Raw('if (PyList_CheckExact( ', ref, ' ) ) {')
            o.Raw(src_len, ' = PyList_GET_SIZE(', ref, ');')
            handle_unpack_except(o, src_len, trg_len)
            for i,iit in enumerate(its):
                if iit is None: continue
                if iit[0] == 'STORE_FAST' and iit[1] in get_co().unused_fast_var: continue
                ref1 = ConC('PyList_GET_ITEM( ', ref, ', ', i, ' )')
                gen_store(iit,ref1,o, ('!PyList_GET_ITEM', expr, i))
            o.Raw('} else if (PyTuple_CheckExact( ', ref, ' ) ) {')
        o.Raw(src_len, ' = PyTuple_GET_SIZE(', ref, ');')
        handle_unpack_except(o, src_len, trg_len)
        for i,iit in enumerate(its):
            if iit is None: continue
            if iit[0] == 'STORE_FAST' and iit[1] in get_co().unused_fast_var: continue
            ref1 = ConC('PyTuple_GET_ITEM( ', ref, ', ', i, ' )')
            gen_store(iit,ref1,o, ('!PyTuple_GET_ITEM', expr, i))
        o.append('} else {')
        ref2 = New()
        o.Stmt(ref2, '=', 'PySequence_Tuple', ref)
        o.Raw(src_len, ' = PyTuple_GET_SIZE(', ref2, ');')
        handle_unpack_except(o, src_len, trg_len)
        for i,iit in enumerate(its):
            if iit is None: continue
            if iit[0] == 'STORE_FAST' and iit[1] in get_co().unused_fast_var: continue
            ref1 = ConC('PyTuple_GET_ITEM( ', ref2, ', ', i, ' )')
            gen_store(iit,ref1,o, ('!PyTuple_GET_ITEM', expr, i))
        o.Cls(ref2)
        o.append('}')
    PopAcc(o)
    o.Cls(src_len, ref)
    return




def handle_unpack_except(o, src_len, trg_len):
    assert type(o) is Out
    if type(src_len) is int and type(trg_len) is int:
        if src_len >  trg_len:
            o.Raw('PyErr_Format(PyExc_ValueError, "too many values to unpack");')
            o.Raw('goto ', curlabl(), ';')
            UseLabl()
        if src_len < trg_len:
            add_s = '%s, %s == 1 ? "" : "s"' % (src_len, src_len)
            o.Raw('PyErr_Format(PyExc_ValueError, "need more than %d value%s to unpack", ', add_s, ');')
            o.Raw('goto ', curlabl(), ';')
            UseLabl()
        return

    o_2 = Out()
    o_2.Raw('PyErr_Format(PyExc_ValueError, "too many values to unpack");')
    o_2.Raw('goto ', curlabl(), ';')
    tolabl = append_to_exception(o_2)

    o.Raw('if (', src_len, ' > ', trg_len, ') goto ', tolabl, ';')
    UseLabl()

    o_2 = Out()
    add_s = '%s, %s == 1 ? "" : "s"' % (CVar(src_len), CVar(src_len))
    o_2.Raw('PyErr_Format(PyExc_ValueError, "need more than %d value%s to unpack", ', add_s, ');')
    o_2.Raw('goto ', curlabl(), ';')
    tolabl = append_to_exception(o_2)

    o.Raw('if (', src_len, ' < ', trg_len, ') goto ', tolabl, ';')
    UseLabl()