-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevaluator.sml
More file actions
67 lines (65 loc) · 1.81 KB
/
evaluator.sml
File metadata and controls
67 lines (65 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
structure Evaluator :> EVALUATOR =
struct
structure L = MinMLTyped
structure U = TypedUtil
exception Stuck of MinMLTyped.expr
fun eval (L.EVar (k,s)) = L.EVar (k,s)
| eval (L.EApp (e1, e2)) =
let
val v1 = eval e1
val v2 = eval e2
in
case v1 of (L.ELam (t, v1')) => eval (U.termSubstTop v2 v1')
| _ => raise Stuck (L.EApp (v1, v2))
end
| eval (L.ELam (t, e)) = L.ELam (t,e)
| eval (L.EPlam e) = L.EPlam e
| eval (L.EPapp (e, t)) =
let
val e_final = eval e
in
case e_final of (L.EPlam e') => eval (U.typeTermSubstTop t e')
| _ => raise Stuck (L.EPapp (e_final, t))
end
| eval (L.EFix (t, e)) = eval (U.termSubstTop (L.EFix (t, e)) e)
| eval (L.ELet (e1, e2)) =
let
val v1 = eval e1
in
eval (U.termSubstTop v1 e2)
end
| eval L.EUnit = L.EUnit
| eval (L.EPair (e1, e2)) = L.EPair (eval e1, eval e2)
| eval (L.EFst e) =
let
val v = eval e
in
case v of (L.EPair (v1, v2)) => v1
| _ => raise Stuck (L.EFst v)
end
| eval (L.ESnd e) =
let
val v = eval e
in
case v of (L.EPair (v1, v2)) => v2
| _ => raise Stuck (L.ESnd v)
end
| eval (L.EInl (e, t)) = L.EInl (eval e, t)
| eval (L.EInr (e, t)) = L.EInr (eval e, t)
| eval (L.ECase (e, e1, e2)) =
let
val cond = eval e
in
case cond of (L.EInl (e', t)) => eval (U.termSubstTop e' e1)
| (L.EInr (e', t)) => eval (U.termSubstTop e' e2)
| _ => raise Stuck (L.ECase (cond, e1, e2))
end
| eval (L.ERollList e) = L.ERollList (eval e)
| eval (L.EUnrollList e) =
let
val v = eval e
in
case v of (L.ERollList v') => v'
| _ => raise Stuck (L.EUnrollList v)
end
end