Why not a compiler? by Y [05-04-00] or later
Version 0.06 alpha, built [23-06-00]
Copyright (c) 1997-2000 YALLIE, Inc. All Rights Reserved.
Посвящается Диане ;)
Введение
--------
Приветствую всех, кто интересуется компиляторами, синтаксическим
анализом и генерацией кода. Посмотрите на этот проект -
чем не компилятор? ;)
Что такое Why?
--------------
Why - универсальный язык программирования, похожий на Форт. Я просто
взял основную идею, выкинул все, что мне не нравилось, добавил несколько
дополнительных возможностей и попытался реализовать все это на базе
синтаксиса, максимально похожего на Форт.
Компилятор Why генерирует быстрый и стабильный (надеюсь) 32-разрядный код
для расширенной DOS (DOW4GW, PMODEW, DOS32A и т.д). Он также может быть
портирован в YaOS, Linux, Win32 и (практически) любую другую 32-битную
среду. У меня нет времени попробовать все это, но вы можете мне помочь ;)
Компилятор Why доступен бесплатно всем желающим, вместе с полным исходным
текстом на Паскале. Почему не на C++? Гм... Точно не знаю. Другой
компилятор (еще пока не законченный) я пишу на портабельном C++, но Why
написан на Паскале. В конце концов, почему бы и нет?
Лицензия
--------
Компилятор Why, его исходный текст и run-time библиотеки не являются
public domain software. Это copyrighted freeware, распространяемое на
условиях GNU General Public License. Run-time библиотеки языка Why
предоставляются на условиях GNU Library General Public License вместо
GNU GPL. См. файлы copying and copying.lib для более достоверной
информации.
Компилятор Why распространяется в надежде, что он окажется полезным
кому-нибудь, но без гарантии и чего-либо подобного. Ни в каком случае
автор не будет чувствовать себя виноватым в какой-нибудь неприятности,
проистекающей от Вашего использования или неиспользования компилятора.
Весь риск на Вашей совести.
Основные идеи
--------------
Как и Форт, язык Why основан на понятии стека. Программа на Why может
работать с двумя стеками: арифметическим (коротко - astack) и стеком
возвратов (rstack). Все данные, с которыми мы работает, либо помещаются
на вершину арифметического стека, либо звлекаются с нее. Rstack тоже
можно использовать для этих операций, но подобный стиль не стоит
практиковать без крайней необходимости.
Пример:
123 PutNumber
В этом примере 123 - целочисленная константа, а PutNumber - вызов
процедуры. 123 помещается на astack, затем вызывается PutNumber.
PutNumber берет вехний элемент стека и отображает его на экране. После
завершения этих операций стек останется в первоначальном состоянии.
PutNumber - это процедура, поскольку она не возвращает значения. Функции
вызываются и описываются точно так же, как процедуры, с единственным
различием - функция помещает возвращаемое значение (или значения) на
вершину стека astack. Функция может возвратить любое число параметров
любого типа, существующего в языке Why.
Как в форте, определение процедуры или функции Why начинается символом
":" и заканчивается ";".
Простой пример определения и использования функции:
: Sum ( a b -> a+b )
+
;
: Main
2 3 Sum PutNumber
;
Этот пример напечатает 5. 2 и 3 помещаются в стек, затем вызывается
функция Sum. Sum выполняет операцию +, которая выбирает два целых числа
с вершины стека и заменяет их значением суммы.
Программа на Why - это набор определений. Каждое определение описывает
процедуру или функцию. Выполнение программы начинается с вызова функции
Main, как в C или C++. В отличие от C, язык Why не различает регистр
символов. Пример программы "Hello, World!".
( hello.why by Y [11-05-00] )
: Main
"Hello, World!" Puts
;
Компилятор Why compiler не может проверять соответствие типов и все
такое, так что весь процесс контролируется только программистом. Такова
особенность этого языка: стек невозможно контролировать на этапе
компиляции.
В соответствии со своей концепцией язык позволяет многие странные вещи.
Следующий пример отображает на экране "Hello there again":
"again\r\n" "there " "Hello " Put Put Put
Вы можете также написать, например, "Hello" PutNumber, и компилятор
не предупредит Вас, потому что не может проверить, какие параметры Вы
передали процедуре PutNumber. Программа в этом случае напечатает адрес
строковой константы "Hello".
Грамматика языка Why
--------------------
Program ::= [ Imports ] { GlobalVariableDefinition | Definition }
Imports ::= "imports" { Identifier }
GlobalVariableDefinition ::= TypeName { Identifier [ "["
IntegerConstant "]" ] } ";"
TypeName ::= "int" | "string";
Definition ::= ":" Identifier Sequence ";"
Sequence ::= { Element }
Element ::= Constant | Operation | ProcedureCall | VariableDefinition |
Variable | BeginStatement | DoLoopStatement | DowntoLoopStatement |
IfStatement | InlineStatement | SimpleStatement | ToLoopStatement |
Pragma
Operation ::= "+" | "-" | "*" | "/" | "%" | ">" | "<" | ">=" | "<=" |
"<>" | "!=" | "==" | "||" | "&&" | "!" | "|" | "&" | "~" | "<-" |
"->" | "<." | ".>" | "[]" | "++" | "--" | "<<" | ">>" | <+> | <-> |
<*> | </> | <%> | <++> | <-->
ProcedureCall ::= Identifier;
VariableDefinition ::= TypeName { Identifier [ "["
IntegerConstant "]" ] } ";"
BeginStatement ::= "begin" Sequence ( "until" | "while" Sequence "repeat" )
DoLoopStatement ::= "do" Sequence "loop"
DowntoLoopStatement ::= "downto" Sequence "loop"
IfStatement ::= "if" Sequence [ "else" Sequence ] "then"
InlineStatement ::= "inline" { IntegerConstant } ";"
SimpleStatement ::= "drop" | "dup" | "rot" | "swap"
ToLoopStatement ::= "to" Sequence "loop"
Pragma ::= "pragma" { Setting } ";"
Setting ::= Identifier StringConstant
Компилятор Why поддерживает следующие виды комментариев:
блочный: (Forth-like)
блочный: /* C-like */
строковый: \ Forth-like
строковый: // C++-like
Run-time библиотека Why
-----------------------
RTL-библиотека Why еще не вполне закончена. Она использует библитотеку
Tran's PMC, pmc.lib, которую напрямую нельзя вызывать из Why-программ
из-за соглашений вызова процедур C. Стартующий код Why, распространяемый
с текущей версией компилятора, w0d32f.asm, поддерживает только расширенную
среду DOS. Он содержит несколько фрагментов из старт-кода Tran's PMC.
Вот список процедур run-time библиотеки Why:
Стандартные общего назначения: nDup, nDrop, nRot, nSwap, xStacks,
AtoR, RtoA, Extract, nExtract, Abs, Sign, UpCase, LoCase, Random,
Str, StrHex, Val
Стандартные вводы-вывода: Put, Puts, PutChar, NewLine, PutNumber,
PutHexNumber, Gets, GetNumber
Переходники к библиотеке PMC: Malloc, Realloc, Free
Оптимизация в компиляторе Why
-----------------------------
Текущая версия компилятора Why делает что-то вроде простой оптимизации
машинного кода. Несколько значений на вершине арифметического стека
хранятся в регистрах процессора, поэтому доступ к ним осуществляется
очень быстро. У меня это называется кэшированием. Кэш может содержать
от 0 до 5 регистров (eax, ebx, ecx, edx, edi), в любом порядке. Операторы
drop, rot и swap выполняются фактически на этапе компиляции: они просто
изменяют имена регистров в кэше. Кэш опустошается перед вызовом любой
процедуры (при опустошении все регистры записываются в настоящий
арифметический стек), поэтому процедуры оперируют со стеком так же,
как обычно.
Другой пример оптимизации - развертка констант. Например:
1 2 + 4 * PutNumber
Когда арифметические операции проводятся над константами, результат
можно вычислять во время компиляции. Для указанного примера текущая
версия компилятора Why сгенерирует такой же код, как для
12 PutNumber
Этот вариант оптимизации позволяет также ускорить некоторые составные
операторы. Например, "0 if ... then" никогда не выполнит блок "if",
поэтому компилятор может сгенерировать безусловный переход к оператору,
следующему за "then" (и так и делает на самом деле ;). Все это
справедливо также для циклов вроде "1 5 to ... loop" (1 > 5, так что
тело цикла ни разу не выполняется).
Примеры на языке Why
--------------------
Зайдите в подкаталог Samples и просмотрите все файлы *.why. Этого должно
быть вполне достаточно для любого, кто занимался программированием...
Если кому-нибудь что-то покажется неясным, обращайтесь за помощью ко
мне (см. адреса ниже).
Использование компилятора Why
-----------------------------
Компилятор называется why.exe. Единственный аргумент командной строки -
имя файла с исходным текстом программы:
why.exe <source.why>
Расширение по умолчанию - "why".
Компилятор генерирует два ассемблерных файла с расширениями "asm" и
"inc". Внимание! Если какой-либо из них уже существует, он будет молча
переписан. Кроме компилятора, Вам может пригодиться утилита whymake
(whymak32.exe). Whymake - это простой драйвер компиляции и линковки
для Why-программ. Например, чтобы скомпилировать и связать hello.why,
выполните команду: "whymak32 hello.why" - и Вы получите exe-файл
"hello.exe". Чтобы скомпилировать demo19.why (которая испортирует
graph.why и keyboard.why), выполните "whymak32 demo19 graph keyboard".
Если не хотите перекомпилировать модули graph и keyboard modules,
укажите расширение ".obj" для этих файлов. Whymake скомпилирует только
demo19.why, а все остальные модули не будут изменены:
"whymak32 demo19.why graph.obj keyboard.obj".
Системные требования
--------------------
Компилятор Why и программное обеспечение, созданное с его помощью,
будет выполняться на любой IBM PC/AT-совместимой машине с процессором
386 и выше и как минимум 1 MB памяти, VGA адаптером и 1 MB свободного
места на винчестере. Рекомендуется Pentium (tm) с 8 MB и SVGA платой.
Лично я не тестировал ничего с подобной конфигурацией, я просто думаю,
что этого хватит. Я использую Celeron 466 MHz с 64 MB памяти и
винчестером Quantum Fireball 10G, поэтому скорость компиляции не была
моей главной целью.
Чтобы компилировать, линковать и отлаживать программы на Why, Вам
также понадобятся:
o TASM (я проверял версии 4.1 и 5.2)
o Tran's PMC library (версия 1.01)
o WLINK (WATCOM Linker, версия 11.0).
o DOS4G/W или совместимый extender (DOS4G/W 1.97, PMODE/W 1.33 и т.д)
o WD (WATCOM Debugger, версия 11.0)
Чтобы начать с чего-нибудь и проверить, работает ли компилятор,
распакуйте все архивы в один каталог и запустите файл demo.bat. Он
скомпилирует и запустит демонстрационную программу (требуется VGA или
SVGA плата).
Перекомпиляция компилятора
--------------------------
Для перекомпиляции Why требуется Turbo Pascal 7.0 или совместимый с ним
компилятор. Загляние в файл build.bat для более точных сведений.
К счастью, это самый короткий исходный текст в каталоге ;)
Заметки, идеи, что еще надо сделать и т.д.
------------------------------------------
См. todo.txt, чтобы узнать, что еще нужно сделать. См. done.txt, чтобы
узнать, что уже было сделано.
Заключение
----------
Я бы хотел поблагодарить всех, кто не мешал мне заниматься делом.
Компилятор Why [почти] готов, поэтому если Вам нужно что-то еще,
свяжитесь со мной. Пришлите e-mail по одному из следующих адресов:
Контактная информация
---------------------
e-mail: yallie@yandex.ru (предпочтительный)
yallie@mail.ru
icq: 67654811
Web сайты по теме
-----------------
http://yallie.narod.ru Моя домашняя страница
Y [05-04-00] or later Перевод: Алексей Яковлев Y [23-12-2002] | |
|