Previous Up Next
3.4 ML2 --- 定義の導入

ここまで,MLプログラム中で参照できる変数は main.ml 中の initial_env であらかじめ定められた変数に限られていた.ML2で は変数宣言の機能を,let 宣言と let 式として導入する.

3.4.1 let 宣言・式の導入

ML2 の構文は,以下のように与えられる.
<プログラム> ::= … | let <識別子> = <式> ;;
<式> ::=
  | let <識別子> = <式1> in <式2>

expressed value, denoted value ともに以前と同じ,つまり, let による束縛の対象は,式の値である.この拡張に伴なう プログラムの変更点を図7に示す.syntax.ml では,構文の 拡張に伴うコンストラクタの追加,parser.mly では,具体的な構文規則 (letは結合が ifと同程度に弱い)の追加,lexer.mllでは,予約語 と記号の追加を行っている.eval_explet 式を扱う部分では, 最初に,束縛変数名,式を取りだし,各式を評価する. その値を使って,現在の環境を拡張し,本体式を評価している.

syntax.ml:

type exp = 
   ...
  | LetExp of id * exp * exp

type program = 
    Exp of exp
  | Decl of id * exp


parser.mly:

%token LET IN EQ

toplevel :
     Expr SEMISEMI { Exp $1 }
   | LET ID EQ Expr SEMISEMI { Decl ($2, $4) }

Expr :
     IfExpr { $1 }
   | LetExpr { $1 }
   | LTExpr { $1 }

LetExpr :
     LET ID EQ Expr IN Expr { LetExp ($2, $4, $6) }


lexer.mll:

let reservedWords = [
   ...
  ("in", Parser.IN);   
  ("let", Parser.LET);
]

...

| "<"  Parser.LT 
| "="  Parser.EQ 


eval.ml:

let rec eval_exp env = function
   ...
   | LetExp (id, exp1, exp2) ->
       let value = eval_exp env exp1 in
         eval_exp (Environment.extend id value env) exp2

let eval_decl env = function
     Exp e -> let v = eval_exp env e in ("-", env, v)
   | Decl (id, e) ->
       let v = eval_exp env e in (id, Environment.extend id v env, v)

Figure 7: 局所定義



Exercise 4  [必修課題] ML2 インタプリタを作成し,テストせよ.

Exercise 5  [難易度 1] Objective Caml では,let宣言の列を一度に入力することができる. この機能を実装せよ.以下は動作例である.


# let x = 1
  let y = x + 1;;
val x = 1
val y = 2

Exercise 6  [難易度 1] バッチインタプリタを作成せよ.具体的には miniml コマンドの引数とし て ファイル名をとり,そのファイルの内容を解釈し,結果をディスプレイ に出力するように変更せよ.また,コメントを無視するよう実装せよ.

Exercise 7  [難易度 2] andを使って変数を同時にふたつ以上宣言できるように let 式・宣言を拡張せよ.例えば以下のプログラム


let x = 100
and y = x in x+y
の実行結果は 200 ではなく,(xが大域環境で 10に束縛され ているので) 110 である.


Previous Up Next