Транслятор с Euphoria на C
версия 2.3, Официальный выпуск от 11 февраля 2002 г.
(с поддержкой для FreeBSD от 18 апреля 2002 г.).

Введение

Транслятор с Euphoria на C предназначен для перевода любых программ, написанных на Euphoria, в эквивалентный исходный код C. RDS предлагает версии этого транслятора для платформ Windows, DOS, Linux и FreeBSD. После перевода программы Euphoria на C вы можете компилировать код C и компоновать его с помощью одного из поддерживаемых компиляторов C. Это даст вам исполняемый файл, который в типовых случаях будет намного более быстрым, чем если бы вы использовали интерпретатор Euphoria.

Установка

Подразумевается, что вы уже установили на своей системе пакет интерпретатора Euphoria 2.3, и что ваши переменные окружения EUDIR и PATH имеют правильные значения.

Для каждого поддерживаемого компилятора C, под Windows, DOS, Linux или FreeBSD, на узле RDS имеется соответствующий .ZIP-файл, содержащий файлы:

     1. транслятор (один на платформу)
           
           ec.exe  - DOS 
           ecw.exe - Windows 
           ecu     - Linux 
           ecu     - FreeBSD
     
     2. библиотека времени прогона (одна на компилятор C)
           
           ec.lib   - DOS (Watcom)
           ec.a     - DOS (DJGPP)
           ecw.lib  - Windows (Watcom)
           ecwl.lib - Windows (LccWin)
           ecwb.lib - Windows (Borland)
           ecu.a    - Linux (GNU)
           ecu.a    - FreeBSD (GNU)
 
     3. включаемый (заголовочный) файл C
           
           euphoria.h - один и тот же для всех платформ и компиляторов

     4. (только Watcom) файлы для поддержки расширителя DOS CauseWay

           cwc.exe    - файловый компрессор
           le23p.exe  - преобразователь формата
           cwstub.exe - расширитель DOS
   
     5. (только DJGPP) Графическая библиотека Allegro, откомпилированная
           специально для транслятора. Получите liballeg.zip
  
Чтобы установить транслятор с Euphoria на C, скопируйте файл euphoria.h в ваш каталог euphoria\include, и скопируйте все остальные файлы .exe и библиотечные файлы в каталог euphoria\bin. Примечание: файл liballeg.zip имеет особое положение. Он должен быть распакован и размещен в каталоге DJGPP\LIB как liballeg.a.

Поддерживаемые компиляторы C

Транслятор в настоящее время работает с GNU C под Linux или FreeBSD, с WATCOM C или DJGPP C под DOS и с Watcom C, LccWin или Borland 5.5 под Windows. Воплощения WATCOM и GNU C на 100% совместимы с интерпретатором Euphoria. Другие совместимы ориентировочно на 99%. Мы отдаем предпочтение Borland перед LccWin. Borland компилирует быстрее, вырабатывает лучший код и имеет меньше ошибок в сравнении с LccWin.

Транслятор был оттестирован с теми версиями GNU C и библиотек ncurses, которые поступают с ОС Red Hat 5.2 и FreeBSD 4.5 или более новыми.

Транслятор был проверен с WATCOM C/C++ 9.5, 10.6 и 11.0. WATCOM 11.0 скоро будет открытым и свободным. Поищите его на узле: http://www.openwatcom.org

Пакет для Watcom DOS32 включает расширитель DOS CauseWay и компрессор файлов. CauseWay открыт и свободен. Вы можете узнать подробности о нем на узле: http://www.devoresoftware.com. Командные файлы emake.bat и objfiles.lnk присоединяют расширитель CauseWay к вашей программе автоматически. Другие расширители DOS, такие как DOS4GW, работали бы с транслятором хуже.

Транслятор проверяет переменные окружения "WATCOM", "LCC", "BORLAND" или "DJGPP" или же каталоги в команде PATH. Он будет генерировать файл emake.bat, который вызывает соответствующий компилятор и компоновщик.

Примечания:

В отличие от WATCOM, DJGPP не отображает нижнюю память DOS в том же самом сегменте, что и остальную память. Подпрограммы машинного кода, написанные для интерпретатора или транслятора Euphoria, основанных на WATCOM, не будут работать с DJGPP и будут, вероятно, "подвешивать" систему при попытках обращения к нижней памяти, такой как видеопамять. Функции Euphoria peek(), poke(), mem_copy(), mem_set() и т.д. *будут* работать корректно, так как транслятор использует специальную макрокоманду DJGPP для доступа к нижней памяти. Вы можете предназначить эти подпрограммы машинного кода и для DJGPP, но тогда вам потребуется изучение документации DJGPP для поиска возможных путей доступа к нижней памяти.

