@@ -19,8 +19,8 @@ function! s:parse_file(filename) abort
1919 endif
2020
2121 let text = join (readfile (a: filename ), " \n " )
22- " fileencoding is always utf8
23- return s: parse (iconv (text, ' utf8 ' , &encoding ))
22+ " fileencoding is always UTF-8
23+ return s: parse (iconv (text, ' utf-8 ' , &encoding ))
2424endfunction
2525
2626"
@@ -69,7 +69,7 @@ function! s:_error(input) abort
6969 let s = matchstr (a: input .text, s: regex_prefix . ' .\{-}\ze\%(\r\?\n\|$\)' , a: input .p )
7070 let s = substitute (s , ' \r' , ' \\r' , ' g' )
7171
72- throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , s )
72+ throw printf (" vital: Text.TOML: Illegal TOML format at `%s'." , s )
7373endfunction
7474
7575function ! s: _parse (input ) abort
@@ -103,6 +103,8 @@ function! s:_keys(input, end) abort
103103 call s: _skip (a: input )
104104 if s: _match (a: input , ' "' )
105105 let key = s: _basic_string (a: input )
106+ elseif s: _match (a: input , " '" )
107+ let key = s: _literal (a: input )
106108 else
107109 let key = s: _consume (a: input , s: bare_key_pattern )
108110 endif
@@ -124,11 +126,11 @@ function! s:_value(input) abort
124126
125127 if s: _match (a: input , ' "\{3}' )
126128 return s: _multiline_basic_string (a: input )
127- elseif s: _match (a: input , ' "\{1} ' )
129+ elseif s: _match (a: input , ' "' )
128130 return s: _basic_string (a: input )
129131 elseif s: _match (a: input , " '\\ {3}" )
130132 return s: _multiline_literal (a: input )
131- elseif s: _match (a: input , " '\\ {1} " )
133+ elseif s: _match (a: input , " '" )
132134 return s: _literal (a: input )
133135 elseif s: _match (a: input , ' \[' )
134136 return s: _array (a: input )
@@ -138,8 +140,12 @@ function! s:_value(input) abort
138140 return s: _boolean (a: input )
139141 elseif s: _match (a: input , ' \d\{4}-' )
140142 return s: _datetime (a: input )
143+ elseif s: _match (a: input , ' \d\{2}:' )
144+ return s: _local_time (a: input )
141145 elseif s: _match (a: input , ' [+-]\?\d\+\%(_\d\+\)*\%(\.\d\+\%(_\d\+\)*\|\%(\.\d\+\%(_\d\+\)*\)\?[eE]\)' )
142146 return s: _float (a: input )
147+ elseif s: _match (a: input , ' [+-]\?\%(inf\|nan\)' )
148+ return s: _special_float (a: input )
143149 else
144150 return s: _integer (a: input )
145151 endif
@@ -155,7 +161,7 @@ function! s:_basic_string(input) abort
155161endfunction
156162
157163function ! s: _multiline_basic_string (input ) abort
158- let s = s: _consume (a: input , ' "\{3}\%(\\.\|\_.\)\{-}"\{3}' )
164+ let s = s: _consume (a: input , ' "\{3}\%(\\.\|\_.\)\{-}"\{,2}"\{ 3}' )
159165 let s = s [3 : -4 ]
160166 let s = substitute (s , ' ^\r\?\n' , ' ' , ' ' )
161167 let s = substitute (s , ' \\\%(\s\|\r\?\n\)*' , ' ' , ' g' )
@@ -168,7 +174,7 @@ function! s:_literal(input) abort
168174endfunction
169175
170176function ! s: _multiline_literal (input ) abort
171- let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {3}" )
177+ let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {,2}' \\ { 3}" )
172178 let s = s [3 : -4 ]
173179 let s = substitute (s , ' ^\r\?\n' , ' ' , ' ' )
174180 return s
@@ -178,9 +184,22 @@ endfunction
178184" Integer
179185"
180186function ! s: _integer (input ) abort
181- let s = s: _consume (a: input , ' [+-]\?\d\+\%(_\d\+\)*' )
187+ if s: _match (a: input , ' 0b' )
188+ let s = s: _consume (a: input , ' 0b[01]\+\%(_[01]\+\)*' )
189+ let base = 2
190+ elseif s: _match (a: input , ' 0o' )
191+ let s = s: _consume (a: input , ' 0o[0-7]\+\%(_[0-7]\+\)*' )
192+ let s = s [2 :]
193+ let base = 8
194+ elseif s: _match (a: input , ' 0x' )
195+ let s = s: _consume (a: input , ' 0x[A-Fa-f0-9]\+\%(_[A-Fa-f0-9]\+\)*' )
196+ let base = 16
197+ else
198+ let s = s: _consume (a: input , ' [+-]\?\d\+\%(_\d\+\)*' )
199+ let base = 10
200+ endif
182201 let s = substitute (s , ' _' , ' ' , ' g' )
183- return str2nr (s )
202+ return str2nr (s , base )
184203endfunction
185204
186205"
@@ -192,35 +211,48 @@ function! s:_float(input) abort
192211 return str2float (s )
193212endfunction
194213
214+ function ! s: _special_float (input ) abort
215+ let s = s: _consume (a: input , ' [+-]\?\%(inf\|nan\)' )
216+ return str2float (s )
217+ endfunction
218+
195219"
196220" Boolean
197221"
198222function ! s: _boolean (input ) abort
199223 let s = s: _consume (a: input , ' \%(true\|false\)' )
200- return ( s == # ' true' ) ? 1 : 0
224+ return s == # ' true'
201225endfunction
202226
203227"
204- " Datetime
228+ " Offset Date-Time
229+ " Local Date-Time
230+ " Local Date
205231"
206232function ! s: _datetime (input ) abort
207- let s = s: _consume (a: input , ' \d\{4}-\d\{2}-\d\{2}T\d\{2}:\d\{2}:\d\{2}\%(Z\|-\?\d\{2}:\d\{2}\|\.\d\+-\d\{2}:\d\{2}\)' )
208- return s
233+ return s: _consume (a: input , ' \d\{4}-\d\{2}-\d\{2}\%([T ]\d\{2}:\d\{2}:\d\{2}\%(\.\d\+\)\?\%(Z\|[+-]\d\{2}:\d\{2}\)\?\)\?' )
234+ endfunction
235+
236+ "
237+ " Local Time
238+ "
239+ function ! s: _local_time (input ) abort
240+ return s: _consume (a: input , ' \d\{2}:\d\{2}:\d\{2}\%(\.\d\+\)\?' )
209241endfunction
210242
211243"
212244" Array
213245"
214246function ! s: _array (input ) abort
215247 let ary = []
216- let _ = s: _consume (a: input , ' \[' )
248+ call s: _consume (a: input , ' \[' )
217249 call s: _skip (a: input )
218250 while ! s: _eof (a: input ) && ! s: _match (a: input , ' \]' )
219251 let ary += [s: _value (a: input )]
220252 call s: _consume (a: input , ' ,\?' )
221253 call s: _skip (a: input )
222254 endwhile
223- let _ = s: _consume (a: input , ' \]' )
255+ call s: _consume (a: input , ' \]' )
224256 return ary
225257endfunction
226258
@@ -297,7 +329,7 @@ function! s:_unescape(text) abort
297329endfunction
298330
299331function ! s: _nr2char (nr) abort
300- return iconv (nr2char (a: nr ), &encoding , ' utf8 ' )
332+ return iconv (nr2char (a: nr ), &encoding , ' utf-8 ' )
301333endfunction
302334
303335function ! s: _put_dict (dict , keys , value) abort
@@ -313,14 +345,17 @@ function! s:_put_dict(dict, keys, value) abort
313345 endif
314346 endfor
315347
316- let ref[a: keys [-1 ]] = a: value
348+ if has_key (ref, a: keys [-1 ]) && type (a: value ) == v: t_dict
349+ call extend (ref[a: keys [-1 ]], a: value )
350+ else
351+ let ref[a: keys [-1 ]] = a: value
352+ endif
317353endfunction
318354
319355function ! s: _put_array (dict , keys , value) abort
320356 let ref = a: dict
321357 for key in a: keys [: -2 ]
322358 let ref[key ] = get (ref, key , {})
323-
324359 if type (ref[key ]) == v: t_list
325360 let ref = ref[key ][-1 ]
326361 else
0 commit comments