aboutsummaryrefslogtreecommitdiff
path: root/lib/expression/repr.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/expression/repr.ml')
-rw-r--r--lib/expression/repr.ml127
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/expression/repr.ml b/lib/expression/repr.ml
new file mode 100644
index 0000000..4990236
--- /dev/null
+++ b/lib/expression/repr.ml
@@ -0,0 +1,127 @@
+open StdLabels
+
+let escape_dquote = Re.Str.regexp "'"
+let escape content = Re.Str.global_replace escape_dquote "\\'" content
+
+module E :
+ Sym.SYM_CHUNK
+ with type 'a obs = top:bool -> string
+ and type 'a path_repr = 'a -> string = struct
+ type 'a repr = top:bool -> string
+ type 'a obs = top:bool -> string
+ type 'a path_repr = 'a -> string
+
+ let observe x = x
+
+ let group : 'a repr list -> 'a repr =
+ fun args ~top ->
+ let args_repr = List.map ~f:(fun v -> v ~top) args in
+ let args = String.concat ~sep:", " args_repr in
+ "[" ^ args ^ "]"
+
+ let arguments : 'a repr list -> 'a repr =
+ fun args ~top ->
+ let args_repr = List.map ~f:(fun v -> v ~top) args in
+ let args = String.concat ~sep:", " args_repr in
+ "(" ^ args ^ ")"
+
+ let empty : unit -> 'a repr =
+ fun () ~top ->
+ match top with
+ | false -> "''"
+ | true -> ""
+
+ let literal : string -> 'a repr =
+ fun l ~top ->
+ if String.equal String.empty l then (empty ()) ~top
+ else
+ match int_of_string_opt l with
+ | Some _ -> l
+ | None -> "'" ^ escape l ^ "'"
+
+ let integer : string -> 'a repr =
+ fun l ~top -> if String.equal String.empty l then (empty ()) ~top else l
+
+ let expr : 'a repr -> 'a repr =
+ fun expr ~top ->
+ ignore top;
+ String.concat ~sep:"" [ "("; expr ~top:false; ")" ]
+
+ let path : 'b path_repr -> 'b -> 'a repr =
+ fun path_repr p ~top ->
+ ignore top;
+ path_repr p
+
+ let concat : 'a repr list -> 'a repr =
+ fun elems ~top ->
+ ignore top;
+ let top = false in
+ let strs = List.map elems ~f:(fun v -> v ~top) in
+ String.concat ~sep:" ^ " strs
+
+ let window : 'a repr T.window -> 'a repr list -> 'a repr list -> 'a repr =
+ fun name g1 sort ~top ->
+ ignore top;
+
+ let args1 = group ~top:false g1
+ and args2 = group ~top:false sort
+ and f_name = T.name_of_window name in
+ let args = [ args1; args2 ] in
+ let args =
+ match name with
+ | T.Counter -> args
+ | T.Min prefix_arg
+ | T.Max prefix_arg
+ | T.Previous prefix_arg
+ | T.Sum prefix_arg -> prefix_arg ~top:false :: args
+ in
+
+ f_name ^ "(" ^ String.concat ~sep:", " args ^ ")"
+
+ let nvl : 'a repr list -> 'a repr =
+ fun elems ~top ->
+ ignore top;
+ let args = arguments ~top:false elems in
+ "nvl" ^ args
+
+ let join : string -> 'a repr list -> 'a repr =
+ fun sep elems ~top ->
+ ignore top;
+ let header = literal sep in
+ let args = arguments ~top:false (header :: elems) in
+ "join" ^ args
+
+ let boperator : T.binary_operator -> 'a repr -> 'a repr -> 'a repr =
+ fun op arg1 arg2 ~top ->
+ ignore top;
+ let top = false in
+ let sep = T.name_of_operator op in
+ String.concat ~sep [ arg1 ~top; arg2 ~top ]
+
+ let gequality : T.binary_operator -> 'a repr -> 'a repr list -> 'a repr =
+ fun op arg1 arg2 ~top ->
+ ignore top;
+ let top = false in
+ let sep = T.name_of_operator op in
+ let args = group ~top:false arg2 in
+ String.concat ~sep [ arg1 ~top; args ]
+
+ let funct : string -> 'a repr list -> 'a repr =
+ fun f args ~top ->
+ ignore top;
+ let args = arguments ~top:false args in
+ f ^ args
+
+ let function' : T.funct -> 'a repr list -> 'a repr =
+ fun f args ~top ->
+ ignore top;
+ let args = arguments ~top:false args in
+ T.name_of_function f ^ args
+end
+
+module M = Sym.M (E)
+
+let repr : ?top:bool -> ('a -> string) -> 'a T.t -> string =
+ fun ?(top = false) printer expr ->
+ let repr = M.eval ~path_repr:printer expr in
+ E.observe repr ~top