Commits

relsa committed 85d6a60

Ex3.11解いた

  • Participants
  • Parent commits cafe111

Comments (0)

Files changed (4)

File Interpreter/eval.ml

     Var x -> 
       (try Environment.lookup x env with 
         Environment.Not_bound -> err ("Variable not bound: " ^ x))
-  | ILit i -> IntV i
-  | BLit b -> BoolV b
+  | ILit i ->
+    IntV i
+  | BLit b ->
+    BoolV b
   | BinOp (op, exp1, exp2) -> 
       let arg1 = eval_exp env exp1 in
       let arg2 = eval_exp env exp2 in
             BoolV true -> eval_exp env exp2 
           | BoolV false -> eval_exp env exp3
           | _ -> err ("Test expression must be boolean: if"))
+
   (* | LetExp (id, exp1, exp2) -> (\* Ex3.4 *\) *)
   (*   let value = eval_exp env exp1 in *)
   (*   eval_exp (Environment.extend id value env) exp2 *)
-  | LetExp (d, exp) ->	       (* Ex3.7 *)
-    let v = eval_decl env d in (*... and ... をそれぞれ評価して環境を更新 *)
+
+  | LetExp (dec, exp) ->	       (* Ex3.7 *)
+    let v = eval_decl env dec in (*... and ... をそれぞれ評価して環境を更新 *)
     let (_, nenv, _) = v in    (* 環境を取り出す *)
     eval_exp nenv exp
-  | FunExp (id, exp) -> ProcV (id, exp, ref env) (* Ex3.8 *)
-  | AppExp (exp1, exp2) ->		     (* Ex3.8 *)
+
+  (* | FunExp (id, exp) -> ProcV (id, exp, ref env) (\* Ex3.8 *\) *)
+
+  | FunExp (param, exp) ->		(* Ex3.10 *)
+    begin
+      match param with
+      | Params (id, rest) ->
+	ProcV (id, FunExp (rest, exp), ref env) (* fun x -> expの形に *)
+      | Param id ->
+	ProcV (id, exp, ref env)
+    end
+  | AppExp (exp1, exp2) ->		(* Ex3.8 *)
     let funval = eval_exp env exp1 in
     let arg = eval_exp env exp2 in
     begin
     let newenv = Environment.extend id (ProcV (para, exp, dummyenv)) env in
     dummyenv := newenv;
     (id, newenv, ProcV(para, exp, ref newenv))
+  | FunDecl (name, params, exp) ->	(* Ex3.10 *)
+    let v = eval_exp env (FunExp (params, exp)) in
+    (name, Environment.extend name v env, v)
 ;;

File Interpreter/parser.mly

 ADecl : // Ex3.7 ... and ...の処理
   | Decl AND ADecl { AndDecl ($1, $3) }
   | Decl { $1 }
+  | FunDecl { $1 }
+
+FunDecl :
+  | ID Params EQ Expr { FunDecl ($1, $2, $4) }
 
 Decl : // Ex3.4
   | ID EQ Expr { Decl ($1, $3) }
   | FunExpr { $1 } // Ex3.8
   | LetRecExpr { $1 } // Ex3.14
 
-FunExpr : // Ex3.8
-  | FUN ID RARROW Expr { FunExp ($2, $4) }
+// FunExpr : // Ex3.8
+//   | FUN ID RARROW Expr { FunExp ($2, $4) }
+
+FunExpr :
+  | FUN Params RARROW Expr { FunExp ($2, $4) }
+
+Params : // Ex3.10
+  | ID Params { Params ($1, $2) }
+  | ID { Param $1 }
 
 LetRecExpr : // Ex3.14
   | LET REC ID EQ FUN ID RARROW Expr IN Expr

File Interpreter/report.ml

 
 (* -------------------------------- *)
 
-(* Ex3,14 *)
+(* Ex3.10 *)
+
+(*
+  [説明]
+  カリー化関数を実装した。
+
+  fun x y z -> exp
+  が
+  fun x -> fun y -> fun z -> exp
+  として、
+  let f x y z = exp
+  が
+  let f = fun x -> fun y -> fun z -> exp
+  として解釈されるよう意識して、
+  parser.ml, eval.mlを変更した。
+  また、syntax.mlに新しくparam型を追加した。
+  
+  [実行例]
+  # (fun x y z -> x * y + z) 5 2 3;;
+  val - = 13
+  # let f x y = x + y * y;;
+  val f = fun
+  # f 10 5;;
+  val - = 35
+
+  (* 部分適用 *)
+  # let g = f 10;;
+  val g = fun
+  # g 5;;
+  val - = 35
+*)
+(* -------------------------------- *)
+
+(* Ex3.11 *)
+
+(* 
+   [実行例]
+   let makemult = 
+     fun maker -> 
+       fun x ->
+         if x < 1 then 
+           1 
+         else
+           x * maker maker (x + -1) in
+   let fact =
+     fun x -> makemult makemult x in
+   fact 5
+   ;;
+*)
+
+(* -------------------------------- *)
+
+(* Ex3.14 *)
 
 (* 
    [実行例]

File Interpreter/syntax.ml

 type id = string
 
 type binOp = Plus | Mult | Lt |
-             And | Or (* Ex3.3 *)
+             And | Or			(* Ex3.3 *)
+
+type param = 
+  | Params of id * param		(* Ex3.10 *)
+  | Param of id
 
 type exp =
     Var of id
   | IfExp of exp * exp * exp
   (* | LetExp of id * exp * exp (\* Ex3.4 *\) *)
   | LetExp of program * exp		(* Ex3.7で引数の型を変更 *)
-  | FunExp of id * exp			(* Ex3.8 *)
+  | FunExp of param * exp		(* Ex3.8, Ex3.10 *)
   | AppExp of exp * exp			(* Ex3.8 *)
   | LetRecExp of id * id * exp * exp	(* Ex3.14 *)
-
+  
 and program = 
     Exp of exp
   | Decl of id * exp
+  | FunDecl of id * param * exp
   | AndDecl of program * program	(* Ex3.7 *)
   | LetDecl of program * program	(* Ex3.5 *)
   | RecDecl of id * id * exp		(* Ex3.14 *)