blob: 7db263fbcf7817a1a9648d9e663deb7f6415262f [file] [edit]
open Util
open Source
open Ast
open Xl
module type Arg =
sig
val visit_atom : atom -> unit
val visit_mixop : mixop -> unit
val visit_typid : id -> unit
val visit_relid : id -> unit
val visit_ruleid : id -> unit
val visit_varid : id -> unit
val visit_defid : id -> unit
val visit_gramid : id -> unit
val visit_typ : typ -> unit
val visit_deftyp : deftyp -> unit
val visit_exp : exp -> unit
val visit_path : path -> unit
val visit_sym : sym -> unit
val visit_prem : prem -> unit
val visit_def : def -> unit
val visit_hint : hint -> unit
end
module Skip =
struct
let visit_atom _ = ()
let visit_mixop _ = ()
let visit_typid _ = ()
let visit_relid _ = ()
let visit_ruleid _ = ()
let visit_varid _ = ()
let visit_defid _ = ()
let visit_gramid _ = ()
let visit_typ _ = ()
let visit_deftyp _ = ()
let visit_exp _ = ()
let visit_path _ = ()
let visit_sym _ = ()
let visit_prem _ = ()
let visit_def _ = ()
let visit_hint _ = ()
end
module Make(X : Arg) =
struct
open X
let opt = Option.iter
let list = List.iter
let pair f1 f2 (x1, x2) = f1 x1; f2 x2
(* Identifiers, operators, literals *)
let bool _b = ()
let num _n = ()
let text _s = ()
let atom at = visit_atom at
let mixop at = visit_mixop at
let typid x = visit_typid x
let relid x = visit_relid x
let ruleid x = visit_ruleid x
let varid x = visit_varid x
let defid x = visit_defid x
let gramid x = visit_gramid x
let unop _op = ()
let binop _op = ()
let cmpop _op = ()
let hint h = visit_hint h
let hints = list hint
(* Iterations *)
let rec iter it =
match it with
| Opt | List | List1 -> ()
| ListN (e, xo) -> exp e; opt varid xo
(* Types *)
and dots _ = ()
and numtyp _nt = ()
and optyp = function #Bool.typ -> () | #Num.typ as nt -> numtyp nt
and typ t =
visit_typ t;
match t.it with
| VarT (x, as_) -> typid x; args as_
| BoolT | TextT -> ()
| NumT nt -> numtyp nt
| TupT ets -> list (pair exp typ) ets
| IterT (t1, it) -> typ t1; iter it
and deftyp t =
visit_deftyp t;
match t.it with
| AliasT t -> typ t
| StructT tfs -> list typfield tfs
| VariantT tcs -> list typcase tcs
and typfield (at, (bs, t, prs), hs) = atom at; binds bs; typ t; prems prs; hints hs
and typcase (op, (bs, t, prs), hs) = mixop op; binds bs; typ t; prems prs; hints hs
(* Expressions *)
and exp e =
visit_exp e;
match e.it with
| VarE x -> varid x
| BoolE b -> bool b
| NumE n -> num n
| TextE s -> text s
| UnE (op, ot, e1) -> unop op; optyp ot; exp e1
| BinE (op, ot, e1, e2) -> binop op; optyp ot; exp e1; exp e2
| CmpE (op, ot, e1, e2) -> cmpop op; optyp ot; exp e1; exp e2
| TupE es | ListE es -> list exp es
| ProjE (e1, _) | TheE e1 | LiftE e1 | LenE e1 -> exp e1
| CaseE (op, e1) -> mixop op; exp e1
| UncaseE (e1, op) -> exp e1; mixop op
| OptE eo -> opt exp eo
| StrE efs -> list expfield efs
| DotE (e1, at) -> exp e1; atom at
| CompE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) | IdxE (e1, e2) -> exp e1; exp e2
| SliceE (e1, e2, e3) -> exp e1; exp e2; exp e3
| UpdE (e1, p, e2) | ExtE (e1, p, e2) -> exp e1; path p; exp e2
| CallE (x, as_) -> defid x; args as_
| IterE (e1, it) -> exp e1; iterexp it
| CvtE (e1, nt1, nt2) -> exp e1; numtyp nt1; numtyp nt2
| SubE (e1, t1, t2) -> exp e1; typ t1; typ t2
and expfield (at, e) = atom at; exp e
and path p =
visit_path p;
match p.it with
| RootP -> ()
| IdxP (p1, e) -> path p1; exp e
| SliceP (p1, e1, e2) -> path p1; exp e1; exp e2
| DotP (p1, at) -> path p1; atom at
and iterexp (it, xes) = iter it; list (pair varid exp) xes
(* Grammars *)
and sym g =
visit_sym g;
match g.it with
| VarG (x, as_) -> gramid x; args as_
| NumG n -> num (`Nat (Z.of_int n))
| TextG s -> text s
| EpsG -> ()
| SeqG gs | AltG gs -> list sym gs
| RangeG (g1, g2) -> sym g1; sym g2
| IterG (g1, it) -> sym g1; iterexp it
| AttrG (e, g1) -> exp e; sym g1
(* Premises *)
and prem pr =
visit_prem pr;
match pr.it with
| RulePr (x, op, e) -> relid x; mixop op; exp e
| IfPr e -> exp e
| ElsePr -> ()
| IterPr (pr1, it) -> prem pr1; iterexp it
| LetPr (e1, e2, _) -> exp e1; exp e2
and prems prs = list prem prs
(* Definitions *)
and arg a =
match a.it with
| ExpA e -> exp e
| TypA t -> typ t
| DefA x -> defid x
| GramA g -> sym g
and bind b =
match b.it with
| ExpB (id, t) -> varid id; typ t
| TypB id -> typid id
| DefB (id, ps, t) -> defid id; params ps; typ t
| GramB (id, ps, t) -> gramid id; params ps; typ t
and param p =
match p.it with
| ExpP (x, t) -> varid x; typ t
| TypP x -> typid x
| DefP (x, ps, t) -> defid x; params ps; typ t
| GramP (x, t) -> gramid x; typ t
and args as_ = list arg as_
and binds bs = list bind bs
and params ps = list param ps
let hintdef d =
match d.it with
| TypH (x, hs) -> typid x; hints hs
| RelH (x, hs) -> relid x; hints hs
| DecH (x, hs) -> defid x; hints hs
| GramH (x, hs) -> gramid x; hints hs
let inst i =
match i.it with
| InstD (bs, as_, dt) -> binds bs; args as_; deftyp dt
let rule r =
match r.it with
| RuleD (x, bs, op, e, prs) -> ruleid x; binds bs; mixop op; exp e; prems prs
let clause c =
match c.it with
| DefD (bs, as_, e, prs) -> binds bs; args as_; exp e; prems prs
let prod p =
match p.it with
| ProdD (bs, g, e, prs) -> binds bs; sym g; exp e; prems prs
let rec def d =
visit_def d;
match d.it with
| TypD (x, ps, insts) -> typid x; params ps; list inst insts
| RelD (x, op, t, rules) -> relid x; mixop op; typ t; list rule rules
| DecD (x, ps, t, clauses) -> defid x; params ps; typ t; list clause clauses
| GramD (x, ps, t, prods) -> gramid x; params ps; typ t; list prod prods
| RecD ds -> list def ds
| HintD hd -> hintdef hd
end