@ -443,6 +443,28 @@ let concat elts = _Concat elts
let apply sym args = _ Apply sym args
(* * Traverse *)
let trms = function
| Var _ | Z _ | Q _ -> Iter . empty
| Arith a -> Arith . trms a
| Splat x -> Iter . ( cons x empty )
| Sized { seq ; siz } -> Iter . ( cons seq ( cons siz empty ) )
| Extract { seq ; off ; len } -> Iter . ( cons seq ( cons off ( cons len empty ) ) )
| Concat xs | Apply ( _ , xs ) -> Iter . of_array xs
let is_atomic = function
| Var _ | Z _ | Q _ | Concat [| |] | Apply ( _ , [| |] ) -> true
| Arith _ | Splat _ | Sized _ | Extract _ | Concat _ | Apply _ -> false
let rec atoms e =
if is_atomic e then Iter . return e else Iter . flat_map ~ f : atoms ( trms e )
(* * Query *)
let fv e = Var . Set . of_iter ( vars e )
let rec height e = 1 + Iter . fold ~ f : ( fun x -> max ( height x ) ) ( trms e ) 0
(* * Transform *)
let rec map_vars e ~ f =
@ -470,26 +492,3 @@ let map e ~f =
map3 f e ( fun seq off len -> _ Extract ~ seq ~ off ~ len ) seq off len
| Concat xs -> mapN f e _ Concat xs
| Apply ( g , xs ) -> mapN f e ( _ Apply g ) xs
(* * Traverse *)
let trms = function
| Var _ | Z _ | Q _ -> Iter . empty
| Arith a -> Arith . trms a
| Splat x -> Iter . ( cons x empty )
| Sized { seq = x ; siz = y } -> Iter . ( cons x ( cons y empty ) )
| Extract { seq = x ; off = y ; len = z } ->
Iter . ( cons x ( cons y ( cons z empty ) ) )
| Concat xs | Apply ( _ , xs ) -> Iter . of_array xs
let is_atomic = function
| Var _ | Z _ | Q _ | Concat [| |] | Apply ( _ , [| |] ) -> true
| Arith _ | Splat _ | Sized _ | Extract _ | Concat _ | Apply _ -> false
let rec atoms e =
if is_atomic e then Iter . return e else Iter . flat_map ~ f : atoms ( trms e )
(* * Query *)
let fv e = Var . Set . of_iter ( vars e )
let rec height e = 1 + Iter . fold ~ f : ( fun x -> max ( height x ) ) ( trms e ) 0