Euphoria → C言語トランスレータ
1. はじめに Euphoria → C言語トランスレータは任意のEuphoriaプログラムと等価なC言語ソースコードへ翻訳・変換します。 トランスレータにはWindows, DOS, Linux および FreeBSD版があります。 EuphoriaプログラムをC言語ソースコードに翻訳後、対応するコンパイラのうち1を使用してコンパイルとリンクができます。これにより普通にEuphoriインタプリタを使用するのと比べて非常に高速に動作する実行可能ファイルが生成されます。 トランスレータ*自身*は動作環境ごとに翻訳/コンパイルして実行可能ファイルにすることができます。トランスレータはインタプリタのフロントエンドの一部であり翻訳/コンパイルで使用されます。トランスレータのソースコードはeuphoria\sourceにあります。これは全てEuphoriaで記述されています。 現在のところトランスレータはLinuxまたはFreBSD上のGNU Cや、DOS上の OpenWatcom CまたはDJGPP Cの双方、Windows上のOpenWatcom C, LccまたはBorland C++ Compiler 5.5の3種類で動作します。これらは全て無償提供されています。GNU CはLinuxまたはFreeBSDシステムにおいて標準でインストールされています。その他は各ウェブサイトからダウンロードできます。WindowsではLccよりOpenWatcom CまたはBorland C++ Compiler 5.5の使用を強く推奨します。Lccの開発は活発であり改良され続けてはいるものの、いくつかバグがあるため巨大なWindowsプログラムを正常にコンパイルすることが困難です。OpenWatcom CまたはBorland C++ Compiler 5.5では正常にコンパイルできます(訳注:この記述は当時(2005年以前)のものであり現在のバージョン(和訳時点では2009.12.02)では既に改善されているものと思われます)。OpenWatcom Cのほうがやや小さくて高速な実行ファイルを生成できますが、大量のC言語ソースをコンパイルすときはBorland C++ Compiler 5.5のほうが高速です。 OpenWatcom CのDOS32版にはCauseWay DOSエクステンダとファイル圧縮ツールが含まれています。現在ではCauseWayは無償のオープンソースです。 emake.bat および objfiles.lnk は自動でCauseWay DOSエクステンダをリンクします。その他DOS4GWのようなDOSエクステンダではトランスレータは正常に動作しません。 トランスレータは環境変数 "WATCOM", "LCC", "BORLAND" または "DJGPP" とディレクトリのパスの両方を調べます。 これは、コンパイラとリンカを適切に起動させるためのバッチファイルemake.bat を生成します。 注意事項:
トランスレータの実行方法はインタプリタと似ています。DOS版を実行するにはこのように入力します: ec allsorts.ex または ec allsortsWindows版を実行するにはこのように入力します: ecw taskwire.exw または ec taskwireLinux/FreeBSD版を実行するにはこのように入力します: ecu qsort.exu または ec qsortしかし、トランスレータはallsort.exプログラムを実行する代わりにC言語ソースファイルをいくつか作成します。誰でもトランスレータを実行できます。これはインタプリタと共にeuphoria\binにあります。C言語ファイルのコンパイルとリンクには対応するC言語コンパイラのうち1つをインストールする必要があります。Tトランスレータはコンパイルとリンクを全て行えるバッチファイル emake.batを作成しますが、実際のところC言語またはC言語コンパイラについての知識は不要です。この作業を行うには次のように入力します: emakeコンパイルとリンク完了後、次の名前のファイルが作成されます: allsorts.exe なお、散乱した不要なC言語ソースは削除されます。
allsorts.exeを実行するのは、次を入力して実行するのと同等です:
ex allsorts
実行ファイル作成後、emakeは作成されたC言語ファイルを削除します。これらファイルを閲覧するには、もう一度トランスレータを実行してemakeを実行する前にファイルを閲覧してください。 LinuxおよびFreeBSD利用者への注意事項:
BorlandおよびLcc利用者への注意事項:
コマンドラインオプション 特定の動作環境でプログラムを使い分けるために複数のC言語コンパイラがインストール済みであれば、コマンドラインオプションで使用したいものを選択できます:
ecw -bor pretend.exw 通常は、emakeバッチファイルにより.exeファイルのビルドが行われ、その後トランスレータで生成されたC言語ファイルとオブジェクトファイルは削除されます。これらのファイルを残しておきたいならば、トランスレータのコマンドラインオプションとして-keepオプションを付加します。すなわち、 ec -wat -keep sanity.ex Windows .dllファイル、 または Linux または FreeBSD .so ファイルを作成するには、コマンドラインオプションとして -dll を付加します。すなわち、 ecw -bor -dll mylib.ewWindows GUIプログラムではなくWindowsコンソールプログラムを作成するには、コマンドラインオプションとして -con を付加します。すなわち、 ecw -bor -con myprog.exwプログラムで使用する予約済みスタック領域の合計を増減するには、コマンドラインオプションとして -stack nnnn を付加します。すなわち、 ec -stack 100000 myprog.ex指定された合計スタック領域(バイト単位)は、実行中のタスク間で分配されます(1つ以上実行されているものと仮定します)。タスクごとに自身のプライベートなスタック領域があります。スタックの割り当てを超過したとき、そのスタック領域を使用しているタスクを識別してランタイムエラーメッセージを表示します。多くの非再帰的タスクは2000バイト程度の小規模なコールスタックで実行できますが、安全のために、これより多くしたほうが良いです。非常に深い再帰的タスクは非常に多くの領域を使用します。それは必要とするタスクの最大呼び出し回数に全て依存します。実行時にプログラムは平行動作するタスクを生成しますが、その場合はタスクごとに割り当てられるスタック領域は減少する傾向があります。 WATCOMでコンパイルを行った高速なハードウェア浮動小数点インストラクションを使用したDOSプログラムを作成するには、コマンドラインオプションとして -fastfp を付加します。すなわち、 ec -wat -fastfp crunch.ex規定値では、DOS版Euphoriaはハードウェア浮動小数点インストラクションが利用可能かどうか判別するためにルーチンを呼び出します。使用できない場合は、やや遅いソフトウェアエミュレーションコードが使用されます。-fastfp が指定されると、コンパイル済みコードはハードウェア浮動小数点があるとみなします。しかし、古い386および486系CPUではハードウェア浮動小数点が搭載されてない場合があるため実行に失敗することがあります。-fastfpを指定したとき、 emake.batはWATCOM Cコンパイラにおいて(出力バイナリに対して)高速化オプションを選択して、さらにemake.batはec.libの代わりにecfastfp.libを必ずリンクします。 その他全ての動作環境では、Euphoriaはハードウェア浮動小数点インストラクションを使用しており、ハードウェア浮動小数点がなくてもオペレーティングシステム側で対応しているためソフトウェアで浮動小数点を扱うことができます。 コンパイラと互換性のあるデバッガを使用するために、プログラムにデバッグ情報をつけてコンパイルするには -debug オプションを使用します: ecu -debug myapp.exu 時として翻訳済みコードを標準ライブラリ以外のEuphoriaランタイムライブラリとリンクすることは有用です。この機能は、主にランタイムライブラリ自身のテストやデバッグするのに非常に有用であり、さらに翻訳済みのEuphoriaコードにデバッグするときに追加のデバッグ情報を与えることもできます。標準ライブラリのみ提供されることに注意してください。カスタムライブラリは標準ライブラリと共に EUDIR\binディレクトリに格納する必要があります。これには-lib {ライブラリ}オプションを使用します: ecu -lib decu.a myapp.exu 単にコマンドラインに-dllを付加すると、トランスレータは実行可能プログラムファイルの代わりに Windows .dll (Linux/FreeBSD .so)をビルドします。 実用性のあるEuphoriaルーチン一式を翻訳およびコンパイルでき、ソースの配布なしで他の人々と共有することができます。さらに、翻訳およびコンパイルされたルーチンは非常に高速な動作をするようになります。翻訳/コンパイル済みおよびインタプリタプログラムは両方もライブラリを使用することができます。 すなわち、"global"キーワードで宣言されたグローバルなEuphoria手続きおよび関数のみ .dll (.so)としてエクスポートできます。 翻訳/コンパイル済みまたはインタプリタで実行されるかに関係なく、Euphoriaの.dll (.so)はC言語で記述された.dll (.so)と同じ仕組みでリンクできます。最初にプログラムでopen_dll()を呼び出して.dllまたは.soファイルを開き、次に任意の呼び出したいルーチンに対してdefine_c_func() または define_c_proc() を呼び出します。最後に c_func() およびc_proc()を使用してルーチンを呼び出します。詳細情報はlibrary.docを参照してください。 Euphoriaの.dllからエクスポートされたルーチン名は、どのC言語コンパイラを使用するかによって異なります。 Linux or FreeBSD上のGNU Cではトランスレータによって生成されたC言語コードは正確な名前でエクスポートされます。すなわちEuphoriaルーチンのことです。 global procedure foo(integer x, integer y)"_0foo" あるいは "_1foo" などの名前でエクスポートされます。下線と数値は衝突を防ぐために付加されます。数値はシンボルが定義されたEuphoriaファイルを参照します。メインファイルには0が番号付けされます。インクルードファイルはコンパイラが遭遇した順に番号付けされます。よってC言語ソースを調べる必要があります。 Lccはfoo()を"__0foo@8"としてエクスポートを行いますが、8の部分はパラメータの総数(foo()の場合は2つ)を4倍(あるいは2倍)したものです。トランスレータにより作成された.defファイルを調べることによりエクスポートされた全ての名前の一覧を見ることができます。 トランスレータはBorland用の.defファイルを作成しますが、この.defファイルでは、Euphoriaソースで使用されている同名のエクスポート済みシンボルの名前が変更されているため、foo()はfooという名前でエクスポートされます。 WatcomはBorlandと同様に名前の変更が発生しますが、.defファイルではなくエクスポートされたシンボルごとにEXPORTコマンドが付加されobjfiles.lnkへ出力されます。 BorlandとWatcomでは.defまたはobjfiles.lnkを編集でき、emake.batを再実行することにより、シンボルの名前を変更したり、またはエクスポートしたくないシンボルを削除できます。Lccではシンボルを削除できますがシンボルの名前を変更できません。 すなわち単一のdefine_c_func()またはdefine_c_proc()命令文において、Euphoriaプログラムは使用する各.dllで名前が必要になったとき一度だけ参照するため、良いエクスポート名であることは重要ではありません。.dllの作者は利用者が必要とするdefine_c_func()および define_c_proc()命令文を含むEuphoriaインクルードファイルを提供する必要があり、さらに.dllにあるルーチンを呼び出すためにEuphoria"ラッパー"ルーチン一式を提供しても良いでしょう。 open_dll()を呼び出したとき、通常のプログラムのように、.dllまたは.so内の先頭にあるEuphoria命令文は自動的に実行されます。これはライブラリから最初にライブラリルーチンを呼び出す前にデータ構造を初期化する機会を与えます。多くのライブラリでは初期化は不要です。 Euphoriaデータ(アトムまたはシーケンス)を引数として渡すか、結果をEuphoriaオブジェクトとして受け取るには、euphoria\include\dll.eにある次の定数を使用する必要があります: -- .dll (.so)にて使用するEuphoria型の引数および返値: global constant E_INTEGER = #06000004, E_ATOM = #07000004, E_SEQUENCE= #08000004, E_OBJECT = #09000004現在、.dllおよび.soの呼び出しでdefine_c_proc() および define_c_func() を使用するとき C_INT, C_UINTなどを利用することができます。 現在、ファイル番号はopen()により返され、ルーチンidはroutine_id()によって返されて、それらはライブラリに渡したり返してもらうことができますが、これらの番号の意味はライブラリとメインプログラムごとに存在する個別の概念です。開いているファイル番号の代わりに、.dll(.so)にファイル名を渡して開けさせることができます。.dll (.so) open it.残念なことにルーチンidを渡すための単純な方法はありません。これは将来修正される場合があります。 現在のEuphoriaの.dllまたは.soでマルチタスク操作を実行できません。これについてはトランスレータではエラーメッセージを出力します。 31bitの整数値のみ交換する限り、Euphoriaの.dll(.so)をC言語プログラムで使用することができます。32bitポインタまたは整数を渡す必要があり、C言語プログラムのソースがあるとき、引数の値を2つの16bit整数に分けて渡すようにすると(上位16bitおよび下位16bit)、Euphoriaルーチンで必要とされる32bitアトムへと値を変換します。 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はUPX: the Ultimate Packer for eXecutables - Homepageから入手できます。トランスレータにより生成された巨大なWin32Libを使用した.exeはUPXを使用すると元のサイズより15%も圧縮でき、ほとんど起動時間に差はありません。 トランスレータは標準Euphoriaインクルードファイルを含む未使用ルーチンを削除します、未使用ルーチンを削除後に、その影響で未使用になった多数のルーチンを調査します。特にWin32Libを使用した巨大ファイルを含むプログラムにおいて、インクルードされたルーチンの大部分はプログラムでは使用されないため、これにより大きな違いがでます。 しかしながら、コンパイルされた実行可能ファイルはバックエンド・インタプリタとバインドされた同一のプログラムよりも大きくなることがあります。これはバックエンド部分が圧縮済み実行可能ファイルであるためです。さら、バインド済みファイルを保存するときEuphoria命令文は非常に小さくなるからでもあります。またC言語コードに翻訳され、コンパイル後に機械語となったプログラムは、より多く空き領域を必要とします。将来のバージョンのトランスレータでは、より早くより小さな実行可能ファイルを生成できるようになる予定です。 全てのEuphoriaプログラムはC言語へ翻訳することができ、注意すべき後述の一部の例外を除き、インタプリタと同様に実行できます(うまくいけば高速動作します)。 インタプリタとトランスレータは同じ構文解析器を共用しており、どちらでも同一の文法エラー、変数未定義エラーなどを得ることができます。 インタプリタは自動的にコールスタック拡張して(メモリー不足になるまで)、膨大な数の入れ子階層になった呼び出しを扱うことができます。 多くのC言語コンパイラ、多くのシステムでは、あらかじめスタックの大きさ決定されており制限されています。制限を緩和したいときは、コンパイラまたはリンカの説明書を参照してください。例えば再帰的ルーチンがあるとき数千階層もの再帰を必要とするかもしれません。また、emake.bat内のリンクコマンドを修正してください。Watcom Cの場合は、OPTION STACK=nnnnを使用します。 なお、nnnnはスタックの空きバイト数を指定します。 注意事項:
プログラムのデバッグは インタプリタで行う必要があります。トランスレータは特定のランタイムエラーに関しては検査しますが、実行速度を稼ぐために大抵は検査されません。翻訳したC言語コードがクラッシュしたとき一般的に非常に不可解なマシン例外となります。大抵、最初にしなければならないことは プログラムをインタプリタで実行して同じ入力を行いますが、できればtype_checkを有効にしてから実行します。もしエラーが翻訳済みのコードのみで発生するならば、最新500件の実行済み命令文を保持できるリングバッファの内容を ctrace.outファイルへ出力するためにwith traceまたはtrace(3)を使用できます。 トランスレータで検出したエラーメッセージが表示されるとき(ex.errにも出力されます)、with traceが有効ならばEuphoriaソースの問題のある行をいつでも調べられます。 with traceを使うとプログラムの動作速度が低下し、さらにtrace(3)が有効なときは極端に動作速度が低下します。 RDSに関連するものである限り、RDSトランスレータライブラリの改変を除き(訳注:現在はBSDライセンスのはずなのでこの条項は無効だと思われる)トランスレータで生成した任意の実行ファイルまたは.dllファイルは、ロイヤリティフリーで再配布できます。RDSで提供されている任意のEuphoria関連ファイル(RDSのアーカイブページではない)をアプリケーションに組み込んでもかまいません。 2000年1月には、CauseWay DOSエクステンダはマイケル・デボラ(Michael Devore)によりパブリック・ドメイン化されました。彼は著作権を放棄し、商用利用を含め、誰でも自由に使用することが推奨されています。 一般に、サードパティによって開発されたEuphoriaコードを利用したいときは、該当する全ての利用規約(ライセンス)を守ったほう良いです。利用規約に疑問がある場合は、開発者に質問をしたり利用許可を得る必要があります。 Linux, FreeBSD および DOS32版DJGPPでは、GNUライブラリライセンスが適用されますが通常はトランスレータが作成したプログラムにライセンスの影響はありません。単にプログラムをGNU Cでコンパイルしただけではフリーソフトウェア財団(FSF:Free Software Foundation)にプログラムのライセンス権限を与えるようなことは一切ありません。静的リンクをしたときはGNUライブラリライセンスが適用されてしまいますが、emakeによる標準的なコンパイル/リンクの手順においてFSF関連ライブラリを静的リンクしないため、問題とはなりません。 AllegroグラフィックスライブラリはDJGPPで使用され、ライセンスは説明書を参照すると"ギフトウェア(Giftware)"と明記されており、プログラムの一部として再配布することができます。これはいくつかの許諾を必要とせず要求もされません。 免責事項:
8. よくある質問集
現在ではトランスレータは完全に安定動作するようになっており、大規模プログラムの翻訳およびコンパイルは対応する各C言語コンパイラを使用して正常に行えます。 注意事項:
場合よっては巨大なEuphoriaルーチンをC言語へ翻訳すると、それはC言語コンパイラにとって負荷の大きい処理になります。この問題に遭遇したときは、対象のEuphoriaルーチンをより小さくて簡素なものにしてください。emake.batを編集することにより処理に失敗する.cファイルに対してC言語コンパイラによる最適化の無効を試みることができます。多数の変数を単一の定数宣言に分割したり単一の各変数を定数宣言に分割することも、役立ちます。Euphoriaにはルーチンの大きさ、またはファイルの大きさの制限はありませんが、多くのC言語コンパイラには制限が存在します。トランスレータはC言語コンパイラに過負荷を与えないために、大規模なEuphoriaファイルから複数の小規模な.Cファイルを自動生成します。しかしそうしたくないときは、大きなルーチンをより小さなルーチンへ分割してください。
なお、バグレポートはEUforum(英語)に投稿してください。
|