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 プロンプトに戻ります。