diff options
| author | Chouser <chouser@n01se.net> | 2015-01-26 19:16:23 -0500 |
|---|---|---|
| committer | Chouser <chouser@n01se.net> | 2015-01-30 12:54:43 -0500 |
| commit | e64878d0af10d7e391e2070ddd02756042bec7b9 (patch) | |
| tree | d3ff809f3969a8964cb6b9ba2ee995dd47ea2620 /ocaml/reader.ml | |
| parent | a878f3bb778513c0cc8bbeb1a8ff61664e43de29 (diff) | |
| download | mal-e64878d0af10d7e391e2070ddd02756042bec7b9.tar.gz mal-e64878d0af10d7e391e2070ddd02756042bec7b9.zip | |
Ocaml: add meta, with-meta, and ^ reader support
Diffstat (limited to 'ocaml/reader.ml')
| -rw-r--r-- | ocaml/reader.ml | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/ocaml/reader.ml b/ocaml/reader.ml index 6827597..a6c2366 100644 --- a/ocaml/reader.ml +++ b/ocaml/reader.ml @@ -32,6 +32,14 @@ let read_atom token = | ':' -> T.Keyword (Str.replace_first (Str.regexp "^:") "" token) | _ -> Types.symbol token +let with_meta obj meta = + match obj with + | T.List { T.value = value } -> T.List { T.value = value; T.meta = meta }; + | T.Map { T.value = value } -> T.Map { T.value = value; T.meta = meta }; + | T.Vector { T.value = value } -> T.Vector { T.value = value; T.meta = meta }; + | T.Symbol { T.value = value } -> T.Symbol { T.value = value; T.meta = meta }; + | _ -> raise (Invalid_argument "metadata not supported on this type") + let rec read_list list_reader = match list_reader.tokens with | [] -> output_string stderr "expected ')', got EOF\n"; @@ -58,16 +66,20 @@ and read_form all_tokens = | "~" -> read_quote "unquote" tokens | "~@" -> read_quote "splice-unquote" tokens | "@" -> read_quote "deref" tokens - | "(" -> let list_reader = - read_list {list_form = []; tokens = tokens} in + | "^" -> + let meta = read_form tokens in + let value = read_form meta.tokens in + {form = with_meta value.form meta.form; tokens = value.tokens} + | "(" -> + let list_reader = read_list {list_form = []; tokens = tokens} in {form = Types.list list_reader.list_form; tokens = list_reader.tokens} - | "{" -> let list_reader = - read_list {list_form = []; tokens = tokens} in + | "{" -> + let list_reader = read_list {list_form = []; tokens = tokens} in {form = Types.list_into_map Types.MalMap.empty list_reader.list_form; tokens = list_reader.tokens} - | "[" -> let list_reader = - read_list {list_form = []; tokens = tokens} in + | "[" -> + let list_reader = read_list {list_form = []; tokens = tokens} in {form = Types.vector list_reader.list_form; tokens = list_reader.tokens} | _ -> {form = read_atom token; tokens = tokens} |
