1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-11 13:55:55 +03:00
mal/impls/sml/types.sml

49 lines
2.0 KiB
Standard ML
Raw Normal View History

2021-03-25 20:59:11 +03:00
datatype mal_type = NIL
| SYMBOL of string
| BOOL of bool
| INT of LargeInt.int
2021-03-30 18:33:57 +03:00
| STRING of string
2021-04-03 00:37:25 +03:00
| KEYWORD of string
2021-04-06 20:50:25 +03:00
| LIST of (mal_type list * mal_meta)
| VECTOR of (mal_type list * mal_meta)
| MAP of ((mal_type * mal_type) list * mal_meta)
2021-03-31 14:20:14 +03:00
| ATOM of mal_type ref
2021-04-06 20:50:25 +03:00
| FN of (mal_type list -> mal_type) * mal_meta
2021-04-05 17:29:10 +03:00
| MACRO of mal_type list -> mal_type
2021-03-27 18:49:04 +03:00
2021-04-06 20:50:25 +03:00
and mal_meta = META of mal_type
| NO_META
2021-04-01 19:12:41 +03:00
and mal_ns = NS of (string * mal_type) list ref
and mal_env = ENV of mal_ns
| INNER of mal_ns * mal_env
2021-03-27 15:13:42 +03:00
fun truthy (BOOL false) = false
| truthy NIL = false
| truthy _ = true
2021-03-27 16:17:50 +03:00
2021-04-06 20:50:25 +03:00
fun malEq ( NIL, NIL) = true
| malEq ( SYMBOL a, SYMBOL b) = a = b
| malEq ( BOOL a, BOOL b) = a = b
| malEq ( INT a, INT b) = a = b
| malEq ( STRING a, STRING b) = a = b
| malEq ( KEYWORD a, KEYWORD b) = a = b
| malEq ( LIST (a,_), LIST (b,_)) = ListPair.allEq malEq (a, b)
| malEq (VECTOR (a,_), VECTOR (b,_)) = ListPair.allEq malEq (a, b)
| malEq ( LIST (a,_), VECTOR (b,_)) = ListPair.allEq malEq (a, b)
| malEq (VECTOR (a,_), LIST (b,_)) = ListPair.allEq malEq (a, b)
| malEq ( MAP (a,_), MAP (b,_)) = mapEq a b
2021-04-07 12:46:12 +03:00
| malEq _ = false
2021-04-03 00:37:25 +03:00
and mapEq a b =
a |> List.map (fn (k,va) => (va, malGet b k)) |> List.all (fn (va,SOME vb) => malEq (va, vb) | _ => false) andalso
b |> List.map (fn (k,vb) => (vb, malGet a k)) |> List.all (fn (vb,SOME va) => malEq (vb, va) | _ => false)
and malGet m k = m |> List.find (fn (k',_) => malEq (k, k')) |> Option.map #2
2021-04-05 21:51:54 +03:00
and malAssoc m k v = (k, v) :: (malDissoc m k)
and malDissoc m k = m |> List.filter (not o (fn (k', _) => malEq (k, k')))
2021-04-06 20:50:25 +03:00
2021-04-07 12:46:12 +03:00
fun malList xs = LIST (xs, NO_META)
fun malVector xs = VECTOR (xs, NO_META)
fun malMap kvps = MAP (kvps, NO_META)