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
|
module AstUtils
open Ast
let BinaryAnd (lhs: Expr) (rhs: Expr) =
match lhs, rhs with
| IdLiteral("true"), _ -> rhs
| IdLiteral("false"), _ -> IdLiteral("false")
| _, IdLiteral("true") -> lhs
| _, IdLiteral("false") -> IdLiteral("false")
| _, _ -> BinaryExpr(30, "&&", lhs, rhs)
let BinaryOr (lhs: Expr) (rhs: Expr) =
match lhs, rhs with
| IdLiteral("true"), _ -> IdLiteral("true")
| IdLiteral("false"), _ -> rhs
| _, IdLiteral("true") -> IdLiteral("true")
| _, IdLiteral("false") -> lhs
| _, _ -> BinaryExpr(30, "||", lhs, rhs)
let BinaryImplies lhs rhs = BinaryExpr(20, "==>", lhs, rhs)
let BinaryNeq lhs rhs = BinaryExpr(40, "!=", lhs, rhs)
let TrueLiteral = IdLiteral("true")
let FalseLiteral = IdLiteral("false")
// --- search functions ---
let FilterFieldMembers members =
members |> List.choose (function Field(vd) -> Some(vd) | _ -> None)
let FilterConstructorMembers members =
members |> List.choose (function Method(_,_,_,_, true) as m -> Some(m) | _ -> None)
let FilterMethodMembers members =
members |> List.choose (function Method(_,_,_,_,_) as m -> Some(m) | _ -> None)
let FilterMembers prog filter =
match prog with
| Program(components) ->
components |> List.fold (fun acc comp ->
match comp with
| Component(Class(_,_,members),_,_) -> List.concat [acc ; members |> filter |> List.choose (fun m -> Some(comp, m))]
| _ -> acc) []
let AllFields c =
match c with
| Component(Class(_,_,members), Model(_,_,cVars,_,_), _) ->
let aVars = FilterFieldMembers members
List.concat [aVars ; cVars]
| _ -> []
let GetClassName comp =
match comp with
| Component(Class(name,_,_),_,_) -> name
| _ -> failwith ("unrecognized component: " + comp.ToString())
let GetMethodName mthd =
match mthd with
| Method(name,_,_,_,_) -> name
| _ -> failwith ("not a method: " + mthd.ToString())
let GetMembers comp =
match comp with
| Component(Class(_,_,members),_,_) -> members
| _ -> failwith ("unrecognized component: " + comp.ToString())
let FindComponent (prog: Program) clsName =
match prog with
| Program(comps) -> comps |> List.filter (function Component(Class(name,_,_),_,_) when name = clsName -> true | _ -> false)
|> Utils.ListToOption
let FindMethod comp methodName =
GetMembers comp |> FilterMethodMembers |> List.filter (function Method(name,_,_,_,_) when name = methodName -> true | _ -> false)
|> Utils.ListToOption
let FindVar (prog: Program) clsName fldName =
let copt = FindComponent prog clsName
match copt with
| Some(comp) ->
AllFields comp |> List.filter (function Var(name,_) when name = fldName -> true | _ -> false)
|> Utils.ListToOption
| None -> None
|