@@ -22,6 +22,19 @@ let make_error_wrong_operation op member_kind (value : Json.t) =
22
22
^ " :" ^ Formatting. enter 1
23
23
^ Chalk. gray (Json. to_string value ~colorize: false ~summarize: true )
24
24
25
+ let make_empty_list_error op =
26
+ let open Console in
27
+ " Trying to "
28
+ ^ Formatting. single_quotes (Chalk. bold op)
29
+ ^ " on an empty array."
30
+
31
+ let make_acessing_to_missing_item access_index length =
32
+ let open Console in
33
+ " Trying to read "
34
+ ^ Formatting. single_quotes
35
+ (" [" ^ Chalk. bold (Int. to_string access_index) ^ " ]" )
36
+ ^ " from an array with " ^ Int. to_string length ^ " elements only."
37
+
25
38
let get_field_name json =
26
39
match json with
27
40
| `List _ -> " list"
@@ -40,8 +53,6 @@ let make_error (name : string) (json : Json.t) =
40
53
make_error_wrong_operation name itemName json
41
54
42
55
module Output = struct
43
- (* type t = (Json.Basic.t list, string) result *)
44
-
45
56
let ok x = Ok x
46
57
let return x = Ok [ x ]
47
58
let empty = Ok []
@@ -68,36 +79,36 @@ module Operators = struct
68
79
| `Bool false | `Null -> Output. return (`Bool true )
69
80
| _ -> Output. return (`Bool false )
70
81
71
- let rec merge_map ~(eq_f : 'a -> 'a -> 'b ) ~(f : 'a -> 'b )
82
+ let rec merge_map ~(eq : 'a -> 'a -> 'b ) ~(f : 'a -> 'b )
72
83
(cmp : 'a -> 'a -> int ) (l1 : 'a list ) (l2 : 'a list ) : 'b list =
73
84
match (l1, l2) with
74
85
| [] , l2 -> List. map f l2
75
86
| l1 , [] -> List. map f l1
76
87
| h1 :: t1 , h2 :: t2 ->
77
88
let r = cmp h1 h2 in
78
- if r = 0 then eq_f h1 h2 :: merge_map ~eq_f ~f cmp t1 t2
79
- else if r < 0 then f h1 :: merge_map ~eq_f ~f cmp t1 l2
80
- else f h2 :: merge_map ~eq_f ~f cmp l1 t2
89
+ if r = 0 then eq h1 h2 :: merge_map ~eq ~f cmp t1 t2
90
+ else if r < 0 then f h1 :: merge_map ~eq ~f cmp t1 l2
91
+ else f h2 :: merge_map ~eq ~f cmp l1 t2
81
92
82
93
let rec add str (left : Json.t ) (right : Json.t ) :
83
94
(Json. t list , string ) result =
84
95
match (left, right) with
85
96
| `Float l , `Float r -> Output. return (`Float (l +. r))
86
- | `Int l , `Float r -> Output. return (`Float (float_of_int l +. r))
87
- | `Float l , `Int r -> Output. return (`Float (l +. float_of_int r))
97
+ | `Int l , `Float r -> Output. return (`Float (Int. to_float l +. r))
98
+ | `Float l , `Int r -> Output. return (`Float (l +. Int. to_float r))
88
99
| `Int l , `Int r ->
89
- Output. return (`Float (float_of_int l +. float_of_int r))
90
- | `Null , `Int r | `Int r , `Null -> Output. return (`Float (float_of_int r))
100
+ Output. return (`Float (Int. to_float l +. Int. to_float r))
101
+ | `Null , `Int r | `Int r , `Null -> Output. return (`Float (Int. to_float r))
91
102
| `Null , `Float r | `Float r , `Null -> Output. return (`Float r)
92
103
| `String l , `String r -> Output. return (`String (l ^ r))
93
104
| `Null , `String r | `String r , `Null -> Output. return (`String r)
94
105
| `Assoc l , `Assoc r -> (
95
106
let cmp (key1 , _ ) (key2 , _ ) = String. compare key1 key2 in
96
- let eq_f (key , v1 ) (_ , v2 ) =
107
+ let eq (key , v1 ) (_ , v2 ) =
97
108
let * result = add str v1 v2 in
98
109
Output. return (key, result)
99
110
in
100
- match merge_map ~f: Output. return ~eq_f cmp l r |> Output. collect with
111
+ match merge_map ~f: Output. return ~eq cmp l r |> Output. collect with
101
112
| Ok l -> Output. return (`Assoc l)
102
113
| Error e -> Error e)
103
114
| `Null , `Assoc r | `Assoc r , `Null -> Output. return (`Assoc r)
@@ -109,19 +120,19 @@ module Operators = struct
109
120
let apply_op str fn (left : Json.t ) (right : Json.t ) =
110
121
match (left, right) with
111
122
| `Float l , `Float r -> Output. return (`Float (fn l r))
112
- | `Int l , `Float r -> Output. return (`Float (fn (float_of_int l) r))
113
- | `Float l , `Int r -> Output. return (`Float (fn l (float_of_int r)))
123
+ | `Int l , `Float r -> Output. return (`Float (fn (Int. to_float l) r))
124
+ | `Float l , `Int r -> Output. return (`Float (fn l (Int. to_float r)))
114
125
| `Int l , `Int r ->
115
- Output. return (`Float (fn (float_of_int l) (float_of_int r)))
126
+ Output. return (`Float (fn (Int. to_float l) (Int. to_float r)))
116
127
| _ -> Error (make_error str left)
117
128
118
129
let compare str fn (left : Json.t ) (right : Json.t ) =
119
130
match (left, right) with
120
131
| `Float l , `Float r -> Output. return (`Bool (fn l r))
121
- | `Int l , `Float r -> Output. return (`Bool (fn (float_of_int l) r))
122
- | `Float l , `Int r -> Output. return (`Bool (fn l (float_of_int r)))
132
+ | `Int l , `Float r -> Output. return (`Bool (fn (Int. to_float l) r))
133
+ | `Float l , `Int r -> Output. return (`Bool (fn l (Int. to_float r)))
123
134
| `Int l , `Int r ->
124
- Output. return (`Bool (fn (float_of_int l) (float_of_int r)))
135
+ Output. return (`Bool (fn (Int. to_float l) (Int. to_float r)))
125
136
| _ -> Error (make_error str right)
126
137
127
138
let condition (str : string ) (fn : bool -> bool -> bool ) (left : Json.t )
@@ -138,6 +149,8 @@ module Operators = struct
138
149
let or_ = condition " or" ( || )
139
150
let eq l r = Output. return (`Bool (l = r))
140
151
let notEq l r = Output. return (`Bool (l <> r))
152
+
153
+ (* Since + is used to concat strings, objects, lists, we don't use apply_op *)
141
154
let add = add " +"
142
155
let sub = apply_op " -" (fun l r -> l -. r)
143
156
let mult = apply_op " *" (fun l r -> l *. r)
@@ -181,7 +194,7 @@ let in_ (json : Json.t) expr =
181
194
| _ -> Error (make_error " in" json))
182
195
| _ -> Error (make_error " in" json)
183
196
184
- let range ?step from upto : int list =
197
+ let range ?step from upto =
185
198
let rec range ?(step = 1 ) start stop =
186
199
if step = 0 then []
187
200
else if (step > 0 && start > = stop) || (step < 0 && start < = stop) then []
@@ -217,27 +230,14 @@ let join expr json =
217
230
218
231
let length (json : Json.t ) =
219
232
match json with
220
- | `List list -> Output. return (`Int (list |> List. length))
233
+ | `List list -> Output. return (`Int (List. length list ))
221
234
| _ -> Error (make_error " length" json)
222
235
223
236
let filter (fn : Json.t -> bool ) (json : Json.t ) =
224
237
match json with
225
238
| `List list -> Ok (`List (List. filter fn list ))
226
239
| _ -> Error (make_error " filter" json)
227
240
228
- let make_empty_list_error op =
229
- let open Console in
230
- " Trying to "
231
- ^ Formatting. single_quotes (Chalk. bold op)
232
- ^ " on an empty array."
233
-
234
- let make_acessing_to_missing_item access_index length =
235
- let open Console in
236
- " Trying to read "
237
- ^ Formatting. single_quotes
238
- (" [" ^ Chalk. bold (string_of_int access_index) ^ " ]" )
239
- ^ " from an array with " ^ string_of_int length ^ " elements only."
240
-
241
241
let head (json : Json.t ) =
242
242
match json with
243
243
| `List list -> (
@@ -279,7 +279,7 @@ let index (value : int) (json : Json.t) =
279
279
| `List list when List. length list > value ->
280
280
Output. return (Json. index value json)
281
281
| `List _ -> Output. return `Null
282
- | _ -> Error (make_error (" [" ^ string_of_int value ^ " ]" ) json)
282
+ | _ -> Error (make_error (" [" ^ Int. to_string value ^ " ]" ) json)
283
283
284
284
let slice (start : int option ) (finish : int option ) (json : Json.t ) =
285
285
let start =
@@ -319,7 +319,7 @@ let slice (start : int option) (finish : int option) (json : Json.t) =
319
319
| _ ->
320
320
Error
321
321
(make_error
322
- (" [" ^ string_of_int start ^ " :" ^ string_of_int finish ^ " ]" )
322
+ (" [" ^ Int. to_string start ^ " :" ^ Int. to_string finish ^ " ]" )
323
323
json)
324
324
325
325
let iterator (json : Json.t ) =
@@ -337,7 +337,7 @@ let rec compile expression json : (Json.t list, string) result =
337
337
| Key key -> member key json
338
338
| Optional expr -> (
339
339
match compile expr json with
340
- | Ok values -> Ok values (* If successful, return the values *)
340
+ | Ok values -> Output. ok values
341
341
| Error _ -> Output. return `Null )
342
342
| Index idx -> index idx json
343
343
| Iterator -> iterator json
@@ -348,25 +348,24 @@ let rec compile expression json : (Json.t list, string) result =
348
348
| Not -> Operators. not json
349
349
| Map expr -> map expr json
350
350
| Operation (left , op , right ) -> (
351
- let open Operators in
352
351
match op with
353
- | Add -> operation left right add json
354
- | Sub -> operation left right sub json
355
- | Mult -> operation left right mult json
356
- | Div -> operation left right div json
357
- | Gt -> operation left right gt json
358
- | Ge -> operation left right gte json
359
- | St -> operation left right lt json
360
- | Se -> operation left right lte json
361
- | Eq -> operation left right eq json
362
- | Neq -> operation left right notEq json
363
- | And -> operation left right and_ json
364
- | Or -> operation left right or_ json)
352
+ | Add -> operation left right Operators. add json
353
+ | Sub -> operation left right Operators. sub json
354
+ | Mult -> operation left right Operators. mult json
355
+ | Div -> operation left right Operators. div json
356
+ | Gt -> operation left right Operators. gt json
357
+ | Ge -> operation left right Operators. gte json
358
+ | St -> operation left right Operators. lt json
359
+ | Se -> operation left right Operators. lte json
360
+ | Eq -> operation left right Operators. eq json
361
+ | Neq -> operation left right Operators. notEq json
362
+ | And -> operation left right Operators. and_ json
363
+ | Or -> operation left right Operators. or_ json)
365
364
| Literal literal -> (
366
365
match literal with
367
366
| Bool b -> Output. return (`Bool b)
368
- | Number float -> Output. return (`Float float )
369
- | String string -> Output. return (`String string )
367
+ | Number f -> Output. return (`Float f )
368
+ | String s -> Output. return (`String s )
370
369
| Null -> Output. return `Null )
371
370
| Pipe (left , right ) ->
372
371
let * left = compile left json in
@@ -378,18 +377,19 @@ let rec compile expression json : (Json.t list, string) result =
378
377
match b with true -> Output. return json | false -> Output. empty)
379
378
| _ -> Error (make_error " select" res))
380
379
| List exprs ->
381
- Output. collect (List. map (fun expr -> compile expr json) exprs)
380
+ List. map (fun expr -> compile expr json) exprs
381
+ |> Output. collect
382
382
|> Result. map (fun x -> [ `List x ])
383
- | Comma (leftR , rightR ) ->
384
- Result. bind (compile leftR json) (fun left ->
385
- Result. bind (compile rightR json) (fun right -> Ok (left @ right)))
383
+ | Comma (left_expr , right_expr ) ->
384
+ Result. bind (compile left_expr json) (fun left ->
385
+ Result. bind (compile right_expr json) (fun right -> Ok (left @ right)))
386
386
| Object [] -> Output. return (`Assoc [] )
387
- | Object list -> handle_objects list json
388
- | Has e -> (
389
- match e with
390
- | Literal ((String _ | Number _ ) as e ) -> has json e
391
- | _ -> Error (show_expression e ^ " is not allowed" ))
392
- | In e -> in_ json e
387
+ | Object list -> objects list json
388
+ | Has expr -> (
389
+ match expr with
390
+ | Literal ((String _ | Number _ ) as expr ) -> has json expr
391
+ | _ -> Error (show_expression expr ^ " is not allowed" ))
392
+ | In expr -> in_ json expr
393
393
| Range (from , upto , step ) ->
394
394
Output. ok (range ?step from upto |> List. map (fun i -> `Int i))
395
395
| Reverse -> (
@@ -398,21 +398,7 @@ let rec compile expression json : (Json.t list, string) result =
398
398
| _ -> Error (make_error " reverse" json))
399
399
| Split expr -> split expr json
400
400
| Join expr -> join expr json
401
- | Fun Abs -> (
402
- match json with
403
- | `Int n -> Output. return (`Int (if n < 0 then - n else n))
404
- | `Float j -> Output. return (`Float (if j < 0. then -. j else j))
405
- | _ -> Error (make_error " reverse" json))
406
- | Fun Add -> (
407
- match json with
408
- | `List [] -> Output. return `Null
409
- | `List l ->
410
- List. fold_left
411
- (fun acc el ->
412
- let * acc = acc in
413
- Operators. add acc el)
414
- (Output. return `Null ) l
415
- | _ -> Error (make_error " add" json))
401
+ | Fun builtin -> builtin_functions builtin json
416
402
| IfThenElse (cond , if_branch , else_branch ) -> (
417
403
let * cond = compile cond json in
418
404
match cond with
@@ -421,20 +407,20 @@ let rec compile expression json : (Json.t list, string) result =
421
407
| json -> Error (make_error " if condition should be a bool" json))
422
408
| _ -> Error (show_expression expression ^ " is not implemented" )
423
409
424
- and operation leftR rightR op json =
425
- let * left = compile leftR json in
426
- let * right = compile rightR json in
410
+ and operation left_expr right_expr op json =
411
+ let * left = compile left_expr json in
412
+ let * right = compile right_expr json in
427
413
op left right
428
414
429
415
and map (expr : expression ) (json : Json.t ) =
430
416
match json with
431
417
| `List list when List. length list > 0 ->
432
418
Output. collect (List. map (compile expr) list )
433
419
|> Result. map (fun x -> [ `List x ])
434
- | `List _list -> Error (make_empty_list_error " map" )
420
+ | `List _ -> Error (make_empty_list_error " map" )
435
421
| _ -> Error (make_error " map" json)
436
422
437
- and handle_objects list json =
423
+ and objects list json =
438
424
List. map
439
425
(fun (left_expr , right_expr ) ->
440
426
match (left_expr, right_expr) with
@@ -465,3 +451,21 @@ and handle_objects list json =
465
451
| _ -> Error (show_expression left_expr ^ " is not implemented" ))
466
452
list
467
453
|> Output. collect
454
+
455
+ and builtin_functions builtin json =
456
+ match builtin with
457
+ | Abs -> (
458
+ match json with
459
+ | `Int n -> Output. return (`Int (if n < 0 then - n else n))
460
+ | `Float j -> Output. return (`Float (if j < 0. then -. j else j))
461
+ | _ -> Error (make_error " reverse" json))
462
+ | Add -> (
463
+ match json with
464
+ | `List [] -> Output. return `Null
465
+ | `List l ->
466
+ List. fold_left
467
+ (fun acc el ->
468
+ let * acc = acc in
469
+ Operators. add acc el)
470
+ (Output. return `Null ) l
471
+ | _ -> Error (make_error " add" json))
0 commit comments