Advertisement
Guest User

nicball

a guest
Apr 24th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.27 KB | None | 0 0
  1. // 在 http://fsharp.net 上了解有关 F# 的更多信息
  2. // 请参阅“F# 教程”项目以获取更多帮助。
  3.  
  4. exception TypeError
  5. exception InvalidProgram
  6. exception NonexistedKey
  7.  
  8. type expr =
  9.     | NumE of int
  10.     | IdE of string
  11.     | AppE of expr * expr
  12.     | LambdaE of string * expr
  13.     | BeginE of stat list
  14.     | SetE of string * expr
  15.  
  16. and stat =
  17.     | ExprS of expr
  18.     | DefS of string * expr
  19.  
  20. type builtin =
  21.     | PrintB
  22.  
  23. type location = Location of int
  24.  
  25. type env = Env of (string * location) list
  26.  
  27. type value =
  28.     | NumV of int
  29.     | BuiltinV of builtin
  30.     | UnitV
  31.     | LambdaV of string * expr * env
  32.  
  33. type store = Store of (location * value) list * int
  34.  
  35. let rec lookup k = function
  36.     | (xk, xv) :: xs -> if xk = k then xv else lookup k xs
  37.     | [] -> raise NonexistedKey
  38.  
  39. let lookupEnv k (Env e) = lookup k e
  40.  
  41. let lookupStore k (Store (s, _)) = lookup k s
  42.  
  43. let print_value = function
  44.     | NumV n -> printfn "%i" n
  45.     | _ -> raise TypeError
  46.  
  47. let mt_env = Env [
  48.         ("print", Location 0);
  49.         ("unit", Location 1)
  50.     ]
  51. let mt_store = Store ([
  52.         (Location 0, BuiltinV PrintB);
  53.         (Location 1, UnitV)
  54.     ], 2)
  55.  
  56. let allocate (Store (xs, count)) =
  57.     let loc = Location count
  58.     (loc, Store ((loc, UnitV) :: xs, count + 1))
  59.  
  60. let bind id loc (Env e) = Env ((id, loc) :: e)
  61.  
  62. let set_location loc v (Store (s, c)) = Store ((loc, v) :: s, c)
  63.  
  64. let rec eval env store = function
  65.     | NumE n -> (NumV n, store)
  66.     | AppE (f, e) ->
  67.         let (fv, store_1) = eval env store f
  68.         let (ev, store_2) = eval env store_1 e
  69.         begin match fv with
  70.         | BuiltinV PrintB -> print_value ev; (UnitV, store_2)
  71.         | LambdaV (id, expr, env_0) ->
  72.             let (loc, store_3) = allocate store_2
  73.             let store_4 = set_location loc ev store_3
  74.             let env_0_1 = bind id loc env_0
  75.             eval env_0_1 store_4 expr
  76.         | _ -> raise TypeError
  77.         end
  78.     | IdE id -> (lookupStore (lookupEnv id env) store, store)
  79.     | BeginE exprs -> run env store UnitV exprs
  80.     | LambdaE (id, expr) -> (LambdaV (id, expr, env), store)
  81.     | SetE (id, expr) ->
  82.         let (v, store_1) = eval env store expr
  83.         let loc = lookupEnv id env
  84.         let store_2 = set_location loc v store_1
  85.         (UnitV, store_2)
  86.  
  87. and run env store retval = function
  88.     | s :: ss ->
  89.         begin match s with
  90.         | ExprS e ->
  91.             let (v, store_1) = eval env store e
  92.             run env store_1 v ss
  93.         | DefS (id, e) ->
  94.             let (loc, store_1) = allocate store
  95.             let env_1 = bind id loc env
  96.             let (v, store_2) = eval env_1 store_1 e
  97.             let store_3 = set_location loc v store_2
  98.             run env_1 store_3 UnitV ss
  99.         end
  100.     | [] -> (retval, store)
  101.  
  102. [<EntryPoint>]
  103. let main argv =
  104.     ignore (eval mt_env mt_store (BeginE [
  105.             DefS ("i", NumE 5);
  106.             DefS ("f", (LambdaE ("x", (AppE (IdE "print", IdE "i")))));
  107.             ExprS (AppE (IdE "f", IdE "unit"));
  108.             ExprS (SetE ("i", NumE 6));
  109.             ExprS (AppE (IdE "f", IdE "unit"));
  110.             DefS ("i", NumE 7);
  111.             ExprS (AppE (IdE "f", IdE "unit"));
  112.         ]))
  113.     ignore (System.Console.Read ())
  114.     0 // 返回整数退出代码
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement