Skip to content

Commit 8f3b264

Browse files
committed
Details
1 parent 6173d66 commit 8f3b264

File tree

1 file changed

+85
-81
lines changed

1 file changed

+85
-81
lines changed

source/Compiler.ml

Lines changed: 85 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ let make_error_wrong_operation op member_kind (value : Json.t) =
2222
^ ":" ^ Formatting.enter 1
2323
^ Chalk.gray (Json.to_string value ~colorize:false ~summarize:true)
2424

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+
2538
let get_field_name json =
2639
match json with
2740
| `List _ -> "list"
@@ -40,8 +53,6 @@ let make_error (name : string) (json : Json.t) =
4053
make_error_wrong_operation name itemName json
4154

4255
module Output = struct
43-
(* type t = (Json.Basic.t list, string) result *)
44-
4556
let ok x = Ok x
4657
let return x = Ok [ x ]
4758
let empty = Ok []
@@ -68,36 +79,36 @@ module Operators = struct
6879
| `Bool false | `Null -> Output.return (`Bool true)
6980
| _ -> Output.return (`Bool false)
7081

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)
7283
(cmp : 'a -> 'a -> int) (l1 : 'a list) (l2 : 'a list) : 'b list =
7384
match (l1, l2) with
7485
| [], l2 -> List.map f l2
7586
| l1, [] -> List.map f l1
7687
| h1 :: t1, h2 :: t2 ->
7788
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
8192

8293
let rec add str (left : Json.t) (right : Json.t) :
8394
(Json.t list, string) result =
8495
match (left, right) with
8596
| `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))
8899
| `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))
91102
| `Null, `Float r | `Float r, `Null -> Output.return (`Float r)
92103
| `String l, `String r -> Output.return (`String (l ^ r))
93104
| `Null, `String r | `String r, `Null -> Output.return (`String r)
94105
| `Assoc l, `Assoc r -> (
95106
let cmp (key1, _) (key2, _) = String.compare key1 key2 in
96-
let eq_f (key, v1) (_, v2) =
107+
let eq (key, v1) (_, v2) =
97108
let* result = add str v1 v2 in
98109
Output.return (key, result)
99110
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
101112
| Ok l -> Output.return (`Assoc l)
102113
| Error e -> Error e)
103114
| `Null, `Assoc r | `Assoc r, `Null -> Output.return (`Assoc r)
@@ -109,19 +120,19 @@ module Operators = struct
109120
let apply_op str fn (left : Json.t) (right : Json.t) =
110121
match (left, right) with
111122
| `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)))
114125
| `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)))
116127
| _ -> Error (make_error str left)
117128

118129
let compare str fn (left : Json.t) (right : Json.t) =
119130
match (left, right) with
120131
| `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)))
123134
| `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)))
125136
| _ -> Error (make_error str right)
126137

