Files
delta/src/value.ml
T

58 lines
2.0 KiB
OCaml

type t =
| VUnit
| VInt of int
| VBool of bool
| VString of string
| VTuple of t list
| VRecord of string * (string * t) list
| VCollection of t Delta_runtime.Pure_map.t
let rec to_string value =
match value with
| VUnit -> "unit"
| VInt number -> string_of_int number
| VBool true -> "true"
| VBool false -> "false"
| VString text -> Printf.sprintf "%S" text
| VTuple items -> "(tuple " ^ Util.join " " (List.map to_string items) ^ ")"
| VRecord (name, fields) ->
Printf.sprintf "(record:%s %s)" name
(Util.join " " (List.map (fun (label, field) -> "(" ^ label ^ " " ^ to_string field ^ ")") fields))
| VCollection map ->
let entries =
List.map (fun (key, item) -> Printf.sprintf "(%d %s)" key (to_string item))
(Delta_runtime.Pure_map.bindings map)
in
"(collection " ^ Util.join " " entries ^ ")"
let collection_of_list entries =
List.fold_left
(fun map (key, value) ->
if Delta_runtime.Pure_map.mem key map then
Diagnostic.error Location.none "duplicate key %d in the initial input" key;
Delta_runtime.Pure_map.add key value map)
Delta_runtime.Pure_map.empty entries
let collection_to_list map = Delta_runtime.Pure_map.bindings map
let rec equal (left : t) (right : t) =
match (left, right) with
| VUnit, VUnit -> true
| VInt a, VInt b -> a = b
| VBool a, VBool b -> a = b
| VString a, VString b -> a = b
| VTuple a, VTuple b -> List.length a = List.length b && List.for_all2 equal a b
| VRecord (name_a, fields_a), VRecord (name_b, fields_b) ->
name_a = name_b
&& List.length fields_a = List.length fields_b
&& List.for_all2 (fun (label_a, value_a) (label_b, value_b) -> label_a = label_b && equal value_a value_b) fields_a fields_b
| VCollection map_a, VCollection map_b -> Delta_runtime.Pure_map.equal equal map_a map_b
| _ -> false
let field record label =
match record with
| VRecord (_, fields) -> Util.assoc_opt label fields
| _ -> None
let is_collection = function VCollection _ -> true | _ -> false