Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- datatype result = RES_ERROR of string
- | RES_NUM of int
- | RES_TRUE
- | RES_FALSE
- | RES_SUCC
- | RES_PRED
- | RES_ISZERO
- | RES_FUN of (string * term)
- | RES_CLOSURE of (string * term * env)
- | RES_LAZY of term
- and env = Env of (string -> result);
- (* Interpret function *)
- fun interp_lazy (Env env) (AST_ID i) =
- let
- val res = env i
- in
- (case res of
- RES_LAZY(term) => interp_lazy (Env env) term
- | _ => res)
- end
- | interp_lazy env (AST_NUM n) = RES_NUM n
- | interp_lazy env AST_TRUE = RES_TRUE
- | interp_lazy env AST_FALSE = RES_FALSE
- | interp_lazy env AST_SUCC = RES_SUCC
- | interp_lazy env AST_PRED = RES_PRED
- | interp_lazy env AST_ISZERO = RES_ISZERO
- | interp_lazy env (AST_IF (b, e1, e2)) =
- let
- val res = interp_lazy env b
- in
- case res of
- RES_TRUE => interp_lazy env e1
- | RES_FALSE => interp_lazy env e2
- | _ => RES_ERROR "b must be a bool"
- end
- | interp_lazy env (AST_FUN (i, b)) = RES_FUN (i, b)
- | interp_lazy env (AST_APP (f, p)) =
- let
- val res_f = interp_lazy env f
- in
- case res_f of
- RES_SUCC =>
- (case (interp_lazy env p) of
- RES_NUM n => RES_NUM (n + 1)
- | _ => RES_ERROR "param must be a number")
- | RES_PRED =>
- (case (interp_lazy env p) of
- RES_NUM n =>
- if n = 0 then RES_NUM 0
- else RES_NUM (n - 1)
- | _ => RES_ERROR "param must be a number")
- | RES_ISZERO =>
- (case (interp_lazy env p) of
- RES_NUM n =>
- if n = 0 then RES_TRUE
- else RES_FALSE
- | _ => RES_ERROR "param must be a number")
- | RES_FUN(param, body) =>
- let
- val res_lazy = RES_LAZY p
- val env_new = Env (update env param res_lazy)
- in
- interp_lazy env_new body
- end
- | _ => RES_ERROR "f must be a function"
- end
- | interp_lazy env (AST_LET (x, e1, e2)) =
- let
- val v1 = interp_lazy env e1
- val env_new = Env (update env x v1)
- in
- interp_lazy env_new e2
- end
- (* Static-scoped *)
- fun interp_lazy_static (Env env) (AST_ID i) =
- let
- val res = env i
- in
- (case res of
- RES_LAZY(term) => interp_lazy_static (Env env) term
- | _ => res)
- end
- | interp_lazy_static env (AST_NUM n) = RES_NUM n
- | interp_lazy_static env AST_TRUE = RES_TRUE
- | interp_lazy_static env AST_FALSE = RES_FALSE
- | interp_lazy_static env AST_SUCC = RES_SUCC
- | interp_lazy_static env AST_PRED = RES_PRED
- | interp_lazy_static env AST_ISZERO = RES_ISZERO
- | interp_lazy_static env (AST_IF (b, e1, e2)) =
- let
- val res = interp_lazy_static env b
- in
- case res of
- RES_TRUE => interp_lazy_static env e1
- | RES_FALSE => interp_lazy_static env e2
- | _ => RES_ERROR "b must be a bool"
- end
- | interp_lazy_static env (AST_FUN (i, b)) = RES_CLOSURE (i, b, env)
- | interp_lazy_static env (AST_APP (f, p)) =
- let
- val res_f = interp_lazy_static env f
- in
- case res_f of
- RES_SUCC =>
- (case (interp_lazy_static env p) of
- RES_NUM n => RES_NUM (n + 1)
- | _ => RES_ERROR "param must be a number")
- | RES_PRED =>
- (case (interp_lazy_static env p) of
- RES_NUM n =>
- if n = 0 then RES_NUM 0
- else RES_NUM (n - 1)
- | _ => RES_ERROR "param must be a number")
- | RES_ISZERO =>
- (case (interp_lazy_static env p) of
- RES_NUM n =>
- if n = 0 then RES_TRUE
- else RES_FALSE
- | _ => RES_ERROR "param must be a number")
- | RES_FUN(param, body) =>
- let
- val res_lazy = RES_LAZY p
- val env_new = Env (update env param res_lazy)
- in
- interp_lazy_static env_new body
- end
- | RES_CLOSURE(param, body, env1) =>
- let
- val res_lazy = RES_LAZY p
- val env_new = Env (update env1 param res_lazy)
- in
- interp_lazy_static env_new body
- end
- | _ => RES_ERROR "f must be a function"
- end
- | interp_lazy_static env (AST_LET (x, e1, e2)) =
- let
- val v1 = interp_lazy_static env e1
- val env_new = Env (update env x v1)
- in
- interp_lazy_static env_new e2
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement