MiniML 言語処理系の使い方 2010/05/17 MiniML は MiniC とほぼ同様の方法で起動,呼び出し,終了できる. 1. 処理系の起動方法 ==================== 自分のホームディレクトリの下に,「本演習用の作業ディレクトリ」を決め て,そこに,いくつかのファイルをコピーする.(ここでは作業ディレクトリ を ~/ML とする.) cd ~ mkdir ML cd ML cp ~kam/miniml/main.cmi . (システム実行の際に必要) cp ~kam/miniml/*.ml . (*.ml はMiniML言語のテストファイル) システム起動方法: ~kam/miniml/miniml もし,事前に, cd ~/ML ln -s ~kam/miniml/miniml (MiniML処理系へのリンク) としておけば, ./miniml とするだけよい. 上記で起動できない場合,ls -l ~kam/miniml/minimlとやって, 自分の権限で,ファイルが読めるかどうかチェックする.また, ocaml コマンドがない場合も起動できないので, ocaml というコマンドをたたいてみる.(ocamlから抜ける時は, control-d を押す.) 2. MiniMLプログラム実行方法 =========================== Main.run "ex1.ml" ;; 上記のように実行したときに, Error: Unbound value Main.run というメッセージが出たら,「1」の作業で main.cmi をコピーし忘れ たと思われる(あるいは,コピーした作業ディレクトリとは違う場所に 移動して MiniML を起動したものと思われる).上記の作業を確認してほ しい. 正しく設定されているとき,上記のように ex1.ml を実行すれば, 以下の出力が得られるはずである. miniML interpreter Version 3.0: 3 5 ... 36 - : string = "ok" # 最後の行 (...string ...という行)は,無視してほしい,その前の行 が実行結果であり,この場合,3 から 36 である. 上記を実行したあとに,続けて別のファイルを実行できる. Main.run "ex2.ml" ;; 3. 処理系の終了方法 ==================== C-d (control-d)を押せば,MiniML 処理系(だけでなく,その ベースとなっているOCaml処理系) から抜けることができる. なお,C-z (control-z)で中断したままでは,メモリをたくさん消費する ので,なるべくきちんと抜けること. さらに,無限ループとなるプログラムを実行してしまった ときは C-c (control-c) を押せば,計算を途中でやめて MiniML処理系のレベルにもどることができる. 4. MiniML プログラム例題 ======================== ~kam/miniml/ex*.ml (* は 1,2,3,...) というファイルが, 例題ファイルである. これらのファイルに含まれるプログラムの一部は,処理モード によっては停止しないので注意されたい.(C-c を押す必要が ある.) 5. 処理系の「モード」を変更したいとき ====================================== Main.mode n ;; とやるとよい(ただし,n は 0,1,2... である.n の最大値がいくつ であるかは,その時点での処理系の作りによる.) 「処理系のモードが 0とか 1というのは何を意味するのか?」という 疑問が当然置きるであろう.実は,「それを考えよ」というのが課題 であるので,ここでは説明しない. 6. MiniML 言語の構文 ==================== 講義時に配布した資料を参照してほしい.なお,授業のweb page からも 取得可能である.さらに,let rec 構文については, 授業で説明する時間がなかったので,ex2.ml という例題ファイルの fib 関数などを見てほしい. 7. MiniC のエラーメッセージ ============================ 現状の処理系は,最小限のエラーしか出さない.また,全てのエラー に対応していない可能性もある.もし,OCaml のプログラムを理解し てプログラムしたい人がいたら,ソースコードを見せるので,改良して ほしい. 8. MiniML の show 関数, print 関数 ================================== show 0 とすると MiniC と同様,その時点でのスタックの中身を簡単に表示す る(ただし,MiniML処理系では,簡潔な表示とするために, Access Link でつ ながっているスタックフレームのみを表示している.MiniC では,スタック フレームをすべて表示していたことに注意されたい.) show 1 とすると,その時点でのヒープの中身を簡単に表示する. ヒープの構成要素は,#3 や #5 といった名前をもつセル(2個のメモリをもつ) とする.すなわち,ヒープは単なる(番地つき)巨大メモリではなく,セルがた くさん集まっているものと考える.1つ1つのセルの名前は,#1 や #2 である. show 1 によって,#1=(100,#23) と表示されたとき, #1という名前のセルの 中身が,100 と #23 の2つであることを意味し,100は整数の100であり,#23 は別のセルへのポインタである. このあたりは,言葉による説明より,実際の中身を見た方がよいと思われるの で,ex2.ml などのファイルを実行して,ヒープの中身を見てほしい. print e とやると,e の計算結果を印刷する.e が関数のときに何が印刷され るかは,自分で試してほしい.なお,print e という式そのものも,計算し た後には何か値を返さないといけないのであるが(C言語では print は「文」 であるが,ML言語では「式」である),意味のある値を返すわけにもいかない ので,常に () という値を返す.() というのは不思議な値であるが,まあ, そういう習慣だ,と理解してほしい.したがって,(print 1, print 2) と やると, 1, 2 が順番に印刷されたあと,((), ()) という不思議な値が 返ってくる. 9. 自分でファイルを作るときの注意点 =================================== ex1.ml 等のファイルを自分で作るときは,必ず, 式 ;; 式 ;; 式 ;; 式 ;; 式 ;; 式 ;; というように,式を1つ書いて,semicolon 2つで区切る,という ように書くこと.semicolon がなかったり,式でないものを書く と,parser がエラーをだしてしまい,式が1つも評価されない. 一方,本来の OCaml のファイルは,単なる式を並べて書くのではなく, let x = 1 + 2 let y = 1 + 2 のような書き方が許されているので,MiniML とは若干違う. (もちろん ;; で区切ってもよいので,OCaml の方が許容範囲が 広い.)