added support for namespaces to Antimony reader
[antimony.git] / src / antimony_reader.voo
blob78e85a6353a9f17403e8e56343b96f6ee3011f19
1 # Functions for reading Antimony code from streams.
3 section data
4 export _antimony_reader_eof
6 align
7 _antimony_reader_eof: word -1
10 section functions
11 export read_antimony
12 import allocate_bytes array blob_builder blob_builder_append_byte \
13     blob_builder_to_blob block dynarray dynarray_add dynarray_to_array \
14     get_namespace make_blob namespace_intern memcpy read_byte_from_stream \
15     J2anamespaceJ2a
17 align
18 read_antimony:
19 function stream
20     let lookahead auto-words 1
21     set @lookahead call read_byte_from_stream stream
22     let expr call read_expr stream lookahead
23     return expr
24 end function
26 align
27 read_blob:
28 function stream lookahead
29     let capacity 256
30     let bytes auto-bytes capacity
31     let i 0
32     let b 0
33 read_blob_loop:
34     set b call read_byte_from_stream stream
35     ifeq b 34
36         goto read_blob_done
37     end if
38     set-byte bytes i b
39     set i add i 1
40     goto read_blob_loop
41 read_blob_done:
42     set @lookahead call read_byte_from_stream stream
43     let heap_bytes call allocate_bytes i
44     call memcpy heap_bytes bytes i
45     return call make_blob heap_bytes i
46 end function
48 align
49 read_blob_escape:
50 function stream
51     let c call read_byte_from_stream stream
52     return c
53 end function
55 align
56 read_block:
57 function stream lookahead
58     let exprs call dynarray 0 0
59     let expr 0
60     set @lookahead call read_byte_from_stream stream
61 read_block_loop:
62     ifeq @lookahead 125         # }
63         set @lookahead call read_byte_from_stream stream
64         goto read_block_done
65     end
66     ifeq @lookahead -1
67         goto read_block_done
68     end if
69     set expr call read_expr stream lookahead
70     ifne expr -1
71         call dynarray_add exprs expr
72     end if
73     goto read_block_loop
74 read_block_done:
75     let arr call dynarray_to_array exprs
76     return call block arr
77 end function
79 align
80 read_expr:
81 function stream lookahead
82     let params call dynarray 0 0
83     let item 0
84     let i 0
85     goto read_expr_loop
87 read_expr_read_byte:
88     set @lookahead call read_byte_from_stream stream
89 read_expr_loop:
90     ifeq @lookahead 32          # space
91         goto read_expr_read_byte
92     end if
93     ifeq @lookahead 10          # newline
94         ifgt i 0
95             goto read_expr_done
96         else
97             goto read_expr_read_byte
98         end if
99     end if
100     ifeq @lookahead 41          # )
101         goto read_expr_done
102     end if
103     ifeq @lookahead 125         # }
104         goto read_expr_done
105     end if
106     ifeq @lookahead 9           # tab
107         goto read_expr_read_byte
108     end if
109     set item call read_item stream lookahead
110     ifeq item _antimony_reader_eof
111         goto read_expr_done
112     end if
113     call dynarray_add params item
114     set i add i 1
115     goto read_expr_loop
117 read_expr_done:
118     ifeq i 0
119         return -1
120     end if
121     return call dynarray_to_array params
122 end function
124 align
125 read_item:
126 function stream lookahead
127     let c @lookahead
128     ifge c 48                   # 0
129         ifle c 57               # 9
130             return call read_number stream lookahead
131         end if
132     end if
133     ifeq c 45                   # -
134         return call read_number stream lookahead
135     end if
136     ifeq c 34                   # "
137         return call read_blob stream lookahead
138     end if
139     ifeq c 40                   # (
140         block
141             set @lookahead call read_byte_from_stream stream
142             let expr call read_expr stream lookahead
143             ifeq @lookahead 41
144                 set @lookahead call read_byte_from_stream stream
145             end if
146             return expr
147         end block
148     end if
149     ifeq c 123                  # {
150         return call read_block stream lookahead
151     end if
152     ifeq c -1
153         return _antimony_reader_eof
154     end if
155     return call read_symbol stream lookahead
156 end function
158 align
159 read_number:
160 function stream lookahead
161     let c @lookahead
162     let value 0
163     ifeq c 45                   # -
164         set c call read_number_aux stream 0 lookahead
165         set value sub 0 c
166     else
167         set value sub c 48      # 0
168         set value call read_number_aux stream value lookahead
169     end if
170     set value shl value 2
171     set value or value 1
172     return value
173 end function
175 align
176 read_number_aux:
177 function stream value lookahead
178     let c 0
179 read_number_aux_loop:
180     set c call read_byte_from_stream stream
181     iflt c 48                   # 0
182         goto read_number_aux_done
183     else ifgt c 57              # 9
184         goto read_number_aux_done
185     end if
186     set value mul value 10
187     set c sub c 48              # 0
188     set value add value c
189     goto read_number_aux_loop
190 read_number_aux_done:
191     set @lookahead c
192     return value
193 end function
195 align
196 read_symbol:
197 function stream lookahead
198     let builder call blob_builder
199     let c @lookahead
200     let namespace @J2anamespaceJ2a
201 read_symbol_loop:
202     iflt c 33                   # !
203         goto read_symbol_done
204     end if
205     ifeq c 41                   # )
206         goto read_symbol_done
207     end if
208     ifeq c 125                  # }
209         goto read_symbol_done
210     end if
211     ifeq c 40                   # (
212         goto read_symbol_done
213     end if
214     ifeq c 46                   # .
215         block
216             let name call blob_builder_to_blob builder
217             let sym call namespace_intern namespace name
218             set namespace call get_namespace sym
219             set builder call blob_builder
220             set c call read_byte_from_stream stream
221         end block
222         goto read_symbol_loop
223     end if
224     ifeq c 123                  # {
225         goto read_symbol_done
226     end if
227     call blob_builder_append_byte builder c
228     set c call read_byte_from_stream stream
229     goto read_symbol_loop
230 read_symbol_done:
231     set @lookahead c
232     let name call blob_builder_to_blob builder
233     return call namespace_intern namespace name
234 end function