5 let chan = open_in filename
in
6 let b = Buffer.create
27 in
7 Buffer.add_channel
b chan (in_channel_length
chan) ;
12 List.map
(function | Str.Delim x
-> x
| Str.Text x
-> "impossible!")
13 (List.filter
(function | Str.Delim x
-> true | Str.Text x
-> false)
14 (Str.full_split re str
))
18 "" (List.map
(function | Str.Delim x
-> f x
| Str.Text x
-> x
)
19 (Str.full_split re str
))
21 let token_re = (Str.regexp
"~@\\|[][{}()'`~^@]\\|\"\\(\\\\.\\|[^\"]\\)*\"\\|;.*\\|[^][ \n{}('\"`,;)]*")
24 form
: Types.mal_type
;
29 list_form
: Types.mal_type list
;
36 | "true" -> T.Bool
true
37 | "false" -> T.Bool
false
40 | '
0'
..'
9'
-> T.Int
(int_of_string token
)
41 | '
-'
-> (match String.length token
with
42 | 1 -> Types.symbol token
43 | _
-> (match token
.[1] with
44 | '
0'
..'
9'
-> T.Int
(int_of_string token
)
45 | _
-> Types.symbol token
))
46 | '
"' -> T.String (gsub (Str.regexp "\\\\.")
49 | x -> String.sub x 1 1)
50 (String.sub token 1 ((String.length token) - 2)))
51 | ':' -> T.Keyword (Str.replace_first (Str.regexp "^
:") "" token)
52 | _ -> Types.symbol token
54 let with_meta obj meta =
56 | T.List { T.value = v }
57 -> T.List { T.value = v; T.meta = meta }; | T.Map { T.value = v }
58 -> T.Map { T.value = v; T.meta = meta }; | T.Vector { T.value = v }
59 -> T.Vector { T.value = v; T.meta = meta }; | T.Symbol { T.value = v }
60 -> T.Symbol { T.value = v; T.meta = meta }; | T.Fn { T.value = v }
61 -> T.Fn { T.value = v; T.meta = meta };
62 | _ -> raise (Invalid_argument "metadata not supported on this
type")
64 let rec read_list eol list_reader =
65 match list_reader.tokens with
66 | [] -> output_string stderr ("expected '
" ^ eol ^ "'
, got EOF
\n");
70 if Str.string_match (Str.regexp eol) token 0 then
71 {list_form = list_reader.list_form; tokens = tokens}
72 else if token.[0] = ';' then
73 read_list eol { list_form = list_reader.list_form;
76 let reader = read_form list_reader.tokens in
77 read_list eol {list_form = list_reader.list_form @ [reader.form];
78 tokens = reader.tokens}
79 and read_quote sym tokens =
80 let reader = read_form tokens in
81 {form = Types.list [ Types.symbol sym; reader.form ];
82 tokens = reader.tokens}
83 and read_form all_tokens =
85 | [] -> raise End_of_file;
88 | "'
" -> read_quote "quote
" tokens
89 | "`
" -> read_quote "quasiquote
" tokens
90 | "~
" -> read_quote "unquote
" tokens
91 | "~
@" -> read_quote "splice
-unquote
" tokens
92 | "@" -> read_quote "deref
" tokens
94 let meta = read_form tokens in
95 let value = read_form meta.tokens in
96 {(*form = with_meta value.form meta.form;*)
97 form = Types.list [Types.symbol "with-meta"; value.form; meta.form];
98 tokens = value.tokens}
100 let list_reader = read_list ")" {list_form = []; tokens = tokens} in
101 {form = Types.list list_reader.list_form;
102 tokens = list_reader.tokens}
104 let list_reader = read_list "}" {list_form = []; tokens = tokens} in
105 {form = Types.list_into_map Types.MalMap.empty list_reader.list_form;
106 tokens = list_reader.tokens}
108 let list_reader = read_list "]" {list_form = []; tokens = tokens} in
109 {form = Types.vector list_reader.list_form;
110 tokens = list_reader.tokens}
111 | _ -> if token.[0] = ';'
112 then read_form tokens
113 else {form = read_atom token; tokens = tokens}
115 let read_str str = (read_form (List.filter ((<>) "") (find_re token_re str))).form