2009-05-27 3 views
32

Lisp用のネイティブコードコンパイラはありますか?動的な性質、ガーベジコレクション、マクロ、その他のものはどれもコンパイルできますか?Lispネイティブコードコンパイラはありますか?

+2

今まで考えて、私はLISPが解釈されたと思った。 –

+1

あなたはCommon Lispについて話していますか? –

+2

@Amit、yesとno。私は、実用的なWindows * .exeファイルを生成してファイルコンバーターのような使い捨てユーティリティを作成する方法を見つけ出したいと思っています。彼らのマシンにLispをインストールすることができます(特にPythonをインストールした後はまだ怒っています)。その目的のために、私はコモン・リスプをもっと「実用的」なものとして好むでしょう。一方、大きな図を見るために、Scheme(または何でも)コンパイラについても知りたいと思います。 – Headcrab

答えて

53

多くのLispコンパイラは 'ネイティブ'コードにコンパイルされます。 'ネイティブ'とは、ここではマシンコード(32ビットまたは64ビットモードのx86、PowerPC、SPARC、...)を意味します。

その他の質問は:

  • '非ネイティブコード' コンパイラは、単一のファイルの実行可能ファイルを生成することができますか? →はい。

  • 「ネイティブコード」コンパイラは、単一ファイル実行ファイルを生成できますか? →はい。

  • どのように 'ネイティブ'は 'ネイティブ'ですか? - > Lispシステムは、ほとんどの時間は、独自の内部データ構造のレイアウト(CLOSクラス)、独自のエラー処理(条件)、独自のメモリ管理(ガベージコレクション)、独自のライブラリ、...

  • GCなしでLispを実行できますか? - >通常はありません。例外があります。

  • アプリケーションサイズは? - >デフォルトでは、Lispアプリケーションを生成する単純な方法はしばしば大きな実行可能ファイルにつながります。実行可能ファイルには、ライブラリ、すべてのシンボルの名前、関数への引数リスト、コンパイラ、デバッガ、ソースコードの位置情報など、Lisp全体が含まれます。コンパイラの中には、大規模なコードも生成するものがあります(SBCLが例です)。

  • アプリケーションサイズを縮小する方法はありますか?これはLispシステムに依存します。 LispWorksやAllegro CLのような市販のLispシステムでも可能です。アプリケーション配信のために、未使用のコードを削除したり、デバッグ情報を削除したり、Lispの一部(ライブラリ、コンパイラなど)を削除することができます。

  • Common Lispシステムは小さな実行可能ファイルを生成できますか?私は本当に小さいことを意味する。 - >そうではありません。実行可能ファイルは大規模(CCL)または非常に大規模(SBCL)です。いくつかのCommon Lispシステムでは、中規模の実行可能ファイルを生成することができます。しかし、本当に小さな実行可能ファイルを生成することはできません。

  • 本当に小さな実行ファイルを生成する方法はありませんか? - >数年前、大きなライブラリを持たないコンパクトなCコードを生成するコンパイラが書かれました。しかし、これらのコンパイラは維持されていません。

  • 実行可能ファイルを縮小する他の方法はありますか? - >複数のLispアプリケーションを実行する場合は、ランタイム、コンパイラ、ライブラリを1つまたは複数の共有ライブラリに再利用することが理にかなっています。そうすれば、ランタイムがすでに共有ライブラリ(または同様のもの)としてインストールされている場合、提供するコードが小さくなります。

  • 私が使っているLispがアプリケーション配信としてどのようにサポートされているかを知るにはどうすればよいですか? - >マニュアルを読んで、他のユーザーに尋ねてください。

  • 大丈夫なので、ほとんどのCommon Lispシステムは、小さなアプリケーションを生成できません。より小さな実行可能ファイルを生成できる他のLisp方言がありますか? - >はい、いくつかのSchemeコンパイラができます。

  • どのようにCommon Lispがランタイムエラーを処理しますか? - >は、アプリケーションを生成する方法によって異なります。デフォルトでは、あなたがLispデバッガを取得します(あなたがそれを削除していない限り)。しかし、アプリケーションで独自のエラー処理ルーチンを使用して、デバッガが表示されないようにすることができます。

  • 本当に小さな実行可能ファイルを生成するときにCommon Lispの特長は何ですか?アプリケーションと対話するためにREPLを含めることができます。ランタイムに新しいコンパイル済みコードをコンパイルすることができます。プラグイン、パッチ、エクステンションなど)、エラーリカバリを含む高度なエラー処理が可能...

  • Lispは動的ですか? - >はい、動的なことは、実行中に多くのことを変更できることを意味します。たとえばCommon Lispでは、実行時にCLOSクラスを変更することができ、クラスのインスタンスは変更に適用されます。しかし、さまざまなLispシステムには、いくつかの動的機能を削除するさまざまな方法があります。構造はCLOSクラスより動的ではありません。さまざまな最適化設定(速度、安全、デバッグなど)を使用して型を宣言し、コンパイルすることができます。関数をインライン化することができます。もっと。