DJGPP полностью поддерживает длинные имена файлов на чтение, запись и создание. WATCOM не поддерживает создание.

DJGPP поддерживает больше текстовых режимов, например, 35 строк.

DJGPP позволяет пользователю прервать программу в любой момент нажатием control-c.

Воплощение для LccWin игнорирует lock_file() и unlock_file(). Эти функции не выполняют никаких действий.

Представляется, что новейшая версия LccWin содержит некоторые ошибки, которых не было в более ранних версиях. В большинстве случаев, если LccWin доставляет вам любые беспокойства, вы можете избежать их в дальнейшем, удалив флаг оптимизации -O из строки одного или нескольких файлов в emake.bat.

Предупреждения отключены во время компиляции по командам emake.bat. Если вы включите их, вы сможете увидеть несколько безобидных сообщений об объявленных, но неиспользуемых переменных, назначенных, но неиспользуемых метках, необъявленных прототипах функций и т.п.

Под Windows компоновщик WATCOM выводит сообщение, что он не может открыть graph.lib. Вы можете игнорировать это сообщение, так как graph.lib не используется. Но, видимо, простого пути для подавления этого сообщения не существует.

Компилятор Microsoft C++ для Windows пока не поддержан. Тем не менее, вы, вероятно, можете импортировать файлы C, выработанные ecw.exe, и файл библиотеки времени прогона для Borland, Lcc или Watcom в проект Microsoft, а затем компилировать/компоновать программу при очень небольших правках.

Запуск транслятора

Запуск транслятора похож на запуск интерпретатора. Из приглашения DOS введите:

 
       ec shell.ex
    или 
       ec shell
 

при этом вместо исполнения программы shell.ex транслятор создаст несколько файлов исходного кода C. Будет также создан командный файл с именем emake.bat - пакетная программа, которая выполнит все действия, необходимые для компиляции и компоновки исполняемого C-файла. Просто введите: emake

Когда компиляция и компоновка C закончатся, вы получите файл с именем: shell.exe

Если вы запустите shell.exe, он будет исполняться точно так же, как если бы вы ввели команду ex shell для того, чтобы работать с интерпретатором, но прогон будет более быстрым, с выполнением большего числа "сортировок в секунду".

Примечание для пользователей Linux и FreeBSD: у файлов будут имена emake и shell, и вы должны будете ввести ./emake, чтобы выполнить компиляцию и компоновку, и ./shell, чтобы запустить программу сортировки shell.

Если вам случится иметь больше одного компилятора C для платформы, с которой вы работаете, вы можете выбрать необходимый вам компилятор, задавая параметры командной строки:

        -bor
        -lcc
        -wat
        -djg
 

в строке запуска ec или ecw, т.е.

        
         ecw -bor кандидат.exw
 
Чтобы создать для Windows .dll-файл, а также для Linux или FreeBSD .so-файл, просто добавьте "-dll" в командную строку, т.е.
         ecw -bor -dll mylib.ew
 

Примечание: Для LccWin и Borland нет стандартной переменной окружения, поэтому транслятор будет искать каталог необходимого компилятора в переменной PATH. Он просматривает стандартные места, такие как: ..\LCC, ..\BCC.., ..\Borland.. и т.д. Если вы установили компилятор в нестандартном месте, может потребоваться переименование каталога установки.

Библиотеки времени прогона (Общие библиотеки)

При простом добавлении "-dll" в командную строку транслятор будет строить файл Windows .dll (Linux/FreeBSD .so) вместо исполняемой программы.

Вы можете оттранслировать и откомпилировать набор полезных подпрограмм 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 для уточнения деталей.

Наименования подпрограмм, экспортируемых из 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), умноженное на 4. Вы можете обратиться к файлу .def, созданному транслятором, чтобы увидеть все экспортированные имена.

Для Borland транслятор также создает файл .def, но в этом .def-файле экспортированные идентификаторы переименованы так, какими они были в вашем исходном тексте Euphoria, то есть, foo() будет экспортирована как "foo".

