mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 01:57:09 +03:00
a878f3bb77
T.Map is now a real OCaml binary-tree map, and supports arbitrary mal value types for both keys and values. Metadata support is provided in the data objects, but not yet in the printer, reader, or core library.
47 lines
1.2 KiB
OCaml
47 lines
1.2 KiB
OCaml
module rec Types
|
|
: sig
|
|
type 'a with_meta = { value : 'a; meta : t }
|
|
and t =
|
|
| List of t list with_meta
|
|
| Vector of t list with_meta
|
|
| Map of t MalMap.t with_meta
|
|
| Int of int
|
|
| Symbol of string with_meta
|
|
| Keyword of string
|
|
| Nil
|
|
| Bool of bool
|
|
| String of string
|
|
| Fn of (t list -> t)
|
|
end = Types
|
|
|
|
and MalValue
|
|
: sig
|
|
type t = Types.t
|
|
val compare : t -> t -> int
|
|
end
|
|
= struct
|
|
type t = Types.t
|
|
let compare = Pervasives.compare
|
|
end
|
|
|
|
and MalMap
|
|
: Map.S with type key = MalValue.t
|
|
= Map.Make(MalValue)
|
|
|
|
let to_bool x = match x with
|
|
| Types.Nil | Types.Bool false -> false
|
|
| _ -> true
|
|
|
|
type mal_type = MalValue.t
|
|
|
|
let list x = Types.List { Types.value = x; meta = Types.Nil }
|
|
let map x = Types.Map { Types.value = x; meta = Types.Nil }
|
|
let vector x = Types.Vector { Types.value = x; meta = Types.Nil }
|
|
let symbol x = Types.Symbol { Types.value = x; meta = Types.Nil }
|
|
|
|
let rec list_into_map target source =
|
|
match source with
|
|
| k :: v :: more -> list_into_map (MalMap.add k v target) more
|
|
| [] -> map target
|
|
| _ :: [] -> raise (Invalid_argument "Literal maps must contain an even number of forms")
|