summaryrefslogtreecommitdiff
path: root/Jennisys/AstUtils.fs
blob: 794a89dc171c8a3170a6dc0a50c065a4a68b9dae (plain)
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
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 Fields members =
  members |> List.choose (function Field(vd) -> Some(vd) | _ -> None)

let Methods prog = 
  match prog with
  | Program(components) ->
      components |> List.fold (fun acc comp -> 
        match comp with
        | Component(Class(_,_,members),_,_) -> List.concat [acc ; members |> List.choose (fun m -> Some(comp, m))]            
        | _ -> acc) []

let AllFields c = 
  match c with
  | Component(Class(_,_,members), Model(_,_,cVars,_,_), _) ->
      let aVars = Fields members
      List.concat [aVars ; cVars]
  | _ -> []

let GetClassName comp =
  match comp with
  | Component(Class(name,_,_),_,_) -> name
  | _ -> 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 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