Source file value.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
(*---------------------------------------------------------------------------
  Copyright (c) 2026 The Raven authors. All rights reserved.
  SPDX-License-Identifier: ISC
  ---------------------------------------------------------------------------*)

type t =
  | Null
  | Bool of bool
  | Int of int
  | Float of float
  | String of string
  | Int_array of int array
  | Float_array of float array
  | Bool_array of bool array
  | List of t list
  | Dict of (string * t) list

(* Equality *)

let rec equal a b =
  match (a, b) with
  | Null, Null -> true
  | Bool a, Bool b -> Bool.equal a b
  | Int a, Int b -> Int.equal a b
  | Float a, Float b -> Float.equal a b
  | String a, String b -> String.equal a b
  | Int_array a, Int_array b -> a = b
  | Float_array a, Float_array b -> a = b
  | Bool_array a, Bool_array b -> a = b
  | List a, List b -> equal_list a b
  | Dict a, Dict b -> equal_dict a b
  | ( ( Null | Bool _ | Int _ | Float _ | String _ | Int_array _ | Float_array _
      | Bool_array _ | List _ | Dict _ ),
      _ ) ->
      false

and equal_list a b =
  match (a, b) with
  | [], [] -> true
  | x :: xs, y :: ys -> equal x y && equal_list xs ys
  | _ -> false

and equal_dict a b =
  match (a, b) with
  | [], [] -> true
  | (ka, va) :: rest_a, (kb, vb) :: rest_b ->
      String.equal ka kb && equal va vb && equal_dict rest_a rest_b
  | _ -> false

(* Formatting *)

let pp_array pp_elt ppf a =
  Format.fprintf ppf "[|";
  for i = 0 to Array.length a - 1 do
    if i > 0 then Format.fprintf ppf "; ";
    pp_elt ppf a.(i)
  done;
  Format.fprintf ppf "|]"

let rec pp ppf = function
  | Null -> Format.fprintf ppf "null"
  | Bool b -> Format.fprintf ppf "%b" b
  | Int i -> Format.fprintf ppf "%d" i
  | Float f -> Format.fprintf ppf "%g" f
  | String s -> Format.fprintf ppf "%S" s
  | Int_array a -> pp_array (fun ppf v -> Format.fprintf ppf "%d" v) ppf a
  | Float_array a -> pp_array (fun ppf v -> Format.fprintf ppf "%g" v) ppf a
  | Bool_array a -> pp_array (fun ppf v -> Format.fprintf ppf "%b" v) ppf a
  | List items ->
      Format.fprintf ppf "[";
      List.iteri
        (fun i v ->
          if i > 0 then Format.fprintf ppf "; ";
          pp ppf v)
        items;
      Format.fprintf ppf "]"
  | Dict fields ->
      Format.fprintf ppf "{";
      List.iteri
        (fun i (k, v) ->
          if i > 0 then Format.fprintf ppf "; ";
          Format.fprintf ppf "%s: %a" k pp v)
        fields;
      Format.fprintf ppf "}"

let to_string v = Format.asprintf "%a" pp v