Главная страница

компилятор ТСС. 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
страница16 из 38
1   ...   12   13   14   15   16   17   18   19   ...   38
int new_size) Поле size_allocated содержит выделенный ранее размер строки. При необходимости выделенный размер увеличивается в два раза с помощью tcc_realloc(). Значения полей обновляются. static void add_char(CString *cstr, int c) Перед '\'', '\"' и '\\' добавляется ASCII-символ экранирования '\\' Обычные ASCII-символы с кодами от 32 до 126 просто добавляются в строку. Не обычные символы выводятся в виде восмиричных кодах. Символ перевода строки выводится как 'n'. Перед этими специальными символами выводится '\\' static int type_size(CType *type, int *a) В поле t проверяются биты кодирующие простые типы. Для VT_STRUCT выравнивание берется из поля r, а размер из c Для VT_PTR проверяется бит VT_ARRAY, если он установлен возращается размер всего массива. Если нет, мы имеем дело с простым указателем и возвращаем PTR_SIZE и устанавливаем такое же выравнивание. Для VT_LDOUBLE возвращатся выравнивание LDOUBLE_ALIGN и размер LDOUBLE_SIZE Для VT_DOUBLE и VT_LLONG возвращатся выравнивание 4 и размер 8 Для VT_INT, VT_ENUM и VT_FLOAT возвращатся выравнивание 4 и размер 4 Для VT_SHORT возвращатся выравнивание 2 и размер 2 Для всех остальных типов возвращатся выравнивание 1 и размер 1 static int expr_const(void) Функция вызывает expr_const1(). В поле r переменной vtop (экземалят SValue) прверяется наличие VT_VALMASK, VT_LVAL или VT_SYM. Если комбинация отличается от VT_CONST, компилятор завершается с ошибкой. В связанном с vtop занчении CValue нас интересует поле i. Его значение возвращается в качестве результат функции. Перед этим вызывается vpop() void vpop(void) Значения поля r переменной vtop (экземалят SValue) сохраняется во временной переменной v. В ней сбрасываются все биты, кроме входящих в VT_VALMASK Если не установлен флаг nocode_wanted и в v окажется в TREG_ST0, вызывается o() Если v будет равно VT_JMP или VT_JMPI, вызывается gsym(), т.е. обертку gsym_addr() Функция возвращает SValue из конца цепочки vtop и уменьшает этот указатель. void gsym(int t) Вызывается gsym_addr() с указателем на данные. void gsym_addr(int t, int a) В Section отвечающей за текущий код происходит обход начиная с переданного смещения. По этому адресу лежит следующее смещение для обхода. Само значение смещения заменяется разностью переданного участка кода, адреса кода и 4 static void expr_const1(void) Флаг const_wanted сохраняется и в конце функции восстанавливается. Вызывается expr_eq() при const_wanted обновленной значением 1 static void expr_eq(void) Если установлен флаг const_wanted присходят следующие дейсвия. Вызывается expr_lor_const(), Для токена '?' происходит следующая обработка: В связанном с vtop занчении CValue нас интересует поле i. Мы сохраняем его во верменной переменной и поседовательно вызываем vpop() и next() При включеном расширении GNU и текущем токене ':', сохраняем в c1 значение временной переменной. В любом другом случае вызываем gexpr(), записываем в c1 соответсвующе значение из текущего vtop и вызываем vpop() Вызываем skip() чтобы пропустить ':' и за тем рекурсивно вызываем expr_eq(). Если сохраненное в начале временное значение оказалось не нулевым, обновляем соответствующее значение из текущего vtop значением c1 Если флаг const_wanted сброшен присходят следующие дейсвия. Вызывается expr_lor() Для токена '?' происходит следующая обработка: Вызывается next(). Если vtop не равен vstack, в CType связнаоом с vtop может быть тип с плавающей точкой. Если is_float() определяет такой тип, временный результат будет RC_FLOAT. В противном случае RC_INT, кроме того в этом случае вызывается gv() и save_regs. При включеном расширении GNU и текущем токене ':', вызывается gv_dup() и gtst() в любом другом случае gtst() и gexpr() SValue в конце цепочки vtop и ее тип сохраняются в временные переменные, а конец цепочки сдвигается на одну позицию. Вызываем skip() чтобы пропустить ':' Вызываются gjmp(), gsym(), expr_eq(). Тип SValue который теперь оказался в ноце цепочки сохраняюется в другой временной переменной. Из обоих сохраненных типов их коды и отдельно части кодов отвечающие за простые типы. Эти части проверяются на кодирование типов с плавающий запятой. Если одна из этих частей кодирует VT_DOUBLE, в результирующем типе устанавливается VT_DOUBLE, иначе VT_FLOAT Если одна из частей кодирует VT_LLONG, в результирующем типе устанавливается VT_LLONG Доболнительно првитяется бит VT_UNSIGNED Если одна из частей кодирует VT_PTR, VT_FUNC или VT_STRUCT, тип целико копируется из первого сохраненного типа. Если одна из частей кодирует VT_VOID, в результирующем типе устанавливается VT_VOID Во всех остальных случаях, в результирующем типе устанавливается VT_INT Доболнительно првитяется бит VT_UNSIGNED Для результирующего типа вызывается gen_cast() Если сосстветсвующая часть кода результирующего типа кодирует VT_STRUCT, то вызывается gaddrof() Временному результату присваивается значение RC_INT Если сосстветсвующая часть кода результирующего типа кодирует тип с плавающей точкой, то временному результату присваивается значение RC_FLOAT Если сосстветсвующая часть кода результирующего типа кодирует тип VT_LLONG, то временному результату присваивается значение RC_IRET Для верменног результата вызывается gv(), результа записывается в r2 В tt записывается результат gjmp() Вызывается gsym() SValue в конце цепочки vtop восстанавливается из сохраненной копии. Для итогового типа вызываеттся gen_cast() Если сосстветсвующая часть кода результирующего типа кодирует тип VT_LLONG, то вызывается gaddrof() В r1 записывается результат еще одного вызова gv() для временного реультата. Для r1 и r2 вызывается move_reg() поле r экземпляра SValue в конце цепочки vtop обновляется значением r2 Для tt вызывается gsym()
1   ...   12   13   14   15   16   17   18   19   ...   38


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