127138
let condition (str : string) (fn : bool -> bool -> bool) (left : Json.t)
@@ -138,6 +149,8 @@ module Operators = struct
138149
let or_ = condition "or" ( || )
139150
let eq l r = Output.return (`Bool (l = r))
140151
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 *)
141154
let add = add "+"
142155
let sub = apply_op "-" (fun l r -> l -. r)
143156
let mult = apply_op "*" (fun l r -> l *. r)
@@ -181,7 +194,7 @@ let in_ (json : Json.t) expr =
181194
| _ -> Error (make_error "in" json))
182195
| _ -> Error (make_error "in" json)
183196

184-
let range ?step from upto : int list =
197+
let range ?step from upto =
185198
let rec range ?(step = 1) start stop =
186199
if step = 0 then []
187200
else if (step > 0 && start >= stop) || (step < 0 && start <= stop) then []
@@ -217,27 +230,14 @@ let join expr json =
217230

218231
let length (json : Json.t) =
219232
match json with
220-
| `List list -> Output.return (`Int (list |> List.length))
233+
| `List list -> Output.return (`Int (List.length list))
221234
| _ -> Error (make_error "length" json)
222235

223236
let filter (fn : Json.t -> bool) (json : Json.t) =
224237
match json with
225238
| `List list -> Ok (`List (List.filter fn list))
226239
| _ -> Error (make_error "filter" json)
227240

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-
241241
let head (json : Json.t) =
242242
match json with
243243
| `List list -> (
@@ -279,7 +279,7 @@ let index (value : int) (json : Json.t) =
279279
| `List list when List.length list > value ->
280280
Output.return (Json.index value json)
281281
| `List _ -> Output.return `Null
282-
| _ -> Error (make_error ("[" ^ string_of_int value ^ "]") json)
282+
| _ -> Error (make_error ("[" ^ Int.to_string value ^ "]") json)
283283

284284
let slice (start : int option) (finish : int option) (json : Json.t) =
285285
let start =
@@ -319,7 +319,7 @@ let slice (start : int option) (finish : int option) (json : Json.t) =
319319
| _ ->
320320
Error
321321
(make_error
322-
("[" ^ string_of_int start ^ ":" ^ string_of_int finish ^ "]")
322+
("[" ^ Int.to_string start ^ ":" ^ Int.to_string finish ^ "]")
323323
json)
324324

325325
let iterator (json : Json.t) =
@@ -337,7 +337,7 @@ let rec compile expression json : (Json.t list, string) result =
337337
| Key key -> member key json
338338
| Optional expr -> (
339339
match compile expr json with
340-
| Ok values -> Ok values (* If successful, return the values *)
340+
| Ok values -> Output.ok values
341341
| Error _ -> Output.return `Null)
342342
| Index idx -> index idx json
343343
| Iterator -> iterator json
@@ -348,25 +348,24 @@ let rec compile expression json : (Json.t list, string) result =
348348
| Not -> Operators.not json
349349
| Map expr -> map expr json
350350
| Operation (left, op, right) -> (
351-
let open Operators in
352351
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)
365364
| Literal literal -> (
366365
match literal with
367366
| 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)
370369
| Null -> Output.return `Null)
371370
| Pipe (left, right) ->
372371
let* left = compile left json in
@@ -378,18 +377,19 @@ let rec compile expression json : (Json.t list, string) result =
378377
match b with true -> Output.return json | false -> Output.empty)
379378
| _ -> Error (make_error "select" res))
380379
| 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
382382
|> 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)))
386386
| 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
393393
| Range (from, upto, step) ->
394394
Output.ok (range ?step from upto |> List.map (fun i -> `Int i))
395395
| Reverse -> (
@@ -398,21 +398,7 @@ let rec compile expression json : (Json.t list, string) result =
398398
| _ -> Error (make_error "reverse" json))
399399
| Split expr -> split expr json
400400
| 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
416402
| IfThenElse (cond, if_branch, else_branch) -> (
417403
let* cond = compile cond json in
418404
match cond with
@@ -421,20 +407,20 @@ let rec compile expression json : (Json.t list, string) result =
421407
| json -> Error (make_error "if condition should be a bool" json))
422408
| _ -> Error (show_expression expression ^ " is not implemented")
423409

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
427413
op left right
428414

429415
and map (expr : expression) (json : Json.t) =
430416
match json with
431417
| `List list when List.length list > 0 ->
432418
Output.collect (List.map (compile expr) list)
433419
|> Result.map (fun x -> [ `List x ])
434-
| `List _list -> Error (make_empty_list_error "map")
420+
| `List _ -> Error (make_empty_list_error "map")
435421
| _ -> Error (make_error "map" json)
436422

437-
and handle_objects list json =
423+
and objects list json =
438424
List.map
439425
(fun (left_expr, right_expr) ->
440426
match (left_expr, right_expr) with
@@ -465,3 +451,21 @@ and handle_objects list json =
465451
| _ -> Error (show_expression left_expr ^ " is not implemented"))
466452
list
467453
|> 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

Comments
 (0)