blob: bd937f65be3fdd008f14a782e59aecdf5a66e935 [file] [log] [blame] [edit]
open Util.Source
open Ast
include Xl.Gen_free
(* Aggregates *)
let free_nl_elem free_x = function Nl -> empty | Elem x -> free_x x
let free_nl_list free_x xs = List.(fold_left (++) empty (map (free_nl_elem free_x) xs))
(* Identifiers *)
let free_typid id =
let id' = Convert.strip_var_suffix id in
match (Convert.typ_of_varid id').it with
| VarT _ -> Xl.Gen_free.free_typid id'
| _ -> empty
let free_op op = {empty with varid = Set.singleton op}
(* Iterations *)
let rec free_iter iter =
match iter with
| Opt | List | List1 -> empty
| ListN (e, id_opt) -> free_exp e ++ free_opt free_varid id_opt
(* Types *)
and free_typ t =
match t.it with
| VarT (id, as_) -> free_typid id ++ free_args as_
| BoolT | NumT _ | TextT -> empty
| ParenT t1 -> free_typ t1
| TupT ts -> free_list free_typ ts
| IterT (t1, iter) -> free_typ t1 ++ free_iter iter
| StrT (_, ts, tfs, _) ->
free_nl_list free_typ ts ++
free_nl_list (fun tf -> free_typfield tf) tfs
| CaseT (_, ts, tcs, _) ->
free_nl_list free_typ ts ++
free_nl_list (fun tc -> free_typcase tc) tcs
| ConT tc -> free_typcon tc
| RangeT tes -> free_nl_list free_typenum tes
| AtomT _ -> empty
| SeqT ts -> free_list free_typ ts
| InfixT (t1, _, t2) -> free_typ t1 ++ free_typ t2
| BrackT (_, t1, _) -> free_typ t1
and free_typfield (_, (t, prems), _) = free_typ t ++ free_prems prems
and free_typcase (_, (t, prems), _) = free_typ t ++ free_prems prems
and free_typcon ((t, prems), _) = free_typ t ++ free_prems prems
and free_typenum (e, eo) = free_exp e ++ free_opt free_exp eo
(* Expressions *)
and free_unop = function
| #signop as op -> free_op (Print.string_of_unop op)
| _ -> empty
and free_exp e =
match e.it with
| VarE (id, as_) -> free_varid id ++ free_list free_arg as_
| AtomE _ | BoolE _ | NumE _ | TextE _ | EpsE | HoleE _ | LatexE _ -> empty
| UnE (op, e1) -> free_unop op ++ free_exp e1
| CvtE (e1, _) | DotE (e1, _) | LenE e1
| ParenE e1 | BrackE (_, e1, _) | ArithE e1 | UnparenE e1 -> free_exp e1
| SizeE id -> free_gramid id
| BinE (e1, _, e2) | CmpE (e1, _, e2)
| IdxE (e1, e2) | CommaE (e1, e2) | CatE (e1, e2) | MemE (e1, e2)
| InfixE (e1, _, e2) | FuseE (e1, e2) -> free_exp e1 ++ free_exp e2
| SliceE (e1, e2, e3) -> free_exp e1 ++ free_exp e2 ++ free_exp e3
| SeqE es | ListE es | TupE es -> free_list free_exp es
| UpdE (e1, p, e2) | ExtE (e1, p, e2) ->
free_exp e1 ++ free_path p ++ free_exp e2
| StrE efs -> free_nl_list free_expfield efs
| CallE (id, as_) -> free_defid id ++ free_list free_arg as_
| IterE (e1, iter) -> free_exp e1 ++ free_iter iter
| TypE (e1, t) -> free_exp e1 ++ free_typ t
and free_expfield (_, e) = free_exp e
and free_path p =
match p.it with
| RootP -> empty
| IdxP (p1, e) -> free_path p1 ++ free_exp e
| SliceP (p1, e1, e2) -> free_path p1 ++ free_exp e1 ++ free_exp e2
| DotP (p1, _) -> free_path p1
(* Grammars *)
and free_sym g =
match g.it with
| VarG (id, as_) -> free_gramid id ++ free_args as_
| NumG _ | TextG _ | EpsG -> empty
| SeqG gs | AltG gs -> free_nl_list free_sym gs
| RangeG (g1, g2) | FuseG (g1, g2) -> free_sym g1 ++ free_sym g2
| ParenG g1 | UnparenG g1 -> free_sym g1
| TupG gs -> free_list free_sym gs
| IterG (g1, iter) -> free_sym g1 ++ free_iter iter
| ArithG e -> free_exp e
| AttrG (e, g1) -> free_exp e ++ free_sym g1
and free_prod prod =
match prod.it with
| SynthP (g, e, prems) -> free_sym g ++ free_exp e ++ free_prems prems
| RangeP (g1, e1, g2, e2) ->
free_sym g1 ++ free_exp e1 ++ free_sym g2 ++ free_exp e2
| EquivP (g1, g2, prems) -> free_sym g1 ++ free_sym g2 ++ free_prems prems
and free_gram gram =
let (_dots1, prods, _dots2) = gram.it in
let s = free_nl_list free_prod prods in
{s with varid = Set.empty}
(* Premises *)
and free_prem prem =
match prem.it with
| VarPr (id, t) -> free_varid id ++ free_typ t
| RulePr (id, as_, e) -> free_relid id ++ free_args as_ ++ free_exp e
| IfPr e -> free_exp e
| ElsePr -> empty
| IterPr (prem1, iter) -> free_prem prem1 ++ free_iter iter
and free_prems prems = free_nl_list free_prem prems
(* Definitions *)
and free_arg a =
match !(a.it) with
| ExpA e -> free_exp e
| TypA t -> free_typ t
| GramA g -> free_sym g
| DefA id -> free_defid id
and free_param p =
match p.it with
| ExpP (_, t) -> free_typ t
| TypP _ -> empty
| GramP (_, ps, t) -> free_params ps ++ free_typ t -- bound_params ps -- impl_bound_typ ps t
| DefP (_, ps, t) -> free_params ps ++ free_typ t -- bound_params ps
and impl_bound_typ ps t = {empty with typid = (free_typ t).typid} -- bound_params ps
and bound_param p =
match p.it with
| ExpP (id, _) -> bound_varid id
| TypP id -> bound_typid id
| GramP (id, ps, t) -> bound_gramid id ++ impl_bound_typ ps t
| DefP (id, _, _) -> bound_defid id
and free_args as_ = free_list free_arg as_
and free_params ps = free_list_dep free_param bound_param ps
and bound_params ps = bound_list bound_param ps
let free_def d =
match d.it with
| FamD (_id, ps, _hints) ->
free_list free_param ps
| TypD (_id1, _id2, as_, t, _hints) ->
free_args as_ ++ free_typ t
| GramD (_id1, _id2, ps, t, gram, _hints) ->
free_params ps ++ (free_typ t ++ free_gram gram -- bound_params ps -- impl_bound_typ ps t)
| VarD (_id, t, _hints) -> free_typ t
| SepD -> empty
| RelD (_id, ps, t, _hints) -> free_typ t -- bound_params ps
| RuleD (id1, ps, _id2, e, prems, _hints) ->
free_relid id1 ++ (free_exp e ++ free_prems prems -- bound_params ps)
| DecD (_id, ps, t, _hints) ->
free_params ps ++ free_typ t -- bound_params ps
| DefD (id, as_, e, prems) ->
free_defid id ++ free_args as_ ++ free_exp e ++ free_prems prems
| HintD _ -> empty