コンパイルされた関数のコードを見る簡単な方法は、Common Lisp関数DISASSEMBLEを使うことです。 x86-64でのClozure CLでの例マック

? (defun foo (x y) (if (= x y) (sin x) (* y (cos x)))) 
FOO 
? (disassemble 'foo) 
L0 
    [0]  (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [7]  (cmpl ($ 16) (% nargs)) 
    [10] (jne L209) 
    [16] (pushq (% rbp)) 
    [17] (movq (% rsp) (% rbp)) 

... DISASSEMBLEの出力は明らかにプロセッサアーキテクチャ、OS、使用のLispコンパイラと現在の最適化設定に依存

[172] (pushq (@ 77752)) 
    [179] (jmpq (@ 10 (% temp0))) 
L189 
    [189] (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [196] (jmpq (@ .SPNVALRET)) 
L209 
    [209] (uuo-error-wrong-number-of-args) 
NIL 

+0

実行時に何かが変更された場合、どうなりますか? Lispは新しいバージョンのマシンコードを生成するのですか?それとも変更は "内部データ構造のレイアウト"にのみ影響しますか? – Headcrab

+0

変更によります。コンパイラを必要としないものもあれば、内部コンパイラを使うものもあれば、既存のコードを置き換えたり拡張したりするために新しく読み込まれたコードを使うものもあれば、コンパイラを必要としないものもあります。すべての変形が可能です。 –

4

賭けてください。 Chez Scheme(市販のコンパイラ)が優れたものの1つです。 GambitとLarcenyはネイティブコードも生成するリサーチコンパイラです。

+0

http://www.iro.umontreal.ca/~gambit/ Gambit Homepage http://www.ccs.neu.edu/home/will/Larceny/Larceny Homepage GambitはCにコンパイルされ、LarcenyはC、マシンコードまたはCLR。 –

3

はい。 http://en.wikipedia.org/wiki/Common_Lispを参照してください。 Steel Bank Common Lisp(かなり普及している実装)は、すべてをデフォルトでネイティブにコンパイルすると述べています。ガベージコレクションなどが使用されているということは、ネイティブコードの障害にはなりません。それは単に何らかのランタイムが必要であることを意味します。しかし何? Cでもランタイムがあります。

9

ネイティブコードにコンパイルする多くのLispコンパイラがあります。 CMUCL、SBCL、ClozureCLは、オープンソースのLispコンパイラで知られています。

ネイティブコードへのコンパイルでは、ガベージコレクションが障害になることはありません。また、LispはGCを必要としないスタック割り当てを使用することができ、パフォーマンスを大幅に向上させることができます(少なくともSBCLはこれをサポートしています)。

マクロ(および読み取り時に読み込まれるコード(読み取りマクロと読み取り評価)、コンパイル時(マクロ、コンパイラマクロ、eval-whenのコード))では、インクリメンタルコンパイルが必要ですコンパイルし、マクロを使用するコードをコンパイルすることができます)。これはややコンパイルを複雑にしますが、あまり問題にはなりません。また、マクロとコンパイラマクロは、プログラマがコードジェネレータとコードオプティマイザを書くことができるので、コンパイラのプロセスを助け、コンパイラを本質的にカスタマイズします。

コンパイラはC言語のような単純な言語よりも複雑ですが、複雑さは管理できます(Design of CMU Common Lisp参照)。

Common Lispの動的性質は制御可能であり、効果的にコンパイルできるように設計されています。他の動的言語(Pythonなど)とは対照的に、ダイナミズムは制限されています(実行時には現在のレキシカル環境を取ることはできません)。

+0

私はずっと前にいくつかのコンパイラを試していました。私が彼らとできることは、「こんにちは、世界!」のために〜10 MBのようなものでした。 Windows .exeファイル。ランタイムエラーがある場合にLispプロンプトを表示します。だから、Lispシステム全体がそれに沿ってドラッグされているように見えるので、実際にあまりにも "ネイティブ"ではないと思うでしょう。 – Headcrab

+10

ええと、javaはJavaランタイム全体をドラッグします.netはclr全体をドラッグします。全体のC++ rt、lispはlispランタイム全体をドラッグします。これはまったく同じことです。ほぼすべての言語で独自のランタイムが必要です。 Lispのランタイムは、その柔軟性のために大きいです(jvmとclrでも同じです)。 しかし、コードはネイティブです。つまり、命令はVM用ではなく、ターゲットCPU用です。 –

+0

私はいくつかのリスプは、いくつかの機能が削除されたイメージをダンプする方法を提供していると思います。多分それを少し縮小するのに役立つでしょうか? –

4

Chickenスキームを忘れないでください。

+0

なぜダウンボートですか? OPはスキームについても知りたかったし、チキンはネイティブコンパイラです。 –

関連する問題