1 # Functions for reading Antimony code from streams.
4 export _antimony_reader_eof
6 var _antimony_reader_eof = -1
11 import eq ge gt le lt ne true false
12 import allocate_bytes array array_length array_nth array_t \
13 blob_builder blob_builder_append_byte \
14 blob_builder_to_blob block dynarray dynarray_add dynarray_to_array \
15 get_namespace make_blob make_comment namespace_intern \
16 read_byte_from_stream type_of *namespace*
17 import get_namespace_absolute
19 function read_antimony stream {
20 let lookahead auto-words 1
21 set @lookahead read_byte_from_stream stream
22 let expr read_stmt stream lookahead
26 function decode_escape b stream {
29 } else if (eq b 92) { # backslash
31 } else if (eq b 110) { # n
33 } else if (eq b 114) { # r
34 return 13 # carriage return
35 } else if (eq b 116) { # t
37 } else if (eq b 120) { # x
39 set b read_byte_from_stream stream
41 } else if (le b 58) { # 9
43 } else if (lt b 97) { # a
44 } else if (le b 102) { # f
48 set b read_byte_from_stream stream
50 } else if (le b 58) { # 9
51 set value or value (sub b 48)
52 } else if (lt b 97) { # a
53 } else if (le b 102) { # f
54 set value or value (sub b 87)
61 function read_blob stream lookahead {
62 let builder (blob_builder)
66 set b read_byte_from_stream stream
68 if (eq b 92) { # backslash
69 set b read_blob_escape stream
71 blob_builder_append_byte builder b
73 set @lookahead read_byte_from_stream stream
74 return (blob_builder_to_blob builder)
77 function read_blob_escape stream {
78 var b = read_byte_from_stream stream
79 return (decode_escape b stream)
82 function read_block stream lookahead {
83 let exprs dynarray 0 0
85 set @lookahead read_byte_from_stream stream
89 if (eq @lookahead 125) { # }
90 set @lookahead read_byte_from_stream stream
94 while (ne @lookahead -1)
95 set expr read_expr stream lookahead
97 dynarray_add exprs expr
100 let arr dynarray_to_array exprs
104 function read_comment stream lookahead {
105 var builder = (blob_builder)
106 blob_builder_append_byte builder 35 # #
109 while (eq @lookahead 35) # #
110 blob_builder_append_byte builder @lookahead
111 set @lookahead read_byte_from_stream stream
113 if (eq @lookahead 32) { # space
114 blob_builder_append_byte builder @lookahead
115 set @lookahead read_byte_from_stream stream
117 let marker blob_builder_to_blob builder
118 set builder (blob_builder)
121 while (ne @lookahead 10) # newline
122 while (ne @lookahead -1)
123 blob_builder_append_byte builder @lookahead
124 set @lookahead read_byte_from_stream stream
126 return (make_comment marker (blob_builder_to_blob builder))
129 function read_expr stream lookahead {
130 var params = dynarray 0 0
136 while (ne @lookahead 41) # )
137 while (ne @lookahead 125) # }
138 if (eq @lookahead 10) { # newline
142 set @lookahead read_byte_from_stream stream
144 } else if (eq @lookahead 9) { # tab
145 set @lookahead read_byte_from_stream stream
146 } else if (eq @lookahead 32) { # space
147 set @lookahead read_byte_from_stream stream
149 set item read_item stream lookahead
150 if (eq item _antimony_reader_eof) {
153 dynarray_add params item
163 return (dynarray_to_array params)
167 function read_item stream lookahead {
171 return (read_number stream lookahead)
175 return (read_number stream lookahead)
178 return (read_blob stream lookahead)
181 return (read_special stream lookahead)
184 set @lookahead read_byte_from_stream stream
185 let expr read_expr stream lookahead
186 if (eq @lookahead 41) { # )
187 set @lookahead read_byte_from_stream stream
191 if (eq c 92) { # backslash
192 set c read_byte_from_stream stream
193 if (eq c 10) { # newline
194 # Read until there is no more whitespace.
199 set c read_byte_from_stream stream
209 return (read_item stream lookahead)
211 let builder (blob_builder)
212 blob_builder_append_byte (decode_escape c stream)
213 set @lookahead read_byte_from_stream stream
214 return (read_symbol1 stream lookahead builder)
218 return (read_block stream lookahead)
221 return _antimony_reader_eof
224 return _antimony_reader_eof
226 return (read_symbol stream lookahead)
229 function read_number stream lookahead {
233 set c read_number_aux stream 0 lookahead
236 set value sub c 48 # 0
237 set value read_number_aux stream value lookahead
239 set value shl value 2
244 function read_number_aux stream value lookahead {
248 set c read_byte_from_stream stream
251 set value mul value 10
253 set value add value c
259 function read_special stream lookahead {
260 let c read_byte_from_stream stream
261 if (eq c 32) { # space
263 return (read_comment stream lookahead)
264 } else if (eq c 35) { # #
266 return (read_comment stream lookahead)
267 } else if (eq c 96) { # `
268 set @lookahead read_byte_from_stream stream
269 let expr read_item stream lookahead
270 let items auto-words 2
271 set-word items 0 (namespace_intern @*namespace* "quote")
272 set-word items 1 expr
273 return (array 2 items)
275 let bytes allocate_bytes 1
276 set-byte bytes 0 @lookahead
278 return (namespace_intern @*namespace* (make_blob bytes 1))
281 function read_stmt stream lookahead {
282 let result read_expr stream lookahead
283 if (eq (type_of result) array_t) {
284 if (eq (array_length result) 1) {
285 return (array_nth result 0)
291 function read_symbol stream lookahead {
292 let builder (blob_builder)
293 return (read_symbol1 stream lookahead builder)
296 function read_symbol1 stream lookahead builder {
298 let namespace @*namespace*
307 let name blob_builder_to_blob builder
308 let sym namespace_intern namespace name
309 set namespace get_namespace sym
310 set builder (blob_builder)
311 set c read_byte_from_stream stream
312 } else if (eq c 92) { # backlash
313 set c read_byte_from_stream stream
314 blob_builder_append_byte builder (decode_escape c stream)
315 set c read_byte_from_stream stream
317 blob_builder_append_byte builder c
318 set c read_byte_from_stream stream
322 let name blob_builder_to_blob builder
323 return (namespace_intern namespace name)