6

compile-fileディスク上の通常のファイルではなく、ストリームまたはメモリ内の文字列の効果を実現する方法はありますか?(つまり、ファイルがなく、このメモリ内データから一時ファイルを作成したくない場合)

編集

私は次のユースケースを考えています:ファイルシステム以外の場所からコードをロードする。たとえば、アーカイブ(JavaのjarまたはPython zip処理機能と同様)またはネットワークから。compile-fileたぶん、これには単なる曲げ機械ではなく、別のアプローチがあるかもしれません。

4

1 に答える 1

3

Rainer Joswig の最初のコメントはそれを明確に示しています。

標準の Common Lisp にはありません。

から行われた呼び出しを各実装で検索してcompile-file、基になる実装がストリームを受け取るかどうかを確認できます。

自分でこれを達成したい場合は、入力ストリームと出力ストリームに対して、または独自のバージョンにcompile-file適した読み込み可能なフォームを生成する非常に非効率的なバージョンを実装することになります。load

でコンパイルをラップすると、フォームがトップレベルのフォームのように扱われるようwith-compilation-unitに特別な注意を払う必要があります。フォームはバインディングを確立し、フォームを非null レキシカル環境 (その操作はどちらも移植性がありません) とプロセスフォーム (一部のフォームが評価、処理、またはその両方である可能性があります)。次に、外部化可能なフォームを生成し、合体できるものとできないもの (シンボルとパッケージなど) に注意し、 、およびインスタンスを呼び出し、コンパイルするストリームに最初の非-アトミックmacroexpandprognlocallymacroletsymbol-macroleteval-whenmake-load-formstandard-objectstructure-objectconditionin-packageloadが異なる値で呼び出された場合にエラーを通知できるようにするかどうかを指定し*package*ます。

そして、これは多かれ少なかれ最小限のコンパイルのための最上位のステップに過ぎず、コンパイルが実際にいつ行われるか (コンパイル時またはロード時)、load-time-valueフォーム、および多くの詳細について言及することはありません。一部の手順では、コード ウォーキングが必要です。

私のアドバイス:コンパイルとロードのセマンティクスを維持したい場合は、圧縮されたデータとソケットからソース コードを抽出して保存し、その後に を呼び出しcompile-fileます。loadより単純な場合は、次のようにすることができます。

(let* ((*package* *package*)
       (*readtable* *readtable*)
       (eof (copy-symbol 'eof))
       (form nil))
  (loop
    (setf form (read stream nil eof))
    (when (eq form eof)
      (return))
    (funcall (compile nil `(lambda () ,form)))))

移植性をあまり気にしない場合は、圧縮ファイルを処理できるように実装compile-fileを作成します。単なるパス名の代わりに。私の知る限り、ABCLは入力用のURLを開くことができます。しかし、compile-fileそのような外部リソースで呼び出された場合の出力ファイルは何でしょうか? のキー引数とのcompile-and-load両方に使用する一時ファイルを記述した独自のファイルを作成することもできます。compile-fileoutput-fileload

于 2012-09-03T16:17:14.817 に答える