@@ -39,10 +39,9 @@ let make_error (name : string) (json : Json.t) =
39
39
let itemName = get_field_name json in
40
40
make_error_wrong_operation name itemName json
41
41
42
- let empty = Ok []
43
-
44
42
module Output = struct
45
43
let return x = Ok [ x ]
44
+ let empty = Ok []
46
45
47
46
let lift2 (f : 'a -> 'b -> 'c ) (mx : ('a, string) result )
48
47
(my : ('b, string) result ) : ('c, string) result =
60
59
61
60
let ( let * ) = Output. bind
62
61
62
+ module Operators = struct
63
+ let not (json : Json.t ) =
64
+ match json with
65
+ | `Bool false | `Null -> Output. return (`Bool true )
66
+ | _ -> Output. return (`Bool false )
67
+
68
+ let rec merge_map ~(eq_f : 'a -> 'a -> 'b ) ~(f : 'a -> 'b )
69
+ (cmp : 'a -> 'a -> int ) (l1 : 'a list ) (l2 : 'a list ) : 'b list =
70
+ match (l1, l2) with
71
+ | [] , l2 -> List. map f l2
72
+ | l1 , [] -> List. map f l1
73
+ | h1 :: t1 , h2 :: t2 ->
74
+ let r = cmp h1 h2 in
75
+ if r = 0 then eq_f h1 h2 :: merge_map ~eq_f ~f cmp t1 t2
76
+ else if r < 0 then f h1 :: merge_map ~eq_f ~f cmp t1 l2
77
+ else f h2 :: merge_map ~eq_f ~f cmp l1 t2
78
+
79
+ let rec add str (left : Json.t ) (right : Json.t ) :
80
+ (Json. t list , string ) result =
81
+ match (left, right) with
82
+ | `Float l , `Float r -> Output. return (`Float (l +. r))
83
+ | `Int l , `Float r -> Output. return (`Float (float_of_int l +. r))
84
+ | `Float l , `Int r -> Output. return (`Float (l +. float_of_int r))
85
+ | `Int l , `Int r ->
86
+ Output. return (`Float (float_of_int l +. float_of_int r))
87
+ | `Null , `Int r | `Int r , `Null -> Output. return (`Float (float_of_int r))
88
+ | `Null , `Float r | `Float r , `Null -> Output. return (`Float r)
89
+ | `String l , `String r -> Output. return (`String (l ^ r))
90
+ | `Null , `String r | `String r , `Null -> Output. return (`String r)
91
+ | `Assoc l , `Assoc r -> (
92
+ let cmp (key1 , _ ) (key2 , _ ) = String. compare key1 key2 in
93
+ let eq_f (key , v1 ) (_ , v2 ) =
94
+ let * result = add str v1 v2 in
95
+ Output. return (key, result)
96
+ in
97
+ match merge_map ~f: Output. return ~eq_f cmp l r |> Output. collect with
98
+ | Ok l -> Output. return (`Assoc l)
99
+ | Error e -> Error e)
100
+ | `Null , `Assoc r | `Assoc r , `Null -> Output. return (`Assoc r)
101
+ | `List l , `List r -> Output. return (`List (l @ r))
102
+ | `Null , `List r | `List r , `Null -> Output. return (`List r)
103
+ | `Null , `Null -> Output. return `Null
104
+ | _ -> Error (make_error str left)
105
+
106
+ let apply_op str fn (left : Json.t ) (right : Json.t ) =
107
+ match (left, right) with
108
+ | `Float l , `Float r -> Output. return (`Float (fn l r))
109
+ | `Int l , `Float r -> Output. return (`Float (fn (float_of_int l) r))
110
+ | `Float l , `Int r -> Output. return (`Float (fn l (float_of_int r)))
111
+ | `Int l , `Int r ->
112
+ Output. return (`Float (fn (float_of_int l) (float_of_int r)))
113
+ | _ -> Error (make_error str left)
114
+
115
+ let compare str fn (left : Json.t ) (right : Json.t ) =
116
+ match (left, right) with
117
+ | `Float l , `Float r -> Output. return (`Bool (fn l r))
118
+ | `Int l , `Float r -> Output. return (`Bool (fn (float_of_int l) r))
119
+ | `Float l , `Int r -> Output. return (`Bool (fn l (float_of_int r)))
120
+ | `Int l , `Int r ->
121
+ Output. return (`Bool (fn (float_of_int l) (float_of_int r)))
122
+ | _ -> Error (make_error str right)
123
+
124
+ let condition (str : string ) (fn : bool -> bool -> bool ) (left : Json.t )
125
+ (right : Json.t ) =
126
+ match (left, right) with
127
+ | `Bool l , `Bool r -> Output. return (`Bool (fn l r))
128
+ | _ -> Error (make_error str right)
129
+
130
+ let gt = compare " >" ( > )
131
+ let gte = compare " >=" ( > = )
132
+ let lt = compare " <" ( < )
133
+ let lte = compare " <=" ( < = )
134
+ let and_ = condition " and" ( && )
135
+ let or_ = condition " or" ( || )
136
+ let eq l r = Output. return (`Bool (l = r))
137
+ let notEq l r = Output. return (`Bool (l <> r))
138
+ let add = add " +"
139
+ let sub = apply_op " -" (fun l r -> l -. r)
140
+ let mult = apply_op " *" (fun l r -> l *. r)
141
+ let div = apply_op " /" (fun l r -> l /. r)
142
+ end
143
+
63
144
let keys (json : Json.t ) =
64
145
match json with
65
146
| `Assoc _list ->
@@ -101,15 +182,11 @@ let range ?step from upto =
101
182
let rec range ?(step = 1 ) start stop =
102
183
if step = 0 then []
103
184
else if (step > 0 && start > = stop) || (step < 0 && start < = stop) then []
104
- else start :: range ~step (start + step) stop
185
+ else `Int start :: range ~step (start + step) stop
105
186
in
106
187
match upto with
107
- | None ->
108
- List. map (fun i -> Output. return (`Int i)) (range 1 from)
109
- |> Output. collect
110
- | Some upto ->
111
- List. map (fun i -> Output. return (`Int i)) (range ?step from upto)
112
- |> Output. collect
188
+ | None -> Output. return (range 1 from)
189
+ | Some upto -> Output. return (range ?step from upto)
113
190
114
191
let split expr json =
115
192
match json with
@@ -142,48 +219,6 @@ let length (json : Json.t) =
142
219
| `List list -> Output. return (`Int (list |> List. length))
143
220
| _ -> Error (make_error " length" json)
144
221
145
- let not (json : Json.t ) =
146
- match json with
147
- | `Bool false | `Null -> Output. return (`Bool true )
148
- | _ -> Output. return (`Bool false )
149
-
150
- let apply str fn (left : Json.t ) (right : Json.t ) =
151
- match (left, right) with
152
- | `Float l , `Float r -> Output. return (`Float (fn l r))
153
- | `Int l , `Float r -> Output. return (`Float (fn (float_of_int l) r))
154
- | `Float l , `Int r -> Output. return (`Float (fn l (float_of_int r)))
155
- | `Int l , `Int r ->
156
- Output. return (`Float (fn (float_of_int l) (float_of_int r)))
157
- | _ -> Error (make_error str left)
158
-
159
- let compare str fn (left : Json.t ) (right : Json.t ) =
160
- match (left, right) with
161
- | `Float l , `Float r -> Output. return (`Bool (fn l r))
162
- | `Int l , `Float r -> Output. return (`Bool (fn (float_of_int l) r))
163
- | `Float l , `Int r -> Output. return (`Bool (fn l (float_of_int r)))
164
- | `Int l , `Int r ->
165
- Output. return (`Bool (fn (float_of_int l) (float_of_int r)))
166
- | _ -> Error (make_error str right)
167
-
168
- let condition (str : string ) (fn : bool -> bool -> bool ) (left : Json.t )
169
- (right : Json.t ) =
170
- match (left, right) with
171
- | `Bool l , `Bool r -> Output. return (`Bool (fn l r))
172
- | _ -> Error (make_error str right)
173
-
174
- let gt = compare " >" ( > )
175
- let gte = compare " >=" ( > = )
176
- let lt = compare " <" ( < )
177
- let lte = compare " <=" ( < = )
178
- let and_ = condition " and" ( && )
179
- let or_ = condition " or" ( || )
180
- let eq l r = Output. return (`Bool (l = r))
181
- let notEq l r = Output. return (`Bool (l <> r))
182
- let add = apply " +" (fun l r -> l +. r)
183
- let sub = apply " -" (fun l r -> l -. r)
184
- let mult = apply " *" (fun l r -> l *. r)
185
- let div = apply " /" (fun l r -> l /. r)
186
-
187
222
let filter (fn : Json.t -> bool ) (json : Json.t ) =
188
223
match json with
189
224
| `List list -> Ok (`List (List. filter fn list ))
@@ -288,15 +323,15 @@ let slice (start : int option) (finish : int option) (json : Json.t) =
288
323
289
324
let iterator (json : Json.t ) =
290
325
match json with
291
- | `List [] -> empty
326
+ | `List [] -> Output. empty
292
327
| `List items -> Ok items
293
328
| `Assoc obj -> Ok (List. map snd obj)
294
329
| _ -> Error (make_error " []" json)
295
330
296
331
let rec compile expression json : (Json.t list, string) result =
297
332
match expression with
298
333
| Identity -> Output. return json
299
- | Empty -> empty
334
+ | Empty -> Output. empty
300
335
| Keys -> keys json
301
336
| Key key -> member key json
302
337
| Optional expr -> (
@@ -309,9 +344,10 @@ let rec compile expression json : (Json.t list, string) result =
309
344
| Head -> head json
310
345
| Tail -> tail json
311
346
| Length -> length json
312
- | Not -> not json
347
+ | Not -> Operators. not json
313
348
| Map expr -> map expr json
314
349
| Operation (left , op , right ) -> (
350
+ let open Operators in
315
351
match op with
316
352
| Add -> operation left right add json
317
353
| Sub -> operation left right sub json
@@ -337,32 +373,44 @@ let rec compile expression json : (Json.t list, string) result =
337
373
| Select conditional -> (
338
374
let * res = compile conditional json in
339
375
match res with
340
- | `Bool b -> ( match b with true -> Output. return json | false -> empty)
376
+ | `Bool b -> (
377
+ match b with true -> Output. return json | false -> Output. empty)
341
378
| _ -> Error (make_error " select" res))
342
379
| List exprs ->
343
380
Output. collect (List. map (fun expr -> compile expr json) exprs)
344
381
|> Result. map (fun x -> [ `List x ])
345
382
| Comma (leftR , rightR ) ->
346
383
Result. bind (compile leftR json) (fun left ->
347
384
Result. bind (compile rightR json) (fun right -> Ok (left @ right)))
385
+ | Object [] -> Output. return (`Assoc [] )
348
386
| Object list -> handle_objects list json
349
387
| Has e -> (
350
388
match e with
351
389
| Literal ((String _ | Number _ ) as e ) -> has json e
352
390
| _ -> Error (show_expression e ^ " is not allowed" ))
353
391
| In e -> in_ json e
354
- | Range (from , upto , step ) -> range ?step from upto
392
+ | Range (from , upto , step ) -> Result. map List. flatten ( range ?step from upto)
355
393
| Reverse -> (
356
394
match json with
357
395
| `List l -> Output. return (`List (List. rev l))
358
396
| _ -> Error (make_error " reverse" json))
359
397
| Split expr -> split expr json
360
398
| Join expr -> join expr json
361
- | Abs -> (
399
+ | Fun Abs -> (
362
400
match json with
363
401
| `Int n -> Output. return (`Int (if n < 0 then - n else n))
364
402
| `Float j -> Output. return (`Float (if j < 0. then -. j else j))
365
403
| _ -> Error (make_error " reverse" json))
404
+ | Fun Add -> (
405
+ match json with
406
+ | `List [] -> Output. return `Null
407
+ | `List l ->
408
+ List. fold_left
409
+ (fun acc el ->
410
+ let * acc = acc in
411
+ Operators. add acc el)
412
+ (Output. return `Null ) l
413
+ | _ -> Error (make_error " add" json))
366
414
| IfThenElse (cond , if_branch , else_branch ) -> (
367
415
let * cond = compile cond json in
368
416
match cond with
0 commit comments