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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
open Mo_def
open Syntax
open Source
type visitor =
{ visit_exp : exp -> exp;
visit_typ : typ -> typ;
visit_pat : pat -> pat;
visit_dec : dec -> dec;
visit_inst : inst -> inst;
}
let rec over_exp (v : visitor) (exp : exp) : exp =
v.visit_exp (match exp.it with
| ImportE _ | PrimE _ | VarE _ | LitE _ | ActorUrlE _ -> exp
| UnE (x, y, exp1) -> { exp with it = UnE (x, y, over_exp v exp1) }
| ShowE (x, exp1) -> { exp with it = ShowE (x, over_exp v exp1) }
| ToCandidE exps -> { exp with it = ToCandidE (List.map (over_exp v) exps) }
| FromCandidE (exp1) -> { exp with it = FromCandidE (over_exp v exp1) }
| ProjE (exp1, x) -> { exp with it = ProjE (over_exp v exp1, x) }
| OptE exp1 -> { exp with it = OptE (over_exp v exp1) }
| DoOptE exp1 -> { exp with it = DoOptE (over_exp v exp1) }
| BangE exp1 -> { exp with it = BangE (over_exp v exp1) }
| TagE (x, exp1) -> { exp with it = TagE (x, over_exp v exp1) }
| DotE (exp1, x) -> { exp with it = DotE (over_exp v exp1, x) }
| NotE exp1 -> { exp with it = NotE (over_exp v exp1) }
| AssertE (how, exp1) -> { exp with it = AssertE (how, over_exp v exp1) }
| LabelE (x, y, exp1) -> { exp with it = LabelE (x, y, over_exp v exp1) }
| BreakE (x, exp1) -> { exp with it = BreakE (x, over_exp v exp1) }
| RetE exp1 -> { exp with it = RetE (over_exp v exp1) }
| AnnotE (exp1, t) -> { exp with it = AnnotE (over_exp v exp1, over_typ v t) }
| AsyncE (s, tb, exp1) -> { exp with it = AsyncE (s, tb, over_exp v exp1) }
| AwaitE (s, exp1) -> { exp with it = AwaitE (s, over_exp v exp1) }
| ThrowE exp1 -> { exp with it = ThrowE (over_exp v exp1) }
| BinE (x, exp1, y, exp2) -> { exp with it = BinE (x, over_exp v exp1, y, over_exp v exp2) }
| IdxE (exp1, exp2) -> { exp with it = IdxE (over_exp v exp1, over_exp v exp2) }
| RelE (x, exp1, y, exp2) -> { exp with it = RelE (x, over_exp v exp1, y, over_exp v exp2) }
| AssignE (exp1, exp2) -> { exp with it = AssignE (over_exp v exp1, over_exp v exp2) }
| CallE (exp1, inst, exp2) -> { exp with it = CallE (over_exp v exp1, over_inst v inst, over_exp v exp2) }
| AndE (exp1, exp2) -> { exp with it = AndE (over_exp v exp1, over_exp v exp2) }
| OrE (exp1, exp2) -> { exp with it = OrE (over_exp v exp1, over_exp v exp2) }
| ImpliesE (exp1, exp2) -> { exp with it = ImpliesE (over_exp v exp1, over_exp v exp2) }
| OldE exp1 -> { exp with it = OldE (over_exp v exp1) }
| WhileE (exp1, exp2) -> { exp with it = WhileE (over_exp v exp1, over_exp v exp2) }
| LoopE (exp1, exp2_opt) -> { exp with it = LoopE (over_exp v exp1, Option.map (over_exp v) exp2_opt) }
| ForE (x, exp1, exp2) -> { exp with it = ForE (x, over_exp v exp1, over_exp v exp2) }
| DebugE exp1 -> { exp with it = DebugE (over_exp v exp1) }
| TupE exps -> { exp with it = TupE (List.map (over_exp v) exps) }
| ArrayE (x, exps) -> { exp with it = ArrayE (x, List.map (over_exp v) exps) }
| BlockE ds -> { exp with it = BlockE (List.map (over_dec v) ds) }
| ObjBlockE (x, (n, t), dfs) -> { exp with it = ObjBlockE (x, (n, Option.map (over_typ v) t), List.map (over_dec_field v) dfs) }
| ObjE (bases, efs) -> { exp with it = ObjE (List.map (over_exp v) bases, List.map (over_exp_field v) efs) }
| IfE (exp1, exp2, exp3) -> { exp with it = IfE(over_exp v exp1, over_exp v exp2, over_exp v exp3) }
| TryE (exp1, cases, exp2) -> { exp with it = TryE (over_exp v exp1, List.map (over_case v) cases, Option.map (over_exp v) exp2) }
| SwitchE (exp1, cases) -> { exp with it = SwitchE (over_exp v exp1, List.map (over_case v) cases) }
| FuncE (name, sort_pat, typ_binds, pat, typ_opt, sugar, exp1) -> { exp with it = FuncE (name, sort_pat, typ_binds, over_pat v pat, Option.map (over_typ v) typ_opt, sugar, over_exp v exp1) }
| IgnoreE exp1 -> { exp with it = IgnoreE (over_exp v exp1)})
and over_typ (v : visitor) (t : typ) : typ = v.visit_typ t
and over_inst (v : visitor) (i : inst) : inst = v.visit_inst i
and over_pat (v : visitor) (p : pat) : pat =
v.visit_pat (match p.it with
| WildP | VarP _ | LitP _ | SignP _ -> p
| TupP ps -> { p with it = TupP (List.map (over_pat v) ps) }
| ObjP pfs -> { p with it = ObjP (List.map (over_pat_field v) pfs) }
| OptP p1 -> { p with it = OptP (over_pat v p1) }
| TagP (x, p1) -> { p with it = TagP (x, over_pat v p1) }
| AltP (p1, p2) -> { p with it = AltP (over_pat v p1, over_pat v p2) }
| AnnotP (p1, t) -> { p with it = AnnotP (over_pat v p1, over_typ v t) }
| ParP p1 -> { p with it = ParP (over_pat v p1) })
and over_dec (v : visitor) (d : dec) : dec =
v.visit_dec (match d.it with
| TypD (tid, tbs, t) -> { d with it = TypD (tid, tbs, over_typ v t) }
| ExpD e -> { d with it = ExpD (over_exp v e)}
| VarD (x, e) -> { d with it = VarD (x, over_exp v e)}
| LetD (p, e, fail) -> { d with it = LetD (over_pat v p, over_exp v e, Option.map (over_exp v) fail)}
| ClassD (sp, cid, tbs, p, t_o, s, id, dfs) -> { d with it = ClassD (sp, cid, tbs, over_pat v p, Option.map (over_typ v) t_o, s, id, List.map (over_dec_field v) dfs)})
and over_dec_field (v : visitor) (df : dec_field) : dec_field =
{ df with it = { df.it with dec = over_dec v df.it.dec } }
and over_exp_field (v : visitor) (ef : exp_field) : exp_field =
{ ef with it = { ef.it with exp = over_exp v ef.it.exp } }
and over_pat_field (v : visitor) (pf : pat_field) : pat_field =
{ pf with it = { pf.it with pat = over_pat v pf.it.pat } }
and over_case (v : visitor) (case : case) : case =
{ case with it = { pat = over_pat v case.it.pat;
exp = over_exp v case.it.exp } }
and over_prog (v : visitor) (prog : prog) : prog =
{ prog with it = List.map (over_dec v) prog.it }