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

компилятор ТСС. 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
страница12 из 38
1   ...   8   9   10   11   12   13   14   15   ...   38

static int tcc_compile(TCCState *s1) Вызывается preprocess_init() Обнуляется строка funcname, значению anon_sym присваивается SYM_FIRST_ANOM, обнуляется section_sym, но если включена отладка то ему присваивается результат put_elf_sym(), вызванной для добавления в symtab_section. Текущий рабочий каталог записывается в буфер с помощью getcwd(). Для Windows вызывается normalize_slashes() В конец буфера добавляется слешь чтобы отделить имя каталога от имени файла. Функция put_stabs_r() вызывается дважды. Один раз для буфера и второй раз для поля filename текущего файла. Функция put_elf_sym() вызывается для поля filename текущего файла. В структурах CType, описывающих типы int и char заполняется поле t значениями VT_INT и VT_BYTE. Для структуры, описыващей тип char вызывается mk_pointer() В поле t структуры func_old_type записывается VT_FUNC, а в поле ref ссылка полученная с помощю sym_push() Указатель define_start инициализируется адресом define_stack. Устанавливается флаг nocode_wanted Функция setjmp() (обертка над библиотечной _setjmp()) вызввается для массива в на который указывает поле error_jmp_buf состояния компилятора s1 . Если возвращен 0 то происходят следующие действия. В состоянии s1 обнуляется счетчик nb_errors и устанавливается флаг error_set_jmp_enabled. Глобальный указатель на ASCII символ обновляется адресом buf_ptr[0] текущего файла. Устанавливаются флаги токенов TOK_FLAG_BOL и TOK_FLAG_BOF. Устанавливаются флаги парсинга PARSE_FLAG_PREPROCESS и PARSE_FLAG_TOK_NUM. Вызывается next() Вызывается decl() для VT_CONST. Если встречается TOK_EOF компилятор завершается. В состоянии s1 сбрасывается флаг error_set_jmp_enabled. free_defines() вызывается для сброса всех объявлений. Вызывается gen_inline_functions() Вызывается sym_pop() для global_stack В зависимости от значения поля nb_errors состояния s1, поле возвращет 0 или -1. static void mk_pointer(CType *type) Экземпляр структуры Sym создается с помощю sym_push(). Его адрес записывается в поле ref переданной струтуры Ctype, в поле t этой струтуры устанавливается бит VT_PTR. static void decl(int l) Бесконечный цикл начинается с вызова parse_btype(), если следом идет токен ';', он пропускается с помощью вызова next() и перехода на следующий шаг цикла. Если в параметре передано значение VT_CONST и встречается токен TOK_ASM1, TOK_ASM2 или TOK_ASM3, вызывается asm_global_instr() и завершается текущий шаг цикла. Если в параметре передано значение VT_LOCAL и встречается токен, меньше чем TOK_DEFINE, происходит завершение текущего шага цикла. В поле t структуры CType записывается VT_INT Если поле t структуры CType при побитовом И с маской VT_BTYPE будет содержать VT_ENUM или VT_STRUCT и при этом встречается токен ';', он пропускается с помощью вызова next() и перехода на следующий шаг цикла. Внутри основного бесконечного цикла запускается еще один. Вызывается type_decl() с параметром TYPE_DIRECT. Функция оперирует со ссылкой на ту же структуру CType. Если после ее вызова поле t структуры при побитовом И с маской VT_BTYPE будет содержать VT_FUNC, то локальный указатель на структуру Sym обновляется полем ref структуры CType. Если в полученном символе поле c содержит FUNC_OLD, то для этого символа вызывается func_decl_list() Если встечается токен '{', проверяется переданный параметр на равенство VT_LOCAL. В этом случае компилятор завершается с ошибкой. Если поле t структуры CType при побитовом И с маской VT_BTYPE не будет равно VT_FUNC, компилятор завершается с ошибкой. Локальный указатель на структуру Sym обновляется полем ref структуры CType. Новый цикл проходит по всей цепочке символов. Если в процессе обхода поле v символа при побитовом И с

SYM_FIELD не равно нулю, компилятор завершается с ошибкой. Если в поле t структуры CType установлены биты VT_EXTERN и VT_INLINE, то бит VT_EXTERN в этом поле сбрасывается, а VT_STATIC устанавливается Перемення v в которую до этого изменила функция type_decl() пердается sym_find() для поиска символа. Если символ найден, проверяется поле t связанной с ним структуры CType, если при побитовом И с маской VT_BTYPE не будет равно VT_FUNC, управление передается на метку func_error1 Временной переменной r присваивается поле r cтруктуры Sym, связанной полем type (ссылка на CType) найденного символа. Макрос FUNC_CALL() преборазовывает в указатель на структуру func_attr_t и возвращает занение поля func_call. Этот макрос вызывается для переменной r и поля r связанного с CType символа (вязь по полю ref). Эти значения проверяются на равенстов с FUNC_CDECL. Если первое значение не равно FUNC_CDECL, а второе равно, во второй указатель полученный с помощю FUNC_CALL(), записывается результат FUNC_CALL() вызваного для r. Макрос FUNC_EXPORT() преборазовывает в указатель на структуру func_attr_t и возвращает занение поля func_export. Макрос вызывается для r и если он возвращает ненулевой значение, то мокрос вызывается поля r связанного с CType символа. В полученный указатель записывается единица. В качестве параметров функции is_compatible_types() передается указатель на CType и CType связанный с символом. Если эта проверка заканыивается неудачей, компилятор завершается. CType связанный с символом обновляется указателем на CType. Если sym_find() не находит символ, символ создается с помощью global_identifier_push(). В CType связанном со вновсь созданным символом поле ref обновляется значением поля ref указателя на CType. Если в поле t указателя на CType присутствуют оба бита VT_INLINE и VT_STATIC. Создается новая структура TokenString с помощью tok_str_new() Счетчик block_level используется для подсчета уровня вложенности блоков кода, обрамленных фигурной скобкой. Начинается бесконечный цикл обработки блоков кода. Если встречается токен TOK_EOF, то компилятор завершается с ошибкой. В TokenString добавляется текущий токен с помощью tok_str_add_tok(). Текущий токен сохраняется во верменной переменой и вызывается next() Если сохраненный токен, это открывающаяся скобка, то block_level увеличивается на единицу, если закрывающася, то уменшьшается. Если при уменьшении достигнут 0, бесконецый цикл завершается. В TokenString с помощю tok_str_add() добавляются поледовательно минус 1 и ноль. Макрос INLINE_DEF() преобразует переданне значение в двойной указатель на int и получает значение по указателю первого уровня, т. е. целевой адрес одного из значений типа int. Макрос вызывается для поля r символа и в полученый адрес записывается значение поля str структуры TokenString. Если проверка бит VT_INLINE и VT_STATIC не прошла указателю cur_text_section присваивается значение поля section временной структуры AttributeDef которую возможно изменила type_decl(). После присваивания проверяется было ли это изменение (не получили ли мы нулевое знаение) и, в этом случае, cur_text_section обновляется значением text_section В поле r символа записывается побитовое или VT_SYM и VT_CONST. Для символа вызывается gen_function(). На этом обработка '{' заканчивается. Бесконечный цикл прерывается. Если текущий токен не '{', то происходят следующие действия: Проверяется поле t структуры CType. Если побитовое И с маской VT_TYPEDEF, генерируется новый символ с помощью sym_push() В поле t структуры CType связанного с новым символом устанавливается бит VT_TYPEDEF/ Если действие с VT_TYPEDEF не требуется, накладывается маска VT_BTYPE и результат сравнивается с VT_FUNC. В случае равенства, проверяется поле func_attr временной структуры AttributeDef которую возможно изменила type_decl(). Если поел не пустое его значение присваивается, полю r символа связанного с CType. Вызывается external_sym() Если Два предидущих действия не тербуется происходят следующие действия Если в поле t структуры CType установлен бит VT_ARRAY, то для это поля вызывается lvalue_type(). Результат записывается во временную переменную r Текущий токен сравнивается с '='. Результат сравнения проверяется дважды и для этого сохраняется во временной переменной has_init Проверяются поля t двух структур CType (вторая является той же структурой, но она была передна type_decl(), и возможно изменена). Первое на наличе VT_EXTERN, второе одноверменно на наличие VT_ARRAY и VT_STATIC. Вротое условие включает сохраненное условие has_init, предполагает равенство параметра переданного все decl() и VT_CONST, а так же что поле r символа связанного с CType содержит значение меньше 0. Если одно из условий выполняется, вызывается external_sym(), в противном случае поисходят следующие действия В поле t структуры CType обработанной type_decl() записывается результат побитового И значения VT_STATIC и поля t структуры CType. Результат проверяется на наличие бита VT_STATIC, если он присутствует, то в переменную r добавляется бит VT_CONST, если нет то в r добавляются биты переданные в decl() в качестве параметра. Если сохраненное условие has_init истинно вызывается next() Вызывается decl_initializer_alloc() Если текущий токен это не ',' то вызывается skip() с параметром ';' и бесконечный цикл прекращается. Вызывается next()
1   ...   8   9   10   11   12   13   14   15   ...   38


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