Scheme で書いた DOS のバッチファイル

DOS のシェルスクリプトはバッチファイルという名で知られています。 例の“Hello, World!”を出力する DOS のバッチファイルは以下のように なっています。

echo Hello, World! 

これは DOS コマンドの echo を使っています。このバッチファイルを hello.bat とします。これはオペレーティングシステムに実行ファイルで あることを認識させるためです。こうしておいて、環境変数 PATH にある ディレクトリに置くと、DOS プロンプトで以下のようにタイプするか

hello.bat 

単に

hello 

とタイプするたびに、即座にそっけない挨拶が得られます。

この hello バッチファイルの Scheme バージョンは同じ出力を Scheme を 使って実行しますが、DOS にファイルの中のコマンドをデフォルトの バッチファイルではなく、Scheme として解釈するように教えるための 何かが必要です。Scheme バッチファイルは hello.bat という名前にし、 その中身は、以下のようになります。

;@echo off 
;goto :start 
#| 
:start 
echo. > c:\_temp.scm 
echo (load (find-executable-path "hello.bat" >> c:\_temp.scm 
echo "hello.bat")) >> c:\_temp.scm 
mzscheme -r c:\_temp.scm %1 %2 %3 %4 %5 %6 %7 %8 %9 
goto :eof 
|# 
 
(display "Hello, World!") 
(newline) 
 
;:eof 

|# までの行は標準の DOS バッチです。そのあとの部分は 挨拶のための Scheme のコードです。最後にまた 標準の DOS バッチの 行が一行あります。それは、;:eof です。

ユーザが DOS プロンプトで hello とタイプすると DOS は hello.bat を通常のバッチファイルとして読み、走らせます。 最初の行、;@echo off はコマンドが走ったときのエコーを オフにします。スクリプトの効果を曇らせる度の過ぎたエコーは 欲しくないからです。2 行目 ;goto :start は先の :start ラベルのラインまでジャンプを実行します。echo ではじまる 3 行は以下の内容の c:\_temp.tmp という一時ファイルを作ります。

(load (find-executable-path "hello.bat" "hello.bat"))

次のバッチコマンドは MzScheme の呼び出しです。 -r オプションは Scheme のファイル c:\_temp.scm を ロードします。すべての引数(ここの例では引数はありません)は ベクタ argv にあり Scheme から利用可能です。 この Scheme の呼び出しは下で見るように Scheme のスクリプトを 評価します。Scheme から復帰したあと、バッチファイルを きれいにまきあげなければなりません。次のバッチコマンドは goto :eof で、これは、すべての Scheme のコードを避け、 まさにこのファイルの最後(ラベル ;:eof を含む)に飛ぶため 制御コードです。こうして、スクリプトは終了します。

これで、どのように Scheme の呼び出しおこなわれるか、すなわち、 このバッチファイルに埋め込まれた Scheme 式をどのように走らせる かを理解することができます。c:\_temp.scm のロードによって Scheme は hello.bat ファイルのフルパス名を (find-executable-path を使って)推論します。そして、hello.batロードします。

これで、Scheme のスクリプトファイルが Scheme ファイルとして実行され、 そのファイルの中の Scheme のフォームが元のスクリプトの引数に ベクタ argv を通じてアクセスできます。

さて、Scheme はスクリプト内のバッチコマンドを回避しなければなりません。 これは、これらのバッチコマンドの前にセミコロンがついているか、 #| ... |# で囲まれているので、簡単です。これらは Scheme の コメントをつくります。

ファイルののこりはもちろん、Scheme そのものです。 そこにある式は、順に評価されます。(最後の式 ;:eof は Scheme ではコメントなので問題ありません。) すべての式の 評価が終了してしまえば、Scheme は終了します。

要するに、hello と DOS プロンプトでタイプすれば、

Hello, World! 

が表示され、また DOS プロンプトに戻ります。