Для WATCOM производится такое же переименование как и для Borland, но вместо создания отдельного файла .def к каждому экспортированному идентификатору в файле objfiles.lnk добавляется команда EXPORT .

С 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 и т.д. для вызова C .dll и .so.

Компилятор Lcc несовместим в том смысле, что вы не можете выдавать общий объект Euphoria (кроме 31-разрядных целых) из .dll, выработанной Lcc, в программу, откомпилированную Borland или WATCOM, или в программу, исполняемую exw. Величина может выглядеть нормальной, но от авоста вы не застрахованы. Аналогично, программа, откомпилированная Lcc, не может обрабатывать общие объекты Euphoria, выдаваемые библиотеками .dll WATCOM или Borland. С подаваемыми данными проблем нет. Только общие *выдаваемые* величины страдают этим недостатком. Это может быть исправлено в будущем.

На текущий момент номера файлов, выдаваемые open(), и идентификаторы, выдаваемые routine_id(), могут быть поданы и выданы, но библиотека и главная программа имеют каждая свои собственные разные виды на то, что означают эти номера. Но вместо подачи номера открытого файла вы можете подавать имя файла, позволяя библиотеке .dll (.so) самой открыть его. К сожалению, простое решение для подачи идентификационных номеров процедур пока отсутствует. Это также может быть исправлено в будущих выпусках.

Библиотеки Euphoria .dll (.so) могут быть использованы программами C только при обмене 31-битными целыми величинами.

Размеры исполняемых файлов и компрессия

Под DOS32 с Watcom, если транслятор находит файлы CauseWay, cwc.exe и le23p.exe, в каталоге euphoria\bin, он добавляет в emake.bat команды, чтобы сжать ваш исполняемый файл. Если вам компрессия не нужна, вы можете изменить emake.bat или удалить (переименовать) cwc.exe и/или le23p.exe.

Под Linux, FreeBSD, Windows и DOS32 с DJGPP в emake нет команды на сжатие исполняемого файла. Если вам необходима компрессия, мы рекомендуем вам опробовать свободный компрессор UPX. Вы можете получить UPX с узла: http://upx.tsx.org

Транслятор не обрабатывает подпрограммы, которые не используются, даже те, которые находятся в стандартных библиотечных файлах Euphoria. После такого пропуска неиспользуемых подпрограмм производится снова проверка, но уже тех подпрограмм, которые стали неиспользуемыми и т.д. Этот метод ведет к значительным выигрышам, особенно с программами, базирующимися на Win32Lib, которая имеет большой библиотечный файл в то время как многие из его подпрограмм часто в данной программе не используются.

Тем не менее, ваш откомпилированный исполняемый файл имеет все шансы оказаться больше, чем та же самая программа Euphoria, связанная с интерпретатором. Частично это результат компрессии интерпретатора. Кроме того, операторы Euphoria имеют экстремально компактную форму, когда размещены в связанном файле. Но им требуется больше места после перевода на C и компиляции в машинный код. Последующие версии транслятора будут давать менее объемные и более быстрые исполняемые файлы.

Интерпретатор против транслятора

Громадное большинство программ Euphoria может быть оттранслировано и в таком виде будет исполняться точно так же (но, надеемся, быстрее).

Интерпретатор и транслятор имеют единый контроль правописания, поэтому вы будете получать те же самые синтаксические ошибки, ошибки объявления переменных и т.д. и с интерпретатором, и с транслятором.

Но транслятор читает всю вашу программу до конца, прежде чем начать что-либо транслировать. Поэтому иногда он может схватить синтаксическую ошибку, которую интерпретатор еще не увидел, так как интерпретатор начинает выполнение операторов высшего уровня немедленно, не ожидая конца вашей программы. Это означает также, что, если в вашей программе есть операторы высшего уровня, которые модифицируют файл, включаемый позже, вы получите другой результат с транслятором. Но очень немногие программы используют технику этих "динамических включений".

Заметьте: транслятор считает, что в вашей программе нет ошибок времени прогона, которые могли бы быть обнаружены интерпретатором. Транслятор не проверяет: индексы вне границ, неинициализированные переменные, присвоение переменным незаконных значений и т.д.

