Skip to content

Commit

Permalink
refactor: add ast to dyn converters
Browse files Browse the repository at this point in the history
  • Loading branch information
rgrinberg committed Oct 26, 2024
1 parent 74b72bb commit a08191a
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 3 deletions.
58 changes: 58 additions & 0 deletions lib/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ type ('a, _) ast =
| No_case : 'a -> ('a, [> `Cased ]) ast
| Case : 'a -> ('a, [> `Cased ]) ast

let dyn_of_ast f =
let open Dyn in
function
| Alternative xs -> variant "Alternative" (List.map xs ~f)
| No_case a -> variant "No_case" [ f a ]
| Case a -> variant "Case" [ f a ]
;;

let empty_alternative : ('a, 'b) ast = Alternative []

let equal_ast (type a) eq (x : (a, [ `Uncased ]) ast) (y : (a, [ `Uncased ]) ast) =
Expand All @@ -28,6 +36,16 @@ type cset =
| Difference of cset * cset
| Cast of (cset, [ `Cased | `Uncased ]) ast

let rec dyn_of_cset =
let open Dyn in
function
| Cset cset -> variant "Cset" [ Cset.to_dyn cset ]
| Intersection xs -> variant "Intersection" (List.map xs ~f:dyn_of_cset)
| Complement xs -> variant "Complement" (List.map xs ~f:dyn_of_cset)
| Difference (x, y) -> variant "Difference" [ dyn_of_cset x; dyn_of_cset y ]
| Cast c -> variant "Cast" [ dyn_of_ast dyn_of_cset c ]
;;

type ('a, 'case) gen =
| Set of 'a
| Ast of (('a, 'case) gen, 'case) ast
Expand All @@ -50,6 +68,45 @@ type ('a, 'case) gen =
| Sem of Automata.Sem.t * ('a, 'case) gen
| Sem_greedy of Automata.Rep_kind.t * ('a, 'case) gen

let rec dyn_of_gen f =
let open Dyn in
function
| Set a -> variant "Set" [ f a ]
| Ast ast -> variant "Ast" [ dyn_of_ast (dyn_of_gen f) ast ]
| Sequence xs -> variant "Sequence" (List.map xs ~f:(dyn_of_gen f))
| Repeat (gen, min, max) ->
let base =
match max with
| None -> []
| Some x -> [ int x ]
in
variant "Repeat" (dyn_of_gen f gen :: int min :: base)
| Beg_of_line -> enum "Beg_of_line"
| End_of_line -> enum "End_of_line"
| Beg_of_word -> enum "Beg_of_word"
| End_of_word -> enum "End_of_word"
| Not_bound -> enum "Not_bound"
| Beg_of_str -> enum "Beg_of_str"
| End_of_str -> enum "End_of_str"
| Last_end_of_line -> enum "Last_end_of_line"
| Start -> enum "Start"
| Stop -> enum "Stop"
| Group (name, t) ->
let args =
let args = [ dyn_of_gen f t ] in
match name with
| None -> args
| Some name -> string name :: args
in
variant "Group" args
| No_group x -> variant "No_group" [ dyn_of_gen f x ]
| Nest x -> variant "Nest" [ dyn_of_gen f x ]
| Pmark (pmark, t) -> variant "Pmark" [ Pmark.to_dyn pmark; dyn_of_gen f t ]
| Sem (sem, t) -> variant "Sem" [ Automata.Sem.to_dyn sem; dyn_of_gen f t ]
| Sem_greedy (rep, t) ->
variant "Sem_greedy" [ Automata.Rep_kind.to_dyn rep; dyn_of_gen f t ]
;;

let rec pp_gen pp_cset fmt t =
let open Format in
let open Fmt in
Expand Down Expand Up @@ -123,6 +180,7 @@ let rec equal cset x1 x2 =
type t = (cset, [ `Cased | `Uncased ]) gen
type no_case = (Cset.t, [ `Uncased ]) gen

let to_dyn = dyn_of_gen dyn_of_cset
let pp = pp_gen pp_cset
let cset cset = Set (Cset cset)

Expand Down
1 change: 1 addition & 0 deletions lib/ast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type ('a, 'case) gen = private
type t = (cset, [ `Cased | `Uncased ]) gen
type no_case = (Cset.t, [ `Uncased ]) gen

val to_dyn : t -> Dyn.t
val pp : t Fmt.t
val merge_sequences : (Cset.t, [ `Uncased ]) gen list -> (Cset.t, [ `Uncased ]) gen list
val handle_case : bool -> t -> (Cset.t, [ `Uncased ]) gen
Expand Down
10 changes: 7 additions & 3 deletions lib/automata.ml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ module Sem = struct
| `First -> "first"
;;

let to_dyn t = Dyn.enum (to_string t)
let equal = Poly.equal
let pp ch k = Format.pp_print_string ch (to_string k)
end
Expand All @@ -95,10 +96,13 @@ module Rep_kind = struct
| `Non_greedy
]

let pp fmt = function
| `Greedy -> Format.pp_print_string fmt "Greedy"
| `Non_greedy -> Format.pp_print_string fmt "Non_greedy"
let to_string = function
| `Greedy -> "Greedy"
| `Non_greedy -> "Non_greedy"
;;

let to_dyn t = Dyn.enum (to_string t)
let pp fmt t = Format.pp_print_string fmt (to_string t)
end

module Mark : sig
Expand Down
2 changes: 2 additions & 0 deletions lib/automata.mli
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module Sem : sig
| `First
]

val to_dyn : t -> Dyn.t
val pp : t Fmt.t
end

Expand All @@ -49,6 +50,7 @@ module Rep_kind : sig
| `Non_greedy
]

val to_dyn : t -> Dyn.t
val pp : t Fmt.t
end

Expand Down
3 changes: 3 additions & 0 deletions lib/dyn.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type t =
| Int of int
| Tuple of t list
| Enum of string
| String of string
| List of t list
| Variant of string * t list
| Record of (string * t) list
Expand All @@ -11,3 +12,5 @@ let list x = List x
let int x = Int x
let pair x y = Tuple [ x; y ]
let record fields = Record fields
let enum x = Enum x
let string s = String s
1 change: 1 addition & 0 deletions lib_test/expect/import.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ let test_re ?pos ?len r s =
let rec sexp_of_dyn (t : Re_private.Dyn.t) : Base.Sexp.t =
match t with
| Int i -> Atom (Int.to_string i)
| String s -> Atom s
| Tuple xs -> List (List.map xs ~f:sexp_of_dyn)
| Enum s -> Atom s
| List xs -> List (List.map ~f:sexp_of_dyn xs)
Expand Down

0 comments on commit a08191a

Please sign in to comment.