Главная страница
Навигация по странице:

  • Для остальных токенов происходит переход на метку

  • компилятор ТСС. Tiny c compiler by Fabrice Bellard Описание алгоритмов


    Скачать 191.99 Kb.
    НазваниеTiny c compiler by Fabrice Bellard Описание алгоритмов
    Анкоркомпилятор ТСС
    Дата08.11.2019
    Размер191.99 Kb.
    Формат файлаodt
    Имя файлаtcc book.odt
    ТипДокументы
    #94047
    страница26 из 38
    1   ...   22   23   24   25   26   27   28   29   ...   38
    Если в t присутствует флаг VT_UNSIGNED) , начинается следующая обработка: Если переданная операция равна TOK_SAR, операции присваивается TOK_SHR Если переданная операция равна '/', операции присваивается TOK_UDIV Если переданная операция равна '%', операции присваивается TOK_UMOD Если переданная операция равна TOK_LT, операции присваивается TOK_ULT Если переданная операция равна TOK_GT, операции присваивается TOK_UGT Если переданная операция равна TOK_LE, операции присваивается TOK_ULE Если переданная операция равна TOK_GE, операции присваивается TOK_UGE Вызывается vswap(), в поле t сохраненного CType записывается значение t Вызываеются gen_cast() и vswap() Если переданная операция равна TOK_SHR, TOK_SAR или TOK_SHL в поле t сохраненного CType записывается значение VT_INT; Вызывается gen_cast() Если проверка t с помощью is_float() возвращает ненулевой результат, вызывается gen_opif(op) иначе gen_opic(op) Если переданная операция больше или равна TOK_ULT и меньше или равна TOK_GT в поле t структуры CType записывается VT_INT иначе значение t static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) Оба SValue проверяются с помощью is_null_pointer() если хотябы одна из проверка возвращает не нулевой результат, функция завершается. Из переданных SValue сохраняются во временные переменны CType и биты кодирующие простые типы. Если проверка этих бит с помощью is_integer_btype() вернет ненулевой результат и при этом переданные операция будет отилчна от '-', фунция завершится. При этом елс ипереданная операция будет отличаться и от TOK_LOR и от TOK_LAND, будет выведено предупреждение. Если первый CType кодирует VT_PTR, ссылка на первый сохраненный CType обновляется вызовом pointed_type() иначе если не кодируется VT_FUNC, проискходит переход на метку invalid_operands Если второй CType кодирует VT_PTR, ссылка на второй сохраненный CType обновляется вызовом pointed_type() иначе если не кодируется VT_FUNC, то компилятор завершается с ошибкой. Этот выход отмещен меткой invalid_operands Если петвый или второй CType кодируют VT_VOID, функция завершается. Сылки на CType превращаются в экземпляры структуры. В полях t обоих экземплятов сбрасываются биты VT_UNSIGNED, VT_CONSTANT или VT_VOLATILE Вызывается is_compatible_types() если она возвращает ненулевое значение, переданная операция проверяется на равенстов '-', если значения равны присходит преход на invalid_operands иначе просто выдается предупреждение. static inline int is_null_pointer(SValue *p) В поле r переданного SValue сбрасываются все биты кроме VT_VALMASK, VT_LVAL и VT_SYM. Если итоговое значение отлично от VT_CONST, функция завершается возврашая 0. Если CType связанный с переданным SValue кодирует VT_INT, а поле i переданного CValue содержит нулевое значение, либо кодируется VT_LLONG и поле ll содержит нулевое значение, возвращается 1, иначе 0 static inline int is_integer_btype(int bt) Фунция возвращает 1 если переданное значение равно VT_BYTE, VT_SHORT, VT_INT или VT_LLONG, иначе возвращается 0 static inline CType *pointed_type(CType *type) Фунция обращается к символу связанному с переданынм CType. В его поле ref есть ссылка на CType. Она возвращается в качестве результата. void gen_opic(int op) Сохраняется вторая с конца SValue из цепочки vtop, и последняя Сохраняются биты кодирующие символы В зависимости от того кодитуется ли VT_LLONG, сохраняются поля ll или i связанных CValue. Их значения записываются в l1 и l2; Если сочетание бит VT_VALMASK | VT_LVAL | VT_SYM в поле r сохраненных SValue дает значение VT_CONST, во временные переменные c1 и c2 сохранется 1 иначе 0. Если c1 и c2 не нулевые происходит следующая обработка в зависимости от переданной поперации: Для '+' происходит сложение двух значений с записью результата в l1 Для '-' происходит вычитание двух значений с записью результата в l1 Для '&' происходит побитовое И двух значений с записью результата в l1 Для '^' происходит исключающиее ИЛИ двух значений с записью результата в l1 Для '|' происходит побитовое ИЛИ двух значений с записью результата в l1 Для '*' происходит умножение двух значений с записью результата в l1 Для TOK_PDIV, '/', '%', TOK_UDIV и TOK_UMOD происходит следующая обработка. Если l2 соделжит 0 происходи переход на метку general_case, но при этом если флаг const_wanted установлен компилятор завершается с ошибкой. Для '%' вычиляется остаток от деления Для TOK_UDIV происходит деление с преобразованием к безнаковому числоу Для TOK_UDIV вычисленяется остаток с преобразованием к безнаковому числоу Для остальных токенов происходит простое деление Для TOK_SHL происходит сдвиг влево с записью результата в l1 Для TOK_SHR происходит беззнаковый сдвиг влево с записью результата в l1 Для TOK_SAR происходит беззнаковый сдвиг влево с записью результата в l1 Для TOK_ULT в l1 записывается результат беззнакового сравнения l1 и l2. 1 если первая меньше второй Для TOK_UGE в l1 записывается результат беззнакового сравнения l1 и l2. 1 если первая больше или равна второй Для TOK_EQ в l1 записывается результат сравнения l1 и l2. 1 если первая равна второй Для TOK_NE в l1 записывается результат сравнения l1 и l2. 1 если первая не равна второй Для TOK_ULE в l1 записывается результат беззнакового сравнения l1 и l2. 1 если первая меньше или равна второй Для TOK_UGT в l1 записывается результат беззнакового сравнения l1 и l2. 1 если первая больше второй Для TOK_LT в l1 записывается результат сравнения l1 и l2. 1 если первая меньше второй Для TOK_GE в l1 записывается результат сравнения l1 и l2. 1 если первая больше или равна второй Для TOK_LE в l1 записывается результат сравнения l1 и l2. 1 если первая меньше или равна второй Для TOK_GT в l1 записывается результат сравнения l1 и l2. 1 если первая больше второй Для TOK_LAND в l1 записывается результат логического И переменных l1 и l2 Для TOK_LOR в l1 записывается результат логического И переменных l1 и l2 Для остальных токенов происходит переход на метку general_case;

    Поле ll структуры CType связанной с предполедней SValue обновляется значением l1

    Цепочка vtop уменьшается Если c1 или c2 оказались нулевыми происходит следующая обработкам Если c1 содержит ненулевое значение и передана одна из операций '+','&', '^' '|' или '*', то вызывается vswap(), c2 обновляется значением c1, l2 обновляется значением l1 Цепочка vtop уменьшается если c2 содержит ненулевое значение и выполняется одно из следующих условий: Передана одна из следующих операций '*', '/', TOK_UDIV или TOK_PDIV, при этом l2 содержит единицу Передана одна из следующих операций '+', '-', '|', '^', TOK_SHL, TOK_SHR, TOK_SAR, при этом l2 содержит 0) || Передана операция '&', при этом l2 содержит -1 Если условие не выполняется, проверяется содержит ли c2 единицу и передана ли одну из следующих операций '*', TOK_PDIV и TOK_UDIV. В этом случае управление передается на метку general_case. При этом если l2 содержит ненулевое значение и это значение при уменьшении на 1 и побитовом И само с собой дает результат отличный от нуля, происходит следующая обработка n увеличивается на 1, начиная с -1, пока побитовый сдвиг вправа не обнулит l2

    Поле ll структуры CType связанной с последней SValue обновляетя значением n

    Операция '*' заменяется на TOK_SHL

    Операция TOK_PDIV заменяется на TOK_SAR

    Операция '*' заменяется на TOK_SHL;

    Операция TOK_UDIV заменяется на TOK_SHL;

    Происходит переход на метку general_case
    Если переменная c2 содержит 1, при этом переданы операции '+' или '-' и при этом поле r предпоследней SValue при побитовом И с VT_VALMASK, VT_LVAL, VT_SYM дает результат побитового ИЛИ VT_CONST и VT_SYM, происходит следующая обработка

    Если передана операция '-', инвертируется знак переменной l2; Уменьшается цепочка vtop.

    Поле ll структуры CType связанной с последней SValue увеличивается на значение l2;
    Другие операции обрабатываются блоком начинающимся с метки general_case Если сброшен флаг nocode_wanted, то проверяются переменные t1 и t2. Если одна из них содержит VT_LLONG, вызывается gen_opl() иначе вызывается gen_opi() Если сброшен флаг nocode_wanted, установлен уменьшается цепочка vtop void vswap(void)

    Последня SValue сохраняется во временной переменной чтобы поменять ее местами с предполседней
    1   ...   22   23   24   25   26   27   28   29   ...   38


    написать администратору сайта