Вы должны отладить программу с интерпретатором. Когда отказывает код C, у вас обыкновенно появляется только весьма таинственное машинное исключение. Если ваша оттранслированная программа .exe сбоит, первым вашим действием должен быть запуск исходного кода под управлением интерпретатора с использованием тех же самых входных воздействий, предпочтительно с включенным режимом "type_check".

Но некоторые из подпрограмм времени прогона еще способны обнаружить ошибку и выдать сообщение в файл "ex.err".

Правовые ограничения

Поскольку RDS не возражает, любые исполняемые программы, которые вы создаете с этим транслятором, могут распространяться без отчислений гонорара. Вы можете свободно вводить в ваш программный продукт любые файлы Euphoria, предлагаемые RDS.

Вы не можете распространять любой транслятор Complete Edition или любой библиотечный файл, который поступает в пакете Complete Edition для любой из платформ.

Вы не можете распространять любые взломанные (подвергнутые обратной переработке) версии любой библиотеки или транслятора, будь то часть пакета Public Domain или Complete Edition.

В январе 2000 г. расширитель DOS CauseWay был дарован в общественное владение автором, Майклом Деворе. Он отказался от своего копирайта, и разрешил использовать расширитель свободно, включая коммерческие цели.

В общем случае, если вы хотите использовать код Euphoria, написанный кем-то еще, а не вами, следует соблюдать любые ограничения, которые предусмотрены автором. В случае сомнений вы должны их разрешить, обратившись к автору.

Под Linux, FreeBSD и DJGPP для DOS32 лицензия GNU Library обычно не будет применима к программам, созданным этим транслятором. Простая компиляция с GNU C не дает Free Software Foundation никаких прав на вашу программу. Если вы статически подключаете их библиотеки, это приводит в действие их лицензию Library, но стандартная процедура компиляции/компоновки в emake не подключает статически никакие библиотеки FSF, поэтому здесь не должно быть проблемы. Библиотека ncurses является единственной статически подключаемой, и хотя сейчас Free Software Foundation владеет копирайтом, библиотека ncurses не может рассматриваться как объект лицензии GNU Library, так как она была дарована FSF авторами, которые не хотели применения к ней лицензии GNU. Прочитайте справку о копирайте в ncurses.h.

Ограничение ответственности: Здесь изложено наше мнение о вопросе. Мы не юристы. Если это важно для вас, вы должны прочитать лицензию GNU Library, лицензию ncurses, комментарий о правах в DJGPP, LccWin и Borland, а также файл read.me на узле Майкла Деворе, чтобы составить свое собственное мнение.

Транслятор редакции Public Domain

Программы (включая .dll и .so), созданные с использованием свободного транслятора редакции Public Domain, выводят на экран короткое сообщение перед началом работы.

Транслятор редакции Complete Edition

Регистрируя транслятор Complete Edition, вы получаете:

Сколько это стоит ?

Транслятор Complete Edition с Euphoria на C доступен сейчас всего за $29.00 U.S. Эта цена покрывает все платформы. Вы можете регистрироваться через DigiBuy на нашем узле Web, www.RapidEuphoria.com, или послать чек:

      Rapid Deployment Software
      130 Holm Crescent
      Thornhill, Ontario
      L3T 5J3
      CANADA
 

Когда вы получаете транслятор Complete Edition с нашего узла, отпадают расходы на пересылку и доставку. Если вы хотите, чтобы мы прислали вам диск и квитанцию, пожалуйста, добавьте $5.00, все станет в $34.00 U.S.

Часто задаваемые вопросы

* На какое приращение скорости можно расчитывать?

Все это зависит от того, на что ваша программа тратит время. Программы, которые в основном работают с целыми числами, не слишком часто вызывают функции и не делают много операций ввода/вывода, покажут наибольшее улучшение, пока около 5-кратного. Другие программы могут дать вам всего несколько процентов. Различные компиляторы C имеют разные оптимизационные возможности. WATCOM, GNU C и DJGPP вырабатывают наиболее быстрый код. Borland вполне хорош. LccWin несколько отстает от других. Borland компилирует наиболее быстро. Watcom самый неторопливый.

* Могу ли я зарегистрировать транслятор до того, как зарегистрирую пакет интерпретатора?

Отладка больших программ пойдет намного проще, если у вас будет интерпретатор Complete Edition. В идеале вы должны разработать и полностью отладить код с интерпретатором, а транслятор использовать только на последнем этапе для разгона скорости. Тем не менее, вы можете купить интерпретатор и транслятор врозь, а недостающий пакет приобрести позже.

