Введение
Компилятор для языка программирования Haskell
Глазго́вский компилятор Haskell (GHC) — это компилятор в машинный код для функционального языка программирования Haskell. Он предоставляет кроссплатформенную программную среду для написания и тестирования кода на Haskell и поддерживает множество расширений, библиотек и оптимизаций, упрощающих процесс генерации и выполнения кода. GHC является наиболее распространенным компилятором Haskell. Это бесплатное программное обеспечение с открытым исходным кодом, распространяемое под лицензией BSD. Ведущие разработчики — Саймон Пейтон Джонс и Саймон Марлоу.
История
GHC изначально был запущен в 1989 году как прототип, написанный на Lazy ML (LML) Кевином Хаммондом в Университете Глазго. Позже в том же году прототип был полностью переписан на Haskell, за исключением его парсера, Корделией Холл, Уиллом Партейном и Саймоном Пейтоном Джонсом. Первый бета-релиз состоялся 1 апреля 1991 года. В последующих версиях были добавлены анализатор строгости и языковые расширения, такие как монадические ввод-вывод, изменяемые массивы, не упакованные типы данных, модели параллельного и конкурентного программирования (например, транзакционная память и параллелизм данных), а также профилировщик. Пейтон Джонс и Марлоу позже перешли в Microsoft Research в Кембридже, где продолжили нести основную ответственность за разработку GHC. GHC также включает код, предоставленный более чем тремя сотнями других разработчиков. С 2009 года сторонние вклады в GHC финансируются группой Industrial Haskell.
Названия ГХК
С первых версий на официальном сайте GHC именовался как The Glasgow Haskell Compiler, в то время как в командной строке исполняемого файла он определялся как The Glorious Glasgow Haskell Compilation System. Это было отражено в документации. Изначально он носил внутреннее название The Glamorous Glasgow Haskell Compiler.
Архитектура
GHC написан на Haskell, но система времени выполнения для Haskell, необходимая для запуска программ, написана на C и C++. Фронт-энд GHC, включающий лексер, парсер и проверщик типов, разработан для сохранения максимально возможного объема информации об исходном языке до завершения вывода типов, с целью предоставления пользователям чётких сообщений об ошибках. В традиции компиляции, управляемой типами, упроститель GHC, или "средний конец", где выполняется большинство оптимизаций, реализованных в GHC, структурирован как последовательность преобразований от источника к источнику над Core-кодом. Анализы и преобразования, выполняемые на этом этапе компилятора, включают анализ спроса (обобщение анализа строгости), применение определяемых пользователем правил переписывания (включая набор правил, входящих в стандартные библиотеки GHC, выполняющих слияние foldr/build), развёртывание (называемое "inlining" в более традиционных компиляторах), перемещение let-выражений, анализ, определяющий, какие аргументы функции могут быть развёрнуты (unboxed), анализ результатов конструкций-произведений, специализация перегруженных функций и набор более простых локальных преобразований, таких как свёртка констант и бета-редукция. Бэк-энд компилятора преобразует Core-код во внутреннее представление C через промежуточный язык STG (сокращение от "Spineless Tagless G-machine"). C-код затем может быть обработан одним из трёх способов: он либо выводится в виде C-кода для компиляции с помощью GCC, либо преобразуется непосредственно в машинный код (традиционная фаза "генерации кода"), либо преобразуется в LLVM IR для компиляции с помощью LLVM. Во всех трёх случаях полученный машинный код в конечном итоге связывается с системой времени выполнения GHC для создания исполняемого файла.
GHC's front end, incorporating the lexer, parser and typechecker, is designed to preserve as much information about the source language as possible until after type inference is complete, toward the goal of providing clear error messages to users. In the tradition of type directed compiling, GHC's simplifier, or "middle end", where most of the optimizations implemented in GHC are performed, is structured as a series of source to source transformations on Core code. The analyses and transformations performed in this compiler stage include demand analysis (a generalization of strictness analysis), application of user defined rewrite rules (including a set of rules included in GHC's standard libraries that performs foldr/build fusion), unfolding (called "inlining" in more traditional compilers), let floating, an analysis that determines which function arguments can be unboxed, constructed product result analysis, specialization of overloaded functions, and a set of simpler local transformations such as constant folding and beta reduction. The back end of the compiler transforms Core code into an internal representation of C , via an intermediate language STG (short for "Spineless Tagless G machine"). The C code can then take one of three routes: it is either printed as C code for compilation with GCC, converted directly into native machine code (the traditional "code generation" phase), or converted to LLVM IR for compilation with LLVM. In all three cases, the resultant native code is finally linked against the GHC runtime system to produce an executable.
Язык
GHC соответствует стандартам языка Haskell 98 и Haskell 2010. Он также поддерживает множество необязательных расширений стандарта Haskell, например, библиотеку программных транзакций (STM), обеспечивающую композиционные транзакции памяти.
Расширения системы типа
Экспрессивная статическая система типов — одна из ключевых характеристик, определяющих Haskell. Соответственно, значительная часть работы по развитию языка была сосредоточена на типах данных и классах типов. Компилятор Glasgow Haskell поддерживает расширенную систему типов, основанную на теоретической системе FC. GHC также был портирован на различные процессорные архитектуры.