Транслятор с Euphoria на C
1. Введение Транслятор с Euphoria на C переведёт (оттранслирует) любую программу Euphoria в эквивалентный исходный код C. Имеются отдельные версии транслятора для Windows, DOS, Linux и FreeBSD. После трансляции программы Euphoria на C вы можете компилировать и линковать код C, используя один из поддерживаемых компиляторов C. Этот процесс создаст для вас исполняемый файл, который в типовом случае будет многократно быстрее, чем если бы вы использовали для своей программы интерпретатор Euphoria. Транслятор умеет транслировать/компилировать *сам себя* в исполняемый файл для каждой из платформ. Транслятор также используется при трансляции/компиляции исполнительного блока интерпретатора. Исходный код транслятора находится в каталоге euphoria\source. Транслятор на 100% написан кодом Euphoria.
Транслятор в настоящее время работает с GNU C на Linux или FreeBSD, а также с Watcom C или DJGPP C на DOS, и с Watcom C, Lcc или Borland 5.5 на Windows. Перечисленные компиляторы все бесплатные. Компилятор GNU C всегда уже присутствует на вашей системе Linux или FreeBSD. Другие могут быть получены на их Web-узлах. Для Windows мы строго рекомендуем в первую очередь Watcom или Borland, а уже затем Lcc. Lcc всё ещё активно разрабатывается и становится лучше и лучше, но там остаются некоторые ошибки, с которыми вам будет трудно откомпилировать корректно большую программу Windows. Watcom и Borland оба очень стабильны. Watcom обычно вырабатывает слегка меньшую, слегка более быструю программу, но зато Borland работает намного быстрее. Пакет Watcom DOS32 включает расширитель DOS CauseWay и файловый компрессор. CauseWay имеет открытый исходный код и свободен. Вы можете прочитать больше о нём по адресу: http://www.devoresoftware.com Файлы emake.bat и objfiles.lnk обеспечивают автоматическое присоединение CauseWay к программе. Другие расширители DOS, такие как DOS4GW, не обеспечивают надёжную работу с транслятором. Начиная работать, транслятор ищет или переменные окружения "WATCOM", "LCC", "BORLAND" и "DJGPP", или соответствующие каталоги в вашей переменной PATH. Далее транслятор генерирует файл emake.bat, который, запускаясь, вызывает соответствующий компилятор и его линкер. Примечания:
Запуск транслятора похож на запуск интерпретатора. Под DOS вам следует ввести команду: ec allsorts.ex или ec allsortsПод Windows введите: ecw taskwire.exw или ecw taskwireПод Linux/FreeBSD будет работать: ecu qsort.exu или ecu qsortОтличие от интерпретатора заключается в том, что вместо запуска программы allsorts.ex транслятор создаст несколько файлов исходного кода C. То есть, любой желающий может запустить транслятор, так как он имеется в каталоге euphoria\bin вместе с интерпретатором. Но чтобы затем компилировать и линковать выданные транслятором файлы C, вам потребуется установленный на вашей машине один или несколько из поддерживаемых компиляторов C. Транслятор создаёт пакетный файл под именем emake.bat, который затем выдаёт все команды, необходимые для компиляции и линковки, автоматически, так что на самом деле у вас нет необходимости знать что-то о C или компиляторах C. Просто введите команду: emakeКогда компиляция и линковка C закончится, у вас появится файл с именем: allsorts.exe, а все файлы исходного кода C будут удалены с диска, чтобы избежать беспорядка.
Когда вы запустите allsorts.exe, всё будет так, будто вы ввели команду
ex allsorts
Как уже было сказано, после создания исполняемого файла команда emake удаляет все файлы C, которые были созданы транслятором. Если вы хотите взглянуть на эти файлы, запустите транслятор ещё раз снова и проинспектируйте файлы C до выдачи команды emake. Примечание для пользователей Linux и FreeBSD:
Примечание для пользователей Borland и Lcc:
Опции командной строки Если у вас на машине скопилось больше одного компилятора C для данной платформы, вы можете уточнить задачу транслятора с помощью опций командной строки:
ecw -bor pretend.exw Обычно после построения вашего .exe-файла пакетный командный файл emake удаляет все файлы C, выработанные вашим транслятором. Если вы хотели бы, чтобы emake сохранил эти файлы до вашей их инспекции, добавьте опцию -keep в командную строку запуска транслятора, например, ec -wat -keep sanity.ex Для того, чтобы выработать .dll-файл Windows, или Linux или FreeBSD .so-файл, просто добавьте в командную строку -dll, например, ecw -bor -dll mylib.ewЧтобы выпустить программу для консоли Windows, а не программу с графическим интерфейсом Windows GUI, добавьте в командную строку -con, например, ecw -bor -con myprog.exwЧтобы увеличить или уменьшить общий объём пространства стека, резервируемого для вашей программы, добавьте в командную строку -stack nnnn, например, ec -stack 100000 myprog.exОбщее пространство стека (в байтах), которое вы задали, будет поделено между всеми задачами, которые исполняются в вашей программе (подразумевается, что там имеется больше одной задачи). Каждая задача имеет своё собственное частное пространство стека. Если выделенное задаче пространство исчерпано, вы получите сообщение об ошибке времени прогона, указывающее на задачу и дающее размер её стекового пространства. Большинство не-рекурсивных задач может исполняться со стеком размера 2000 байт, но чтобы быть в безопасности, вы можете зарезервировать побольше. Глубоко-рекурсивная задача могла бы использовать огромный объём пространства. Это всё зависит от максимального числа уровней вызовов, которые могут требоваться задаче. Во время прогона, по мере того, как ваша программа создаёт всё больше одновременно-активных задач, пространство стека, выделенное каждой задаче, имеет тенденцию уменьшаться. Чтобы создать программу DOS, компилируемую WATCOM, которая использует быстрые машинные инструкции плавающей точки, добавьте в командную строку -fastfp, например, ec -wat -fastfp crunch.exПо умолчанию Euphoria для DOS вызывает подпрограммы, проверяющие доступность машинных инструкций плавающей точки (наличие математического сопроцессора). Если они недоступны, включается более медленный код программной эмуляции. Когда задана опция -fastfp, компилированный код подразумевает наличие сопроцессора. Программы с широким использованием данных с плавающей точкой в этих условиях будут иполняться примерно в два раза быстрее, но они откажутся работать вообще на старых машинах серий 486 и 386, где иногда может не быть сопроцессора. С опцией -fastfp, emake.bat выбирает более быстрые опции компилятора WATCOM C, а также задаёт линковку ecfastfp.lib вместо ec.lib. На всех остальных платформах Euphoria использует быстрые машинные инструкции сопроцессора, отдавая на откуп операционной системе исправление ситуации при отсутствии сопроцессора. Для компилирования вашей программы с отладочной информацией, которая нужна отладчику, совместимому с вашим компилятором, используйте опцию -debug: ecu -debug myapp.exu Иногда бывает полезным линковать ваш транслированный код с библиотекой времени прогона (БВП) Euphoria, отличающейся от поставляемой по умолчанию (стандартной). Эта возможность, вероятно, наиболее полезна для тестирования и отладки собственно БВП или для получения дополнительной отладочной инфорамации при отладке транслированного кода Euphoria. Имейте в виду, что потребителю поставляется только стандартная БВП. Новая особенная БВП должна размещаться в вашем каталоге EUDIR/bin вместе со стандартной. Вот пример использования опции -lib {library}: ecu -lib decu.a myapp.exu
При добавлении в командную строку опции -dll транслятор строит .dll-файл Windows (Linux/FreeBSD .so-файл) вместо .exe-файла исполняемой программы. Вы можете транслировать и компилировать набор полезных подпрограмм Euphoria,а затем делиться ими с другими людьми, не раскрывая перед ними свой исходный код. Более того, ваши подпрограммы будут заметно более быстрыми в транслированном и компилированном виде. И транслированные/компилированные, и интерпретируемые программы смогут использовать эту вашу библиотеку. Только глобальные подпрограммы Euphoria, то есть, те, что объявлены с ключевым словом "global", могут быть экспортированы из библиотек .dll (.so). Любая программа Euphoria, будь то транслированная/компилированная или интерпретируемая, может подключать Euphoria .dll-файл (.so-файл), используя тот же самый механизм, который позволяет вам подключать .dll-файлы (.so-), написанные на C. Данная программа сначала вызывает функцию open_dll(), чтобы открыть .dll-файл или .so-файл, затем она вызывает define_c_func() или define_c_proc() для любых подпрограмм, которые ей необходимо вызвать. Вызов подпрограмм производится с помощью c_func() и c_proc(). Прочтите library.doc, чтобы уяснить детали. Имена подпрограмм, экспортируемых из Euphoria .dll-файла, будут различаться в зависимомти от компилятора C, который вы используете. GNU C на Linux или FreeBSD, экспортирует имена точно в том виде, как они появляются в коде C, выработанном транслятором, например подрограмма Euphoria global procedure foo(integer x, integer y)будет экспортирована как "_0foo" или возможно "_1foo" и т.п. Символ подчерка и цифра добавляются, чтобы предотвратить конфликты имён. Цифра даёт номер файла Euphoria, где имя было определено. Главный файл нумеруется как 0. Библиотечные файлы нумеруются в том порядке, как они встретились компилятору. Вам необходимо будет обратиться к исходному коду C, чтобы быть вполне уверенными в правильности используемых вами имён. Lcc мог бы экспортировать foo() как "__0foo@8", где 8 означает учетверённое число параметров (2). Просмотрите .def-файл, созданный транслятором, чтобы знать все экспортируемые имена. При работе с Borland транслятор также создаёт .def-файл, но в этом .def-файле все экспортированные имена возвращены к их первоначальному виду, который был в вашем исходном коде Euphoria, так что foo() будет экспортирована как "foo". В случае использования Watcom всё происходит, как с Borland, но вместо .def-файла, команда EXPORT для каждого экспортируемого имени размещается в файле objfiles.lnk. С Borland и Watcom вы можете отредактировать .def-файл или файл objfiles.lnk, а затем перезапустить emake.bat, чтобы переименовать экспортируемые идентификаторы, или удалить те, которые вы не хотите экспортировать. С Lcc вы можете удалить идентификаторы, но не можете переименовать их. Вопрос красивых имён для экспортируемых подпрограмм не критичен, так как эти имена появляются только один раз в каждой программе Euphoria, которая использует .dll-файл, т.е. в единственной команде define_c_func() или define_c_proc(). Кроме того, автор .dll-файла мог бы, вероятно, предложить своим пользователям библиотеку-оболочку Euphoria, содержащую необходимые команды define_c_func() и define_c_proc(). Возможно также оформление удобного по форме набора вспомогательных подпрограмм Euphoria для вызова подпрограмм из .dll-файла. Когда вызывается функция open_dll(), все команды Euphoria высшего уровня в файлах .dll или .so выполняются автоматически, совершенно та же, как и в обычной программе. Эта особенность даёт библиотеке возможность инициализировать её структуры данных до первого вызова её подпрограммы. Но для многих библиотек такая инициализация не требуется. Чтобы подать данные Euphoria (атомы и ряды) в качестве аргументов, или получить объект Euphoria как результат, вам потребуются следующие константы библиотеки euphoria\include\dll.e: -- Типы Euphoria для аргументов .dll (.so) и выдаваемых величин: global constant E_INTEGER = #06000004, E_ATOM = #07000004, E_SEQUENCE= #08000004, E_OBJECT = #09000004Используйте их в define_c_proc() и define_c_func() точно так же, как вы используете C_INT, C_UINT и т.д. для вызова .dll и .so C. В настоящее время номера файлов, выдаваемые open(), и номера подпрограмм, выдаваемые routine_id(), могут быть поданы в качестве аргументов и получены как результат, но в библиотеке и в главной программе смысл этих номеров различен. Вместо подачи номера открытого файла, следует подавать имя файла, так, чтобы собственно сами .dll (или .so) и открыли его. К сожалению, простое решение для подачи номеров подпрограмм отсутствует, что может быть восполнено в будущем. Библиотеки Euphoria .dll или .so в настоящее время не могут выполнять никакие операции многозадачности. Транслятор выдаёт об этом сообщение. Библиотеки Euphoria .dll или .so могут быть использованы программами C только в том случае, если 31-разрядные целые в них заменены. Если должны быть поданы 32-разрядные указатель или целое, а у вас имеется исходный код программы C, вы могли бы подать величину в двух отдельных 16-разрядных целых аргументах (верхние 16 разрядов и нижние 16 разрядов), и затем скомбинировать величины в подпрограмме Euphoria в требуемый 32-разрядный атом.
На платформе DOS32 с Watcom, если транслятор находит файлы расширителя CauseWay, cwc.exe и le23p.exe в каталоге euphoria\bin, он добавляет в emake.bat команды, которые обеспечат компрессию результирующего исполняемого файла. Если вам не нужна компрессия, вы можете отредактировать emake.bat, а также удалить или переименовать cwc.exe и/или le23p.exe. На платформах Linux, FreeBSD, Windows, и DOS32 с DJGPP, emake не содержит команды компрессии результирующей программы. Если вы желаете иметь сжатый файл программы, мы рекомендуем опробовать свободный компрессор UPX. Его можно получить здесь: http://upx.sourceforge.net Большие программы, основанные на Win32Lib, преобразованные транслятором в .exe-файлы, могут быть сжаты компрессором UPX до примерно 15% от их оригинального размера, и вы не заметите никакой разницы во времени старта сжатой и несжатой программ. Транслятор, обрабатывая программные файлы, удаляет те подпрограммы, которые не используются, включая стандартные библиотеки Euphoria. После удаления неиспользуемых подпрограмм, он снова ищет такие, которые стали неиспользуемыми, и так далее. Данный процесс может резко уменьшить объём результирующей программы, особенно, когда к программе подключаются большие универсальные библиотеки вроде Win32Lib, многие подпрограммы которых не используются в данной небольшой программе. Тем не менее, ваша откомпилированная программа имеет все шансы оказаться большего размера, чем та же программа, связанная с исполнительным блоком интерпретатора. Такое положение частично является следствием того, что исполнительный блок является сжатым. Плюс команды Euphoria, размещаемые в связанном файле, сами по себе экстремально компактны. Они требуют большего пространства, будучи транслированными на C и компилированными в машинный код. В следующих версиях транслятора мы планируем внедрить дополнительные меры по ускорению и уменьшению вырабатываемых программ.
Все программы Euphoria могут быть транслированы на C, и с очень небольшими исключениями, отмеченными ниже, будут исполняться точно так же, как и с интерпретатором (но быстрее). Интерпретатор и транслятор используют один и тот же пазер, так что вы будете получать все те же сообщения о синтаксических ошибках, о необъявленных переменных и т.д. при работе и с тем, и с другим. Интерпретатор автоматически расширяет объём стека (пока хватает памяти), так что вы можете иметь громадное число уровней вложенных вызовов. Большинство компиляторов C, на большинстве систем, имеет предустановленный предел на размер стека. Обратитесь к документации на свой компилятор и линкер, если вы хотите увеличить этот предел, например, если ваша рекурсивная подпрограмма требует тысяч уровней рекурсии. Измените команду линковки в emake.bat. Для Watcom C используйте OPTION STACK=nnnn, где nnnn - это число байт пространства стека. Примечание:
Вам следует отладить свою программу с интерпретатором. Транслятор осуществляет проверку некоторых ошибок времени прогона, но в интересах скорости их список очень короткий. Если транслированный код C аварийно останавливается, вы обычно получите весьма таинственное сообщение о машинном исключении. В большинстве случаев первое, что вы должны сделать, это запустить свою программу с интерпретатором, используя те же самые вводы, с которыми программа остановилась, и предпочтительно с включенной опцией type_check. Если ошибка возникает только в транслированном коде, вы можете использовать with trace и trace(3), чтобы получить файл ctrace.out, показывающий круговой буфер последних 500 выполненных команд Euphoria. Если сообщение об обнаруживаемой транслятором ошибке отображается (и размещается в файле ex.err), вы также увидите ошибочную строку исходного кода Euphoria всякий раз, когда опция with trace задействована. Опция with trace будет замедлять вашу программу, и это замедление может быть экстремальным, когда опция trace(3) также включена. Как решила RDS, любые исполняемые программы или .dll-файлы, которые вы создаёте с помощью данного транслятора без изменений библиотечного файла транслятора от RDS, могут распространяться без отчислений от гонорара. Вам разрешено свободное включение любых файлов Euphoria, выпущенных RDS в данном пакете, в ваше приложение. В январе 2000 года расширитель DOS CauseWay был передан автором, Майклом Деворе, в общественное достояние. Автор отказался от своих запретительных прав и предоставил каждому желающему возможность пользоваться расширителем свободно, включая коммерческое использование. Вобщем случае, если вы хотите использовать код Euphoria, написанный третьими сторонами, вы должны уважать любые ограничения, которые могут иметь место и отражены в авторской лицензии. В случае сомнений вам следует спросить у автора соответствующее разрешение. На платформах Linux, FreeBSD и DJGPP для DOS32, лицензия GNU Library обычно не будет затрагивать ваши права на программы, созданные с помощью этого транслятора. Простая компиляция с GNU C не даёт Free Software Foundation никакой юрисдикции над вашей программой. Если же вы статически линкуете их библиотеки, вы подпадаете под действие их лицензии Library, но стандартная процедура компиляции/линковки в emake не линкует статически никакие библиотеки FSF, так что здесь не должно быть проблем. Графическая библиотека Allegro, используемая DJGPP, называется в их документации "Giftware", что означает "Подарочный набор", и они позволяют распространять её как часть вашей программы. Они просят только выражения вашей признательности в их адрес, но это не обязательно. Ограничение ответственности:
Различные компиляторы C не одинаковы в части оптимизационных способностей.
Watcom, GNU C и DJGPP вырабатывают наиболее быстрый код. Borland вполне
хорош. Lcc слегка отстаёт, даже при использовании его флага -O.
Borland компилирует наиболее быстро. Watcom компилирует наиболее медленно.
Как правило, типы, определённые вами, не будут снижать скорость. Так как
ваша программа подразумевается свободной от ошибок типов, типы игнорируются
транслятором, если вы не вызываете их непосредственно, как обычные функции.
Здесь есть одно исключение, когда определённая пользователем подпрограмма
типа имеет сторонние эффекты (т.е. она изменяет глобальную переменную,
выполняет обращения к памяти, ввод/вывод и т.п.). В этом случае, если опция
with type_check действует, транслятор
вырабатывает код для вызова подпрограммы типа и сообщает в результате о
любом отказе по проверке этого типа.
На Windows и DOS мы не стали вводить оптимизацию циклов /ol для wcc386
Watcom. Мы обнаружили в паре редких случаев, что эта опция ведёт к выработке
некорректного машинного кода, выдаваемого компилятором Watcom C.
Если вы добавите её в свою версию файла emake.bat, вы, возможно,
получите небольшое улучшение в скорости за счёт увеличения риска аварий
из-за ошибочного кода. Для DJGPP вы могли бы опробовать -O6 вместо -O2.
Для DOS мы используем опцию Watcom /fpc, которая обеспечивает вызовы
подпрограмм, выполняющих операции с плавающей точкой. Если на машине имеется
математический сопроцессор, он используется подпрограммами, в противном
случае он эмулируется программно. Такое решение несколько уменьшает скорость
и не требуется на машинах с Pentium, но оно гарантирует, что ваша программа
будет работать на всех 386-х и 486-х компьютерах, даже если там нет
сопроцессора. Библиотека времени прогона дла DOS,
ec.lib, была построена именно таким
путём, поэтому вы не можете просто удалить эту опцию.
На Linux или FreeBSD вы можете опробовать опцию gcc (GNU C) O3 вместо O2.
В этом случае компилятор "выстраивает" небольшие подпрограммы, слегка
поднимая скорость, но увеличивая размер программы. Вы можете также испытать
Компилятор Intel C++ для Linux. Он считается совместимым с GNU C, но
некоторые подстройки в emake могут понадобиться. Многие большие программы были успешно оттранслированы и откомпилированы с ипользованием каждого из поддерживаемых нами компиляторов C, и транслятор представляется теперь совершенно стабильным. Примечание:
Иногда очень большая подпрограмма Euphoria при трансляции на C может оказаться слишком большой для обработки компилятором C. Если вы столкнётесь с этой проблемой, постарайтесь упростить и уменьшить свою подпрограмму Euphoria. Вы можете также попытаться отключить оптимизацию C в emake.bat именно для того .c-файла, который даёт отказ. Иногда помогает разбиение единственного большого объявления группы констант на несколько маленьких объявлений или даже индивидуальных для каждой константы. Euphoria не имеет ограничений на размер подпрограммы или на размер файла, но большинство компиляторов C имеет такие ограничения. Транслятор будет автоматически вырабатывать множество маленьких .c-файлов из большого файла Euphoria, чтобы избежать перегрузки компилятора C. Тем не менее, он не может переделать большую подпрограмму в несколько маленьких.
Присылайте отчёты об ошибках на EUforum.
|