* Что если я хочу изменить режимы компиляции или компоновки в emake.bat?

Не стесняйтесь делать это, однако лучше скопировать emake.bat в ваш собственный файл с именем (скажем) mymake.bat, а затем запустить уже mymake.bat после окончания работы транслятора. Иногда число файлов .с, выработанных транслятором, может измениться.

* Как еще больше разогнать мою программу?

Важно объявлять переменные как целое (integer) везде, где можно. В общем случае, ускорению способствует выбор наиболее конкретных типов при объявлении переменных. Пользовательские типы не будут снижать скорость. Они игнорируются транслятором, если вы не вызываете их и прямо, как нормальную функцию. Под Windows и DOS мы отказались от /ol оптимизации циклов для wcc386 Watcom. Мы обнаружили в паре редких случаев, что этот режим приводил к генерации некорректного машинного кода, выдаваемого компилятором WATCOM C. Если вы вернетесь к этому режиму в своей версии emake.bat, вы сможете слегка увеличить скорость, слегка увеличив риск получения "блохастого" кода. С DJGPP вы можете попробовать применить режим -O6 вместо -O2. Для DOS мы используем режим WATCOM /fpc, который генерирует вызовы процедур времени прогона для выполнения операций с плавающей точкой. Если на машине есть математический сопроцессор, он будет использоваться процедурой, если сопроцессора нет, он эмулируется программно. Этот режим несколько снижает скорость и не требуется на машинах с Pentium, но зато гарантирует, что ваша программа будет исполняться на всех 386 и 486 машинах, даже если на них нет сопроцессора плавающей точки. Библиотека времени прогона для DOS, ec.lib, была построена именно этим путем, поэтому вы не можете просто удалить этот режим. Под Linux или FreeBSD вы можете испытать режим O3 в gcc вместо O2. Этот режим будет выстраивать маленькие процедуры "в-линию", несколько разгоняя, но увеличивая файл. Имеется улучшенная версия gcc, под названием pgcc, которая претендует на добавочную оптимизацию для процессоров Pentium. Мы испытали ее, но она дала нам только очень небольшое (пара процентов) ускорение. Она доступна свободно на узле: http://goof.com/pcg/

Общие проблемы

Множество больших программ было успешно оттранслировано и откомпилировано с использованием каждого из поддерживаемых компиляторов C, и транслятор теперь вполне стабилен.

N.B. Весьма часто: Lcc может жаловаться на неопределенный идентификатор, или на слишком длинный идентификатор. Это проявление ошибки в оптимизаторе Lcc. Просто удалите опцию -O в emake.bat при построении такого особенного файла. Например, если жалоба касается xyz.obj, удалите опцию -O для шага, где компилируется файл xyz.c. В редких случаях -O может не вызывать ошибку времени компиляции, но вырабатывать ошибочный машинный код, ведущий к отказу.

N.B. Если вызывается функция C в файле Windows .dll, убедитесь, что эта функция использует соглашение __stdcall (в противоположность __cdecl, которое действует по умолчанию в большинстве компиляторов C). Если этого не сделать, вызов может *казаться* работающим, но вы будете получать повреждение стека вызова. Это повреждение может не проявиться под управлением интерпретатора и дать о себе знать только при прогоне оттранслированного/откомпилированного кода.

В некоторых случаях громадная подпрограмма Euphoria, будучи переведена на C, оказывается слишком большой для обработки компилятором C. Если вы столкнетесь с такой проблемой, сделайте свою подпрограмму Euphoria меньше и проще. Вы можете также попытаться отменить оптимизацию C в emake.bat только для того файла .c, который вызывает отказ. Разбивка единственного объявления констант на несколько последовательных объявлений вплоть до отдельного объявления для каждой константы также может помочь. Euphoria не имеет ограничений на размер подпрограммы или размер файла, но большинство компиляторов C имеют. Транслятор будет автоматически вырабатывать множественные маленькие файлы .c из большого файла Euphoria, чтобы избежать перегрузок компилятора C. Но он не станет, тем не менее, разбивать большую подпрограмму на меньшие.

Посылайте сообщения об ошибках на rds@RapidEuphoria.com В частности, дайте нам знать, если какая-то оттранслированная программа не будет делать после компиляции то же, что она делает у интерпретатора.