Advertisement
uyuyuy99

CS 425 - Ass 7 (Part 1)

Jun 9th, 2025 (edited)
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (* Given datatypes *)
  2. datatype term = AST_ID of string
  3.               | AST_NUM of int
  4.               | AST_TRUE
  5.               | AST_FALSE
  6.               | AST_SUCC
  7.               | AST_PRED
  8.               | AST_ISZERO
  9.               | AST_IF of term * term * term
  10.               | AST_FUN of string * term
  11.               | AST_APP of term * term
  12.               | AST_LET of string * term * term;
  13.  
  14. datatype result = RES_ERROR of string
  15.                 | RES_NUM of int
  16.                 | RES_TRUE
  17.                 | RES_FALSE
  18.                 | RES_SUCC
  19.                 | RES_PRED
  20.                 | RES_ISZERO
  21.                 | RES_FUN of (string * term)
  22.                 | RES_CLOSURE of (string * term * env)
  23. and env = Env of (string -> result);
  24. (* Helpers previously given, and slightly modified.
  25.    You will need to modify these when using static scope
  26.    and call-by-name *)
  27. exception UnboundID of string
  28. exception Unimplemented
  29. fun emptyenvFun (x : string) : result = (print (x ^ " is unbound"); raise (UnboundID x));
  30. val emptyenv = Env emptyenvFun
  31.  
  32. (* This is the environment from the typechecker
  33.    Note that it returns string -> result so you will
  34.    have to tag the return with Env *)
  35. (* Env -> string -> result -> string -> result *)
  36. fun update (Env e) (x : string) (v: result) y = if x = y then v else e y;
  37.  
  38. (* Interpret function *)
  39. fun interp (Env env) (AST_ID i)      = env i
  40.   | interp env (AST_NUM n)           = RES_NUM n
  41.   | interp env AST_TRUE              = RES_TRUE
  42.   | interp env AST_FALSE             = RES_FALSE
  43.   | interp env AST_SUCC              = RES_SUCC
  44.   | interp env AST_PRED              = RES_PRED
  45.   | interp env AST_ISZERO            = RES_ISZERO
  46.   | interp env (AST_IF (b, e1, e2))  =
  47.   let
  48.     val res = interp env b
  49.   in
  50.     case res of
  51.       RES_TRUE => interp env e1
  52.     | RES_FALSE => interp env e2
  53.     | _ => RES_ERROR "b must be a bool"
  54.   end
  55.   | interp env (AST_FUN (i, b))      = RES_FUN (i, b)
  56.   | interp env (AST_APP (f, p))      =
  57.   let
  58.     val res_f = interp env f
  59.     val res_p = interp env p
  60.   in
  61.     case res_f of
  62.       RES_SUCC =>
  63.         (case res_p of
  64.           RES_NUM n => RES_NUM (n + 1)
  65.         | _ => RES_ERROR "param must be a number")
  66.     | RES_PRED =>
  67.         (case res_p of
  68.           RES_NUM n =>
  69.             if n = 0 then RES_NUM 0
  70.             else RES_NUM (n - 1)
  71.         | _ => RES_ERROR "param must be a number")
  72.     | RES_ISZERO =>
  73.         (case res_p of
  74.           RES_NUM n =>
  75.             if n = 0 then RES_TRUE
  76.             else RES_FALSE
  77.         | _ => RES_ERROR "param must be a number")
  78.     | RES_FUN(param, body) =>
  79.         let
  80.           val env_new = Env (update env param res_p)
  81.         in
  82.           interp env_new body
  83.         end
  84.     | _ => RES_ERROR "f must be a function"
  85.   end
  86.   | interp env (AST_LET (x, e1, e2)) =
  87.   let
  88.     val v1 = interp env e1
  89.     val env_new = Env (update env x v1)
  90.   in
  91.     interp env_new e2
  92.   end
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101. (* Static-scoped *)
  102. fun interp_static (Env env) (AST_ID i)      = env i
  103.   | interp_static env (AST_NUM n)           = RES_NUM n
  104.   | interp_static env AST_TRUE              = RES_TRUE
  105.   | interp_static env AST_FALSE             = RES_FALSE
  106.   | interp_static env AST_SUCC              = RES_SUCC
  107.   | interp_static env AST_PRED              = RES_PRED
  108.   | interp_static env AST_ISZERO            = RES_ISZERO
  109.   | interp_static env (AST_IF (b, e1, e2))  =
  110.   let
  111.     val res = interp_static env b
  112.   in
  113.     case res of
  114.       RES_TRUE => interp_static env e1
  115.     | RES_FALSE => interp_static env e2
  116.     | _ => RES_ERROR "b must be a bool"
  117.   end
  118.   | interp_static env (AST_FUN (i, b))      = RES_CLOSURE (i, b, env)
  119.   | interp_static env (AST_APP (f, p))      =
  120.   let
  121.     val res_f = interp_static env f
  122.     val res_p = interp_static env p
  123.   in
  124.     case res_f of
  125.       RES_SUCC =>
  126.         (case res_p of
  127.           RES_NUM n => RES_NUM (n + 1)
  128.         | _ => RES_ERROR "param must be a number")
  129.     | RES_PRED =>
  130.         (case res_p of
  131.           RES_NUM n =>
  132.             if n = 0 then RES_NUM 0
  133.             else RES_NUM (n - 1)
  134.         | _ => RES_ERROR "param must be a number")
  135.     | RES_ISZERO =>
  136.         (case res_p of
  137.           RES_NUM n =>
  138.             if n = 0 then RES_TRUE
  139.             else RES_FALSE
  140.         | _ => RES_ERROR "param must be a number")
  141.     | RES_FUN(param, body) =>
  142.         let
  143.           val env_new = Env (update env param res_p)
  144.         in
  145.           interp_static env_new body
  146.         end
  147.     | RES_CLOSURE(param, body, env1) =>
  148.         let
  149.           val env_new = Env (update env1 param res_p)
  150.         in
  151.           interp_static env_new body
  152.         end
  153.     | _ => RES_ERROR "f must be a function"
  154.   end
  155.   | interp_static env (AST_LET (x, e1, e2)) =
  156.   let
  157.     val v1 = interp_static env e1
  158.     val env_new = Env (update env x v1)
  159.   in
  160.     interp_static env_new e2
  161.   end
  162.  
  163. (* Tests *)
  164. (* ------------ *)
  165.  
  166. (* Dynamic vs static scope *)
  167. (* let x = 0
  168.    in let f = fn z => x
  169.         in let x = 100
  170.             in f x *)
  171. val test0 = AST_LET ("x", AST_NUM 0,
  172.                AST_LET("f",AST_FUN("z",AST_ID "x"),
  173.                   AST_LET("x",AST_NUM 100,
  174.                     AST_APP(AST_ID "f", AST_ID "x"))));
  175.  
  176. val res_test0 = interp_static emptyenv test0;
  177.  
  178. (* Call-By-Value vs Call-By-Name *)
  179. (* (fn x => 42) ((fn x => x x) (fn x => x x)) *)
  180.  
  181. val test1 =
  182.     AST_APP
  183.         (AST_FUN ("x",AST_NUM 42)
  184.         ,AST_APP
  185.              (AST_FUN ("x",AST_APP(AST_ID "x",AST_ID "x"))
  186.              ,AST_FUN ("x",AST_APP(AST_ID "x",AST_ID "x"))));
  187.  
  188. val res_test1 = interp emptyenv test1;
  189.  
  190.  
  191. (* ((fn x => fn y => x 42) (fn y => y)) 0 *)
  192. val test2 =
  193.     AST_APP
  194.         (AST_APP
  195.              (AST_FUN ("x",AST_FUN ("y", AST_APP (AST_ID "x",AST_NUM 42))) ,AST_FUN ("y",AST_ID "y"))
  196.         ,AST_NUM 0)
  197.  
  198. val res_test2 = interp emptyenv test2;
  199.  
  200. OS.Process.exit(OS.Process.success);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement