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

  • Если текущий токен отичается от

  • компилятор ТСС. 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
    страница23 из 38
    1   ...   19   20   21   22   23   24   25   26   ...   38
    static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr) Если параметр is_expr установлен, вызывается vpushi(0), коду типа связанному с в vtop присваивается VT_VOID; Если текущий токен равен TOK_IF, происходит селдующая обработка Вызывается next(), пропускается '(', gexpr(), припускается ')', переменной a присваивается результат вызова gtst(), вызывается, block(), сохранеяется текущий токен. Если его значение это TOK_ELSE происходит следующая обработка Вызывается next(), переменной d присваивается результат вызова gjmp(), вызывается gsym(), вызывается block() и gsym() Если текущий токен отичается от TOK_ELSE, то вызывается gsym() Если текущий токен равен TOK_WHILE происходят следующие действия: Вызывается next(), сохраняется указатель на данные, пропускается '('. Вызываетя gexpr(), пропускается ')', переменнйо a присваивается результат вызова gtst(), переменная b обнуляется, вызывается block(). Вызываются gjmp_addr(d), gsym(a), gsym_addr(b, d) Если текущий токен равен '{' происходят следующие действия. Вызывается next(), сохраняется переменны local_stack и local_label_stack; Если текущий токен равен TOK_LABEL, то вызывается next() и наченается бесконечный цикл Если тоекн является зарегистрированным словом, компилятор завершается с ошибкой. Вызывается label_push(), вызывается next(), если текущий токен равен ',', то вызывается next() иначе пропускается ';' и бесконечный цикл завершается. Начинается цикл который завершится при достижении '}' Вызывается decl() Если текущий токен отличен от '}', то при установленом флаге is_expr вызывается, vpop() Вызывается block() Вызываются label_pop(), sym_pop() и next() Если текущий токен равен TOK_RETURN происходят следующие действия: Вызывается next() Если текущий токен отличен он ';', вызываются gexpr() и gen_assign_cast(). Если возвращаемый тип кодирует VT_STRUCT происходят следующие действия: Возвращаемый тип сохраняется во временную переменну, для нее вызываются mk_pointer() и vset(); Вызываются indir(), vswap() и vstore() Если возвращаемый тип не кодирует VT_STRUCT, то он проверяется функцией is_float() если функция возвращает ненулевой результат, вызывается gv(); Если для возвращаемого типа не сработало ни одно из двух условий, вызывается gv() Указатель vtop уменьшается Пропускается ';' В rsym записывается результат вызова gjmp() Если текущий токен TOK_BREAK, то провенятеся указатель bsym. Если он не установлен, компилятор завершается с ошибкой. В адрес по указателю bsym записывается результат вызова gjmp() Вызывается next(), пропускается ';' Если текущий токен равен TOK_CONTINUE, то проверяется указатель csym. Если он не установлен, компилятор завершается с ошибкой. В адрес по указателю csym записывается результат вызова gjmp() Вызывается next(), пропускается ';' Если текущий токен равен TOK_FOR, происходит следующая обработка: Вызываетя next(), пропускается '(' Если текущий токен отличен он ';', вызываются gexpr() и vpop(); Пропускается ';' Значение указателя на данные записывается в переменные d и c Переменны a и b обнуляются. Если текущий токен отличен от ';', то вызывается gexpr(), переменной a присваивается результат вызова gtst() Пропускается ';' Если текущий токен отличен от ')' происходят следующие действия: В переменную e записывается результат вызова gjmp(). В c сохраняется адрес данных. Вызываются gexpr(), vpop(), gjmp_addr(d) и gsym() Пропускается ')' Вызываются block(), gjmp_addr(), gsym() и gsym_addr() Если текущий токен равен TOK_DO Вызывается next(), a и b обнуляются, d присваивается указатель на данные. Вызывается block(), пропускаются TOK_WHILE и '(' Вызываеются gsym(b) и gexpr() Значение c обновляется результатом вызова gtst() Вызывается gsym_addr(c, d), пропускается ')', вызывается gsym(), пропускается ';' Если текущий токен равен TOK_SWITCH) Вызывается next(), пропускается '(', вызывается gexpr() Значение case_reg обновляется результатом вызова gv() Вызывается vpop(), пропускается ')', обнуляется a, значение b обновляется результатом gjmp(), обнуляется c = 0; Вызывается block(), если в c будет записан 0, то ее значение обновляется указателем на данные. Вызываетя gsym_addr() и gsym() Если текущий токен равен TOK_CASE Если case_sym содержит нулевое значение, компилятор завершается с ошибкой. Вызывается next() Результат вызова expr_const() записывается в две временные переменные Если включен флаг gnu_ext и текущий токен равен TOK_DOTS, то вызывается next(), вторая временная переменная обновляется вызовом expr_const() и сравнивается с первой временной переменной, если вторая меньше первой, выводится предупреждение Переменная b обновяется вызовом gjmp(). Вызываются gsym(), vseti() и vpushi() Если временные переменные равны, вызывается gen_op() и по адресу содержащемуся в case_sym записывается результат вызова gtst() Если переменные не равны, вызывается gen_op(), по адресу содержащемуся в case_sym записывается результат вызова gtst(), вызываются vseti(), vpushi() и gen_op(), по адресу содержащемуся в case_sym записывается результат вызова gtst() Вызывается gsym(), пропускается ':', сбрасывается флаг is_expr = 0, происходит переход на метку block_after_label Если текущий токен равен TOK_DEFAULT Вызывается next(), пропускается ':' Если def_sym содержит нулевой адрес или по этому адресу содержится ненулевое значение, компилятор завершается с ошибкой По адресу содержашемуся в def_sym помещается указатель на данные. Сбрасывается флаг is_expr = 0, происходит переход на метку block_after_label Если текущий токен равен TOK_GOTO Вызывается next(); Если текущий токен равен '*' и установлен флаг gnu_ext Вызываются next(), gexpr(); Если тип связанный с vtop кодирует VT_PTR, компилятор завершается с ошибкой Вызывается ggoto(); Если текущий токен не является предопределенным Вызывается label_find(), если она вызвращает нулевое значение, вызывается label_push() иначе в возвращенном значение проверяется поле r Если оно содержит LABEL_DECLARED, то это значение заменяется на LABEL_FORWARD Если поле r найденного символа содержит LABEL_FORWARD, то поле next этого символа обновляется вызовом gjmp(), иначе вызывается gjmp_addr() Вызывается next() Если токен является предопределенным, компилятор завершается с ошибкой Пропускается ';' Если текущий токен равен TOK_ASM1 или TOK_ASM2 или TOK_ASM3, вызывается asm_instr() Значение b обновляется результатом вызова is_label() Если получено ненулевое значение label_find() если найден символ и в его поле r записан LABEL_DEFINED, компилятор завершается с ошибкой Вызывается gsym(), в поле r записывается LABEL_DEFINED Если символ не найден вызывается label_push() В символе обновляется поле next указателем на данные. Начиная с метки block_after_label присходит следующая обработка Если текущий токен равен '}' выводится предупреждение, в противном слвуче если установлен флаг is_expr, вызывается vpop() Вызывается block() Если предыдущая проверка функцией is_label() вернула нулевой результат Если текущий токен равен ';' и установлен флаг is_expr, вызываются и vpop() gexpr(). Если флаг не установлен, вызываются gexpr() и vpop() Пропускается ';'
    1   ...   19   20   21   22   23   24   25   26   ...   38


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