@@ -19,8 +19,8 @@ function! s:parse_file(filename) abort
19
19
endif
20
20
21
21
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 ))
24
24
endfunction
25
25
26
26
"
@@ -69,7 +69,7 @@ function! s:_error(input) abort
69
69
let s = matchstr (a: input .text, s: regex_prefix . ' .\{-}\ze\%(\r\?\n\|$\)' , a: input .p )
70
70
let s = substitute (s , ' \r' , ' \\r' , ' g' )
71
71
72
- throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , s )
72
+ throw printf (" vital: Text.TOML: Illegal TOML format at `%s'." , s )
73
73
endfunction
74
74
75
75
function ! s: _parse (input ) abort
@@ -103,6 +103,8 @@ function! s:_keys(input, end) abort
103
103
call s: _skip (a: input )
104
104
if s: _match (a: input , ' "' )
105
105
let key = s: _basic_string (a: input )
106
+ elseif s: _match (a: input , " '" )
107
+ let key = s: _literal (a: input )
106
108
else
107
109
let key = s: _consume (a: input , s: bare_key_pattern )
108
110
endif
@@ -124,11 +126,11 @@ function! s:_value(input) abort
124
126
125
127
if s: _match (a: input , ' "\{3}' )
126
128
return s: _multiline_basic_string (a: input )
127
- elseif s: _match (a: input , ' "\{1} ' )
129
+ elseif s: _match (a: input , ' "' )
128
130
return s: _basic_string (a: input )
129
131
elseif s: _match (a: input , " '\\ {3}" )
130
132
return s: _multiline_literal (a: input )
131
- elseif s: _match (a: input , " '\\ {1} " )
133
+ elseif s: _match (a: input , " '" )
132
134
return s: _literal (a: input )
133
135
elseif s: _match (a: input , ' \[' )
134
136
return s: _array (a: input )
@@ -138,8 +140,12 @@ function! s:_value(input) abort
138
140
return s: _boolean (a: input )
139
141
elseif s: _match (a: input , ' \d\{4}-' )
140
142
return s: _datetime (a: input )
143
+ elseif s: _match (a: input , ' \d\{2}:' )
144
+ return s: _local_time (a: input )
141
145
elseif s: _match (a: input , ' [+-]\?\d\+\%(_\d\+\)*\%(\.\d\+\%(_\d\+\)*\|\%(\.\d\+\%(_\d\+\)*\)\?[eE]\)' )
142
146
return s: _float (a: input )
147
+ elseif s: _match (a: input , ' [+-]\?\%(inf\|nan\)' )
148
+ return s: _special_float (a: input )
143
149
else
144
150
return s: _integer (a: input )
145
151
endif
@@ -155,7 +161,7 @@ function! s:_basic_string(input) abort
155
161
endfunction
156
162
157
163
function ! 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}' )
159
165
let s = s [3 : -4 ]
160
166
let s = substitute (s , ' ^\r\?\n' , ' ' , ' ' )
161
167
let s = substitute (s , ' \\\%(\s\|\r\?\n\)*' , ' ' , ' g' )
@@ -168,7 +174,7 @@ function! s:_literal(input) abort
168
174
endfunction
169
175
170
176
function ! s: _multiline_literal (input ) abort
171
- let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {3}" )
177
+ let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {,2}' \\ { 3}" )
172
178
let s = s [3 : -4 ]
173
179
let s = substitute (s , ' ^\r\?\n' , ' ' , ' ' )
174
180
return s
@@ -178,9 +184,22 @@ endfunction
178
184
" Integer
179
185
"
180
186
function ! 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
182
201
let s = substitute (s , ' _' , ' ' , ' g' )
183
- return str2nr (s )
202
+ return str2nr (s , base )
184
203
endfunction
185
204
186
205
"
@@ -192,35 +211,48 @@ function! s:_float(input) abort
192
211
return str2float (s )
193
212
endfunction
194
213
214
+ function ! s: _special_float (input ) abort
215
+ let s = s: _consume (a: input , ' [+-]\?\%(inf\|nan\)' )
216
+ return str2float (s )
217
+ endfunction
218
+
195
219
"
196
220
" Boolean
197
221
"
198
222
function ! s: _boolean (input ) abort
199
223
let s = s: _consume (a: input , ' \%(true\|false\)' )
200
- return ( s == # ' true' ) ? 1 : 0
224
+ return s == # ' true'
201
225
endfunction
202
226
203
227
"
204
- " Datetime
228
+ " Offset Date-Time
229
+ " Local Date-Time
230
+ " Local Date
205
231
"
206
232
function ! 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\+\)\?' )
209
241
endfunction
210
242
211
243
"
212
244
" Array
213
245
"
214
246
function ! s: _array (input ) abort
215
247
let ary = []
216
- let _ = s: _consume (a: input , ' \[' )
248
+ call s: _consume (a: input , ' \[' )
217
249
call s: _skip (a: input )
218
250
while ! s: _eof (a: input ) && ! s: _match (a: input , ' \]' )
219
251
let ary += [s: _value (a: input )]
220
252
call s: _consume (a: input , ' ,\?' )
221
253
call s: _skip (a: input )
222
254
endwhile
223
- let _ = s: _consume (a: input , ' \]' )
255
+ call s: _consume (a: input , ' \]' )
224
256
return ary
225
257
endfunction
226
258
@@ -297,7 +329,7 @@ function! s:_unescape(text) abort
297
329
endfunction
298
330
299
331
function ! s: _nr2char (nr) abort
300
- return iconv (nr2char (a: nr ), &encoding , ' utf8 ' )
332
+ return iconv (nr2char (a: nr ), &encoding , ' utf-8 ' )
301
333
endfunction
302
334
303
335
function ! s: _put_dict (dict , keys , value) abort
@@ -313,14 +345,17 @@ function! s:_put_dict(dict, keys, value) abort
313
345
endif
314
346
endfor
315
347
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
317
353
endfunction
318
354
319
355
function ! s: _put_array (dict , keys , value) abort
320
356
let ref = a: dict
321
357
for key in a: keys [: -2 ]
322
358
let ref[key ] = get (ref, key , {})
323
-
324
359
if type (ref[key ]) == v: t_list
325
360
let ref = ref[key ][-1 ]
326
361
else
0 commit comments