@@ -26,13 +26,11 @@ endfunction
2626"
2727" private api
2828"
29- " work around: '[^\r\n]*' doesn't work well in old-vim, but "[^\r\n]*" works well
30- let s: skip_pattern = ' \C^\%(\_s\+\|' . " #[^\r \n ]*" . ' \)'
31- let s: table_name_pattern = ' \%([^ [:tab:]#.[\]=]\+\)'
32- let s: table_key_pattern = s: table_name_pattern
29+ let s: skip_pattern = ' \C^\%(\%(\s\|\r\?\n\)\+\|#[^\r\n]*\)'
30+ let s: bare_key_pattern = ' \%([A-Za-z0-9_-]\+\)'
3331
3432function ! s: _skip (input ) abort
35- while s: _match (a: input , ' \%(\_s \|#\)' )
33+ while s: _match (a: input , ' \%(\s\|\r\?\n \|#\)' )
3634 let a: input .p = matchend (a: input .text, s: skip_pattern , a: input .p )
3735 endwhile
3836endfunction
@@ -68,14 +66,10 @@ function! s:_eof(input) abort
6866endfunction
6967
7068function ! s: _error (input ) abort
71- let buf = []
72- let offset = 0
73- while (a: input .p + offset) < a: input .length && a: input .text[a: input .p + offset] !~# " [\r \n ]"
74- let buf += [a: input .text[a: input .p + offset]]
75- let offset += 1
76- endwhile
69+ let s = matchstr (a: input .text, s: regex_prefix . ' .\{-}\ze\%(\r\?\n\|$\)' , a: input .p )
70+ let s = substitute (s , ' \r' , ' \\r' , ' g' )
7771
78- throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , join ( buf , ' ' ) )
72+ throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , s )
7973endfunction
8074
8175function ! s: _parse (input ) abort
@@ -84,25 +78,16 @@ function! s:_parse(input) abort
8478 call s: _skip (a: input )
8579 while ! s: _eof (a: input )
8680 if s: _match (a: input , ' [^ [:tab:]#.[\]]' )
87- let key = s: _key (a: input )
81+ let keys = s: _keys (a: input, ' = ' )
8882 call s: _equals (a: input )
8983 let value = s: _value (a: input )
90-
91- call s: _put_dict (data, key , value)
92-
93- unlet value
84+ call s: _put_dict (data, keys , value)
9485 elseif s: _match (a: input , ' \[\[' )
95- let [key , value] = s: _array_of_tables (a: input )
96-
97- call s: _put_array (data, key , value)
98-
99- unlet value
86+ let [keys , value] = s: _array_of_tables (a: input )
87+ call s: _put_array (data, keys , value)
10088 elseif s: _match (a: input , ' \[' )
101- let [key , value] = s: _table (a: input )
102-
103- call s: _put_dict (data, key , value)
104-
105- unlet value
89+ let [keys , value] = s: _table (a: input )
90+ call s: _put_dict (data, keys , value)
10691 else
10792 call s: _error (a: input )
10893 endif
@@ -112,14 +97,26 @@ function! s:_parse(input) abort
11297 return data
11398endfunction
11499
115- function ! s: _key (input ) abort
116- let s = s: _consume (a: input , s: table_key_pattern )
117- return s
100+ function ! s: _keys (input , end ) abort
101+ let keys = []
102+ while ! s: _eof (a: input ) && ! s: _match (a: input , a: end )
103+ call s: _skip (a: input )
104+ if s: _match (a: input , ' "' )
105+ let key = s: _basic_string (a: input )
106+ else
107+ let key = s: _consume (a: input , s: bare_key_pattern )
108+ endif
109+ let keys += [key ]
110+ call s: _consume (a: input , ' \.\?' )
111+ endwhile
112+ if empty (keys )
113+ return s: _error (a: input )
114+ endif
115+ return keys
118116endfunction
119117
120118function ! s: _equals (input ) abort
121- call s: _consume (a: input , ' =' )
122- return ' ='
119+ return s: _consume (a: input , ' =' )
123120endfunction
124121
125122function ! s: _value (input ) abort
@@ -135,11 +132,13 @@ function! s:_value(input) abort
135132 return s: _literal (a: input )
136133 elseif s: _match (a: input , ' \[' )
137134 return s: _array (a: input )
135+ elseif s: _match (a: input , ' {' )
136+ return s: _inline_table (a: input )
138137 elseif s: _match (a: input , ' \%(true\|false\)' )
139138 return s: _boolean (a: input )
140139 elseif s: _match (a: input , ' \d\{4}-' )
141140 return s: _datetime (a: input )
142- elseif s: _match (a: input , ' [+-]\?\%( \d\+\.\d\|\ d\+\%(\.\d\+\)\?[eE]\)' )
141+ elseif s: _match (a: input , ' [+-]\?\d\+\%(_ \d\+\)*\%(\ .\d\+\%(_\ d\+\)*\|\ %(\.\d\+\%(_\d\+\)* \)\?[eE]\)' )
143142 return s: _float (a: input )
144143 else
145144 return s: _integer (a: input )
@@ -158,8 +157,8 @@ endfunction
158157function ! s: _multiline_basic_string (input ) abort
159158 let s = s: _consume (a: input , ' "\{3}\%(\\.\|\_.\)\{-}"\{3}' )
160159 let s = s [3 : -4 ]
161- let s = substitute (s , " ^ \n " , ' ' , ' ' )
162- let s = substitute (s , ' \\' . " \n " . ' \_s *' , ' ' , ' g' )
160+ let s = substitute (s , ' ^\r\?\n ' , ' ' , ' ' )
161+ let s = substitute (s , ' \\\%(\s\|\r\?\n\) *' , ' ' , ' g' )
163162 return s: _unescape (s )
164163endfunction
165164
@@ -171,36 +170,25 @@ endfunction
171170function ! s: _multiline_literal (input ) abort
172171 let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {3}" )
173172 let s = s [3 : -4 ]
174- let s = substitute (s , " ^ \n " , ' ' , ' ' )
173+ let s = substitute (s , ' ^\r\?\n ' , ' ' , ' ' )
175174 return s
176175endfunction
177176
178177"
179178" Integer
180179"
181180function ! s: _integer (input ) abort
182- let s = s: _consume (a: input , ' [+-]\?\d\+' )
181+ let s = s: _consume (a: input , ' [+-]\?\d\+\%(_\d\+\)*' )
182+ let s = substitute (s , ' _' , ' ' , ' g' )
183183 return str2nr (s )
184184endfunction
185185
186186"
187187" Float
188188"
189189function ! s: _float (input ) abort
190- if s: _match (a: input , ' [+-]\?[0-9.]\+[eE][+-]\?\d\+' )
191- return s: _exponent (a: input )
192- else
193- return s: _fractional (a: input )
194- endif
195- endfunction
196-
197- function ! s: _fractional (input ) abort
198- let s = s: _consume (a: input , ' [+-]\?[0-9.]\+' )
199- return str2float (s )
200- endfunction
201-
202- function ! s: _exponent (input ) abort
203- let s = s: _consume (a: input , ' [+-]\?[0-9.]\+[eE][+-]\?\d\+' )
190+ let s = s: _consume (a: input , ' [+-]\?[0-9._]\+\%([eE][+-]\?\d\+\%(_\d\+\)*\)\?' )
191+ let s = substitute (s , ' _' , ' ' , ' g' )
204192 return str2float (s )
205193endfunction
206194
@@ -241,40 +229,54 @@ endfunction
241229"
242230function ! s: _table (input ) abort
243231 let tbl = {}
244- let name = s: _consume (a: input , ' \[\s*' . s: table_name_pattern . ' \%(\s*\.\s*' . s: table_name_pattern . ' \)*\s*\]' )
245- let name = name[1 : -2 ]
232+ call s: _consume (a: input , ' \[' )
233+ let name = s: _keys (a: input , ' \]' )
234+ call s: _consume (a: input , ' \]' )
246235 call s: _skip (a: input )
247236 " while !s:_eof(a:input) && !s:_match(a:input, '\[\{1,2}[a-zA-Z0-9.]\+\]\{1,2}')
248237 while ! s: _eof (a: input ) && ! s: _match (a: input , ' \[' )
249- let key = s: _key (a: input )
238+ let keys = s: _keys (a: input, ' = ' )
250239 call s: _equals (a: input )
251240 let value = s: _value (a: input )
252-
253- let tbl[key ] = value
254-
255- unlet value
241+ call s: _put_dict (tbl, keys , value)
256242 call s: _skip (a: input )
257243 endwhile
258244 return [name, tbl]
259245endfunction
260246
261247"
262- " Array of tables
248+ " Inline Table
249+ "
250+ function ! s: _inline_table (input ) abort
251+ let tbl = {}
252+ call s: _consume (a: input , ' {' )
253+ while ! s: _eof (a: input ) && ! s: _match (a: input , ' }' )
254+ let keys = s: _keys (a: input , ' =' )
255+ call s: _equals (a: input )
256+ let value = s: _value (a: input )
257+ call s: _put_dict (tbl, keys , value)
258+ call s: _consume (a: input , ' ,\?' )
259+ call s: _skip (a: input )
260+ endwhile
261+ call s: _consume (a: input , ' }' )
262+ return tbl
263+ endfunction
264+
265+ "
266+ " Array of Tables
263267"
264268function ! s: _array_of_tables (input ) abort
265269 let tbl = {}
266- let name = s: _consume (a: input , ' \[\[\s*' . s: table_name_pattern . ' \%(\s*\.\s*' . s: table_name_pattern . ' \)*\s*\]\]' )
267- let name = name[2 : -3 ]
270+ call s: _consume (a: input , ' \[\[' )
271+ let name = s: _keys (a: input , ' \]\]' )
272+ call s: _consume (a: input , ' \]\]' )
268273 call s: _skip (a: input )
269274 " while !s:_eof(a:input) && !s:_match(a:input, '\[\{1,2}[a-zA-Z0-9.]\+\]\{1,2}')
270275 while ! s: _eof (a: input ) && ! s: _match (a: input , ' \[' )
271- let key = s: _key (a: input )
276+ let keys = s: _keys (a: input, ' = ' )
272277 call s: _equals (a: input )
273278 let value = s: _value (a: input )
274-
275- let tbl[key ] = value
276-
277- unlet value
279+ call s: _put_dict (tbl, keys , value)
278280 call s: _skip (a: input )
279281 endwhile
280282 return [name, [tbl]]
@@ -288,7 +290,6 @@ function! s:_unescape(text) abort
288290 let text = substitute (text, ' \\n' , " \n " , ' g' )
289291 let text = substitute (text, ' \\f' , " \f " , ' g' )
290292 let text = substitute (text, ' \\r' , " \r " , ' g' )
291- let text = substitute (text, ' \\/' , ' /' , ' g' )
292293 let text = substitute (text, ' \\\\' , ' \' , ' g' )
293294 let text = substitute (text, ' \C\\u\(\x\{4}\)' , ' \=s:_nr2char("0x" . submatch(1))' , ' g' )
294295 let text = substitute (text, ' \C\\U\(\x\{8}\)' , ' \=s:_nr2char("0x" . submatch(1))' , ' g' )
@@ -299,39 +300,35 @@ function! s:_nr2char(nr) abort
299300 return iconv (nr2char (a: nr ), &encoding , ' utf8' )
300301endfunction
301302
302- function ! s: _put_dict (dict , key , value) abort
303- let keys = split (a: key , ' \.' )
304-
303+ function ! s: _put_dict (dict , keys , value) abort
305304 let ref = a: dict
306- for key in keys [ : -2 ]
307- if has_key (ref, key ) && type (ref[key ]) == type ({})
305+ for key in a: keys [: -2 ]
306+ if has_key (ref, key ) && type (ref[key ]) == v: t_dict
308307 let ref = ref[key ]
309- elseif has_key (ref, key ) && type (ref[key ]) == type ([])
308+ elseif has_key (ref, key ) && type (ref[key ]) == v: t_list
310309 let ref = ref[key ][-1 ]
311310 else
312311 let ref[key ] = {}
313312 let ref = ref[key ]
314313 endif
315314 endfor
316315
317- let ref[keys [-1 ]] = a: value
316+ let ref[a: keys [-1 ]] = a: value
318317endfunction
319318
320- function ! s: _put_array (dict , key , value) abort
321- let keys = split (a: key , ' \.' )
322-
319+ function ! s: _put_array (dict , keys , value) abort
323320 let ref = a: dict
324- for key in keys [ : -2 ]
321+ for key in a: keys [: -2 ]
325322 let ref[key ] = get (ref, key , {})
326323
327- if type (ref[key ]) == type ([])
324+ if type (ref[key ]) == v: t_list
328325 let ref = ref[key ][-1 ]
329326 else
330327 let ref = ref[key ]
331328 endif
332329 endfor
333330
334- let ref[keys [-1 ]] = get (ref, keys [-1 ], []) + a: value
331+ let ref[a: keys [-1 ]] = get (ref, a: keys [-1 ], []) + a: value
335332endfunction
336333
337334let &cpo = s: save_cpo
0 commit comments