functionalscript 0.0.525 → 0.0.526

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,38 +43,11 @@ module.exports = {
43
43
  const result = stringify(tokenizeString('ᄑ'))
44
44
  if (result !== '[{"kind":"error","message":"unexpected character"}]') { throw result }
45
45
  },
46
- () => {
47
- const result = stringify(tokenizeString('err'))
48
- if (result !== '[{"kind":"id","value":"err"}]') { throw result }
49
- },
50
- () => {
51
- const result = stringify(tokenizeString('{e}'))
52
- if (result !== '[{"kind":"{"},{"kind":"id","value":"e"},{"kind":"}"}]') { throw result }
53
- },
54
46
  () => {
55
47
  const result = stringify(tokenizeString('{ \t\n\r}'))
56
- if (result !== '[{"kind":"{"},{"kind":"}"}]') { throw result }
57
- },
58
- () => {
59
- const result = stringify(tokenizeString('true'))
60
- if (result !== '[{"kind":"true"}]') { throw result }
61
- },
62
- () => {
63
- const result = stringify(tokenizeString('tru'))
64
- if (result !== '[{"kind":"id","value":"tru"}]') { throw result }
65
- },
66
- () => {
67
- const result = stringify(tokenizeString('false'))
68
- if (result !== '[{"kind":"false"}]') { throw result }
69
- },
70
- () => {
71
- const result = stringify(tokenizeString('null'))
72
- if (result !== '[{"kind":"null"}]') { throw result }
73
- },
74
- () => {
75
- const result = stringify(tokenizeString('[null]'))
76
- if (result !== '[{"kind":"["},{"kind":"null"},{"kind":"]"}]') { throw result }
48
+ if (result !== '[{"kind":"{"},{"kind":"ws"},{"kind":"}"}]') { throw result }
77
49
  },
50
+
78
51
  () => {
79
52
  const result = stringify(tokenizeString('""'))
80
53
  if (result !== '[{"kind":"string","value":""}]') { throw result }
@@ -89,7 +62,7 @@ module.exports = {
89
62
  },
90
63
  () => {
91
64
  const result = stringify(tokenizeString('"value1" "value2"'))
92
- if (result !== '[{"kind":"string","value":"value1"},{"kind":"string","value":"value2"}]') { throw result }
65
+ if (result !== '[{"kind":"string","value":"value1"},{"kind":"ws"},{"kind":"string","value":"value2"}]') { throw result }
93
66
  },
94
67
  () => {
95
68
  const result = stringify(tokenizeString('"'))
@@ -157,15 +130,15 @@ module.exports = {
157
130
  },
158
131
  () => {
159
132
  const result = stringify(tokenizeString('1 2'))
160
- if (result !== '[{"bf":[1n,0],"kind":"number","value":"1"},{"bf":[2n,0],"kind":"number","value":"2"}]') { throw result }
133
+ if (result !== '[{"bf":[1n,0],"kind":"number","value":"1"},{"kind":"ws"},{"bf":[2n,0],"kind":"number","value":"2"}]') { throw result }
161
134
  },
162
135
  () => {
163
136
  const result = stringify(tokenizeString('0. 2'))
164
- if (result !== '[{"kind":"error","message":"invalid number"},{"bf":[2n,0],"kind":"number","value":"2"}]') { throw result }
137
+ if (result !== '[{"kind":"error","message":"invalid number"},{"kind":"ws"},{"bf":[2n,0],"kind":"number","value":"2"}]') { throw result }
165
138
  },
166
139
  () => {
167
140
  const result = stringify(tokenizeString('10-0'))
168
- if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
141
+ if (result !== '[{"bf":[10n,0],"kind":"number","value":"10"},{"kind":"-"},{"bf":[0n,0],"kind":"number","value":"0"}]') { throw result }
169
142
  },
170
143
  () => {
171
144
  const result = stringify(tokenizeString('9a:'))
@@ -173,19 +146,19 @@ module.exports = {
173
146
  },
174
147
  () => {
175
148
  const result = stringify(tokenizeString('-10'))
176
- if (result !== '[{"bf":[-10n,0],"kind":"number","value":"-10"}]') { throw result }
149
+ if (result !== '[{"kind":"-"},{"bf":[10n,0],"kind":"number","value":"10"}]') { throw result }
177
150
  },
178
151
  () => {
179
152
  const result = stringify(tokenizeString('-0'))
180
- if (result !== '[{"bf":[0n,0],"kind":"number","value":"-0"}]') { throw result }
153
+ if (result !== '[{"kind":"-"},{"bf":[0n,0],"kind":"number","value":"0"}]') { throw result }
181
154
  },
182
155
  () => {
183
156
  const result = stringify(tokenizeString('-00'))
184
- if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
157
+ if (result !== '[{"kind":"-"},{"kind":"error","message":"invalid number"}]') { throw result }
185
158
  },
186
159
  () => {
187
160
  const result = stringify(tokenizeString('-.123'))
188
- if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
161
+ if (result !== '[{"kind":"-"},{"kind":"."},{"bf":[123n,0],"kind":"number","value":"123"}]') { throw result }
189
162
  },
190
163
  () => {
191
164
  const result = stringify(tokenizeString('0.01'))
@@ -193,15 +166,15 @@ module.exports = {
193
166
  },
194
167
  () => {
195
168
  const result = stringify(tokenizeString('-0.9'))
196
- if (result !== '[{"bf":[-9n,-1],"kind":"number","value":"-0.9"}]') { throw result }
169
+ if (result !== '[{"kind":"-"},{"bf":[9n,-1],"kind":"number","value":"0.9"}]') { throw result }
197
170
  },
198
171
  () => {
199
172
  const result = stringify(tokenizeString('-0.'))
200
- if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
173
+ if (result !== '[{"kind":"-"},{"kind":"error","message":"invalid number"}]') { throw result }
201
174
  },
202
175
  () => {
203
176
  const result = stringify(tokenizeString('-0.]'))
204
- if (result !== '[{"kind":"error","message":"invalid number"},{"kind":"]"}]') { throw result }
177
+ if (result !== '[{"kind":"-"},{"kind":"error","message":"invalid number"},{"kind":"]"}]') { throw result }
205
178
  },
206
179
  () => {
207
180
  const result = stringify(tokenizeString('12.34'))
@@ -209,11 +182,11 @@ module.exports = {
209
182
  },
210
183
  () => {
211
184
  const result = stringify(tokenizeString('-12.00'))
212
- if (result !== '[{"bf":[-1200n,-2],"kind":"number","value":"-12.00"}]') { throw result }
185
+ if (result !== '[{"kind":"-"},{"bf":[1200n,-2],"kind":"number","value":"12.00"}]') { throw result }
213
186
  },
214
187
  () => {
215
188
  const result = stringify(tokenizeString('-12.'))
216
- if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
189
+ if (result !== '[{"kind":"-"},{"kind":"error","message":"invalid number"}]') { throw result }
217
190
  },
218
191
  () => {
219
192
  const result = stringify(tokenizeString('12.]'))
@@ -237,11 +210,11 @@ module.exports = {
237
210
  },
238
211
  () => {
239
212
  const result = stringify(tokenizeString('-12e-0001'))
240
- if (result !== '[{"bf":[-12n,-1],"kind":"number","value":"-12e-0001"}]') { throw result }
213
+ if (result !== '[{"kind":"-"},{"bf":[12n,-1],"kind":"number","value":"12e-0001"}]') { throw result }
241
214
  },
242
215
  () => {
243
216
  const result = stringify(tokenizeString('-12.34e1234'))
244
- if (result !== '[{"bf":[-1234n,1232],"kind":"number","value":"-12.34e1234"}]') { throw result }
217
+ if (result !== '[{"kind":"-"},{"bf":[1234n,1232],"kind":"number","value":"12.34e1234"}]') { throw result }
245
218
  },
246
219
  () => {
247
220
  const result = stringify(tokenizeString('0e'))
@@ -261,11 +234,11 @@ module.exports = {
261
234
  },
262
235
  () => {
263
236
  const result = stringify(tokenizeString('123 _123'))
264
- if (result !== '[{"bf":[123n,0],"kind":"number","value":"123"},{"kind":"id","value":"_123"}]') { throw result }
237
+ if (result !== '[{"bf":[123n,0],"kind":"number","value":"123"},{"kind":"ws"},{"kind":"id","value":"_123"}]') { throw result }
265
238
  },
266
239
  () => {
267
240
  const result = stringify(tokenizeString('123 $123'))
268
- if (result !== '[{"bf":[123n,0],"kind":"number","value":"123"},{"kind":"id","value":"$123"}]') { throw result }
241
+ if (result !== '[{"bf":[123n,0],"kind":"number","value":"123"},{"kind":"ws"},{"kind":"id","value":"$123"}]') { throw result }
269
242
  },
270
243
  () => {
271
244
  const result = stringify(tokenizeString('123_123'))
@@ -285,7 +258,7 @@ module.exports = {
285
258
  },
286
259
  () => {
287
260
  const result = stringify(tokenizeString('[-1234567890n]'))
288
- if (result !== '[{"kind":"["},{"kind":"bigint","value":-1234567890n},{"kind":"]"}]') { throw result }
261
+ if (result !== '[{"kind":"["},{"kind":"-"},{"kind":"bigint","value":1234567890n},{"kind":"]"}]') { throw result }
289
262
  },
290
263
  () => {
291
264
  const result = stringify(tokenizeString('123.456n'))
@@ -318,37 +291,279 @@ module.exports = {
318
291
  const result = stringify(tokenizeString('-'))
319
292
  if (result !== '[{"kind":"-"}]') { throw result }
320
293
  },
294
+ () => {
295
+ const result = stringify(tokenizeString('1*2'))
296
+ if (result !== '[{"bf":[1n,0],"kind":"number","value":"1"},{"kind":"*"},{"bf":[2n,0],"kind":"number","value":"2"}]') { throw result }
297
+ },
298
+ () => {
299
+ const result = stringify(tokenizeString('( )'))
300
+ if (result !== '[{"kind":"("},{"kind":"ws"},{"kind":")"}]') { throw result }
301
+ },
321
302
  () => {
322
303
  const result = stringify(tokenizeString('== != === !== > >= < <='))
323
- if (result !== '[{"kind":"=="},{"kind":"!="},{"kind":"==="},{"kind":"!=="},{"kind":">"},{"kind":">="},{"kind":"<"},{"kind":"<="}]') { throw result }
304
+ if (result !== '[{"kind":"=="},{"kind":"ws"},{"kind":"!="},{"kind":"ws"},{"kind":"==="},{"kind":"ws"},{"kind":"!=="},{"kind":"ws"},{"kind":">"},{"kind":"ws"},{"kind":">="},{"kind":"ws"},{"kind":"<"},{"kind":"ws"},{"kind":"<="}]') { throw result }
324
305
  },
325
306
  () => {
326
307
  const result = stringify(tokenizeString('+ - * / % ++ -- **'))
327
- if (result !== '[{"kind":"+"},{"kind":"-"},{"kind":"*"},{"kind":"/"},{"kind":"%"},{"kind":"++"},{"kind":"--"},{"kind":"**"}]') { throw result }
308
+ if (result !== '[{"kind":"+"},{"kind":"ws"},{"kind":"-"},{"kind":"ws"},{"kind":"*"},{"kind":"ws"},{"kind":"/"},{"kind":"ws"},{"kind":"%"},{"kind":"ws"},{"kind":"++"},{"kind":"ws"},{"kind":"--"},{"kind":"ws"},{"kind":"**"}]') { throw result }
328
309
  },
329
310
  () => {
330
311
  const result = stringify(tokenizeString('= += -= *= /= %= **='))
331
- if (result !== '[{"kind":"="},{"kind":"+="},{"kind":"-="},{"kind":"*="},{"kind":"/="},{"kind":"%="},{"kind":"**="}]') { throw result }
312
+ if (result !== '[{"kind":"="},{"kind":"ws"},{"kind":"+="},{"kind":"ws"},{"kind":"-="},{"kind":"ws"},{"kind":"*="},{"kind":"ws"},{"kind":"/="},{"kind":"ws"},{"kind":"%="},{"kind":"ws"},{"kind":"**="}]') { throw result }
332
313
  },
333
314
  () => {
334
315
  const result = stringify(tokenizeString('& | ^ ~ << >> >>>'))
335
- if (result !== '[{"kind":"&"},{"kind":"|"},{"kind":"^"},{"kind":"~"},{"kind":"<<"},{"kind":">>"},{"kind":">>>"}]') { throw result }
316
+ if (result !== '[{"kind":"&"},{"kind":"ws"},{"kind":"|"},{"kind":"ws"},{"kind":"^"},{"kind":"ws"},{"kind":"~"},{"kind":"ws"},{"kind":"<<"},{"kind":"ws"},{"kind":">>"},{"kind":"ws"},{"kind":">>>"}]') { throw result }
336
317
  },
337
318
  () => {
338
319
  const result = stringify(tokenizeString('&= |= ^= <<= >>= >>>='))
339
- if (result !== '[{"kind":"&="},{"kind":"|="},{"kind":"^="},{"kind":"<<="},{"kind":">>="},{"kind":">>>="}]') { throw result }
320
+ if (result !== '[{"kind":"&="},{"kind":"ws"},{"kind":"|="},{"kind":"ws"},{"kind":"^="},{"kind":"ws"},{"kind":"<<="},{"kind":"ws"},{"kind":">>="},{"kind":"ws"},{"kind":">>>="}]') { throw result }
340
321
  },
341
322
  () => {
342
323
  const result = stringify(tokenizeString('&& || ! ??'))
343
- if (result !== '[{"kind":"&&"},{"kind":"||"},{"kind":"!"},{"kind":"??"}]') { throw result }
324
+ if (result !== '[{"kind":"&&"},{"kind":"ws"},{"kind":"||"},{"kind":"ws"},{"kind":"!"},{"kind":"ws"},{"kind":"??"}]') { throw result }
344
325
  },
345
326
  () => {
346
327
  const result = stringify(tokenizeString('&&= ||= ??='))
347
- if (result !== '[{"kind":"&&="},{"kind":"||="},{"kind":"??="}]') { throw result }
328
+ if (result !== '[{"kind":"&&="},{"kind":"ws"},{"kind":"||="},{"kind":"ws"},{"kind":"??="}]') { throw result }
348
329
  },
349
330
  () => {
350
331
  const result = stringify(tokenizeString('? ?. . =>'))
351
- if (result !== '[{"kind":"?"},{"kind":"?."},{"kind":"."},{"kind":"=>"}]') { throw result }
332
+ if (result !== '[{"kind":"?"},{"kind":"ws"},{"kind":"?."},{"kind":"ws"},{"kind":"."},{"kind":"ws"},{"kind":"=>"}]') { throw result }
333
+ },
334
+ ],
335
+ ws: [
336
+ () => {
337
+ const result = stringify(tokenizeString(' '))
338
+ if (result !== '[{"kind":"ws"}]') { throw result }
339
+ },
340
+ () => {
341
+ const result = stringify(tokenizeString('\t'))
342
+ if (result !== '[{"kind":"ws"}]') { throw result }
343
+ },
344
+ () => {
345
+ const result = stringify(tokenizeString('\n'))
346
+ if (result !== '[{"kind":"ws"}]') { throw result }
347
+ },
348
+ () => {
349
+ const result = stringify(tokenizeString('\r'))
350
+ if (result !== '[{"kind":"ws"}]') { throw result }
351
+ },
352
+ () => {
353
+ const result = stringify(tokenizeString(' \t\n\r'))
354
+ if (result !== '[{"kind":"ws"}]') { throw result }
355
+ },
356
+ ],
357
+ id: [
358
+ () => {
359
+ const result = stringify(tokenizeString('err'))
360
+ if (result !== '[{"kind":"id","value":"err"}]') { throw result }
361
+ },
362
+ () => {
363
+ const result = stringify(tokenizeString('{e}'))
364
+ if (result !== '[{"kind":"{"},{"kind":"id","value":"e"},{"kind":"}"}]') { throw result }
365
+ },
366
+ () => {
367
+ const result = stringify(tokenizeString('tru'))
368
+ if (result !== '[{"kind":"id","value":"tru"}]') { throw result }
369
+ },
370
+ ],
371
+ keywords: [
372
+ () => {
373
+ const result = stringify(tokenizeString('true'))
374
+ if (result !== '[{"kind":"true"}]') { throw result }
375
+ },
376
+ () => {
377
+ const result = stringify(tokenizeString('false'))
378
+ if (result !== '[{"kind":"false"}]') { throw result }
379
+ },
380
+ () => {
381
+ const result = stringify(tokenizeString('null'))
382
+ if (result !== '[{"kind":"null"}]') { throw result }
383
+ },
384
+ () => {
385
+ const result = stringify(tokenizeString('[null]'))
386
+ if (result !== '[{"kind":"["},{"kind":"null"},{"kind":"]"}]') { throw result }
387
+ },
388
+ () => {
389
+ const result = stringify(tokenizeString('arguments'))
390
+ if (result !== '[{"kind":"arguments"}]') { throw result }
391
+ },
392
+ () => {
393
+ const result = stringify(tokenizeString('await'))
394
+ if (result !== '[{"kind":"await"}]') { throw result }
395
+ },
396
+ () => {
397
+ const result = stringify(tokenizeString('break'))
398
+ if (result !== '[{"kind":"break"}]') { throw result }
399
+ },
400
+ () => {
401
+ const result = stringify(tokenizeString('case'))
402
+ if (result !== '[{"kind":"case"}]') { throw result }
403
+ },
404
+ () => {
405
+ const result = stringify(tokenizeString('catch'))
406
+ if (result !== '[{"kind":"catch"}]') { throw result }
407
+ },
408
+ () => {
409
+ const result = stringify(tokenizeString('class'))
410
+ if (result !== '[{"kind":"class"}]') { throw result }
411
+ },
412
+ () => {
413
+ const result = stringify(tokenizeString('const'))
414
+ if (result !== '[{"kind":"const"}]') { throw result }
415
+ },
416
+ () => {
417
+ const result = stringify(tokenizeString('continue'))
418
+ if (result !== '[{"kind":"continue"}]') { throw result }
419
+ },
420
+ () => {
421
+ const result = stringify(tokenizeString('debugger'))
422
+ if (result !== '[{"kind":"debugger"}]') { throw result }
423
+ },
424
+ () => {
425
+ const result = stringify(tokenizeString('default'))
426
+ if (result !== '[{"kind":"default"}]') { throw result }
427
+ },
428
+ () => {
429
+ const result = stringify(tokenizeString('delete'))
430
+ if (result !== '[{"kind":"delete"}]') { throw result }
431
+ },
432
+ () => {
433
+ const result = stringify(tokenizeString('do'))
434
+ if (result !== '[{"kind":"do"}]') { throw result }
435
+ },
436
+ () => {
437
+ const result = stringify(tokenizeString('else'))
438
+ if (result !== '[{"kind":"else"}]') { throw result }
439
+ },
440
+ () => {
441
+ const result = stringify(tokenizeString('enum'))
442
+ if (result !== '[{"kind":"enum"}]') { throw result }
443
+ },
444
+ () => {
445
+ const result = stringify(tokenizeString('eval'))
446
+ if (result !== '[{"kind":"eval"}]') { throw result }
447
+ },
448
+ () => {
449
+ const result = stringify(tokenizeString('export'))
450
+ if (result !== '[{"kind":"export"}]') { throw result }
451
+ },
452
+ () => {
453
+ const result = stringify(tokenizeString('extends'))
454
+ if (result !== '[{"kind":"extends"}]') { throw result }
455
+ },
456
+ () => {
457
+ const result = stringify(tokenizeString('finally'))
458
+ if (result !== '[{"kind":"finally"}]') { throw result }
459
+ },
460
+ () => {
461
+ const result = stringify(tokenizeString('for'))
462
+ if (result !== '[{"kind":"for"}]') { throw result }
463
+ },
464
+ () => {
465
+ const result = stringify(tokenizeString('function'))
466
+ if (result !== '[{"kind":"function"}]') { throw result }
467
+ },
468
+ () => {
469
+ const result = stringify(tokenizeString('if'))
470
+ if (result !== '[{"kind":"if"}]') { throw result }
471
+ },
472
+ () => {
473
+ const result = stringify(tokenizeString('implements'))
474
+ if (result !== '[{"kind":"implements"}]') { throw result }
475
+ },
476
+ () => {
477
+ const result = stringify(tokenizeString('import'))
478
+ if (result !== '[{"kind":"import"}]') { throw result }
479
+ },
480
+ () => {
481
+ const result = stringify(tokenizeString('in'))
482
+ if (result !== '[{"kind":"in"}]') { throw result }
483
+ },
484
+ () => {
485
+ const result = stringify(tokenizeString('instanceof'))
486
+ if (result !== '[{"kind":"instanceof"}]') { throw result }
487
+ },
488
+ () => {
489
+ const result = stringify(tokenizeString('interface'))
490
+ if (result !== '[{"kind":"interface"}]') { throw result }
491
+ },
492
+ () => {
493
+ const result = stringify(tokenizeString('let'))
494
+ if (result !== '[{"kind":"let"}]') { throw result }
495
+ },
496
+ () => {
497
+ const result = stringify(tokenizeString('new'))
498
+ if (result !== '[{"kind":"new"}]') { throw result }
499
+ },
500
+ () => {
501
+ const result = stringify(tokenizeString('package'))
502
+ if (result !== '[{"kind":"package"}]') { throw result }
503
+ },
504
+ () => {
505
+ const result = stringify(tokenizeString('private'))
506
+ if (result !== '[{"kind":"private"}]') { throw result }
507
+ },
508
+ () => {
509
+ const result = stringify(tokenizeString('protected'))
510
+ if (result !== '[{"kind":"protected"}]') { throw result }
511
+ },
512
+ () => {
513
+ const result = stringify(tokenizeString('public'))
514
+ if (result !== '[{"kind":"public"}]') { throw result }
515
+ },
516
+ () => {
517
+ const result = stringify(tokenizeString('return'))
518
+ if (result !== '[{"kind":"return"}]') { throw result }
519
+ },
520
+ () => {
521
+ const result = stringify(tokenizeString('static'))
522
+ if (result !== '[{"kind":"static"}]') { throw result }
523
+ },
524
+ () => {
525
+ const result = stringify(tokenizeString('super'))
526
+ if (result !== '[{"kind":"super"}]') { throw result }
527
+ },
528
+ () => {
529
+ const result = stringify(tokenizeString('switch'))
530
+ if (result !== '[{"kind":"switch"}]') { throw result }
531
+ },
532
+ () => {
533
+ const result = stringify(tokenizeString('this'))
534
+ if (result !== '[{"kind":"this"}]') { throw result }
535
+ },
536
+ () => {
537
+ const result = stringify(tokenizeString('throw'))
538
+ if (result !== '[{"kind":"throw"}]') { throw result }
539
+ },
540
+ () => {
541
+ const result = stringify(tokenizeString('try'))
542
+ if (result !== '[{"kind":"try"}]') { throw result }
543
+ },
544
+ () => {
545
+ const result = stringify(tokenizeString('typeof'))
546
+ if (result !== '[{"kind":"typeof"}]') { throw result }
547
+ },
548
+ () => {
549
+ const result = stringify(tokenizeString('var'))
550
+ if (result !== '[{"kind":"var"}]') { throw result }
551
+ },
552
+ () => {
553
+ const result = stringify(tokenizeString('void'))
554
+ if (result !== '[{"kind":"void"}]') { throw result }
555
+ },
556
+ () => {
557
+ const result = stringify(tokenizeString('while'))
558
+ if (result !== '[{"kind":"while"}]') { throw result }
559
+ },
560
+ () => {
561
+ const result = stringify(tokenizeString('with'))
562
+ if (result !== '[{"kind":"with"}]') { throw result }
563
+ },
564
+ () => {
565
+ const result = stringify(tokenizeString('yield'))
566
+ if (result !== '[{"kind":"yield"}]') { throw result }
352
567
  },
353
568
  ]
354
569
  }
@@ -95,7 +95,7 @@ module.exports = {
95
95
  const obj = parser.parse(tokenList)
96
96
  const result = stringify(obj)
97
97
  if (result !== '["ok",{"a":{"b":{"c":["d"]}}}]') { throw result }
98
- },
98
+ }
99
99
  ],
100
100
  invalid: [
101
101
  () => {
@@ -236,5 +236,11 @@ module.exports = {
236
236
  const result = stringify(obj)
237
237
  if (result !== '["error","unexpected token"]') { throw result }
238
238
  },
239
+ () => {
240
+ const tokenList = tokenizeString('10-5')
241
+ const obj = parser.parse(tokenList)
242
+ const result = stringify(obj)
243
+ if (result !== '["error","unexpected token"]') { throw result }
244
+ },
239
245
  ]
240
246
  }
@@ -1,38 +1,92 @@
1
+ const operator = require('../../types/function/operator/module.f.cjs')
1
2
  const list = require('../../types/list/module.f.cjs')
3
+ const { empty, flat, stateScan } = list
4
+ const { multiply } = require('../../types/bigfloat/module.f.cjs')
2
5
  const jsTokenizer = require('../../js/tokenizer/module.f.cjs')
3
6
 
4
7
  /**
5
8
  * @typedef {|
6
- * jsTokenizer.SimpleToken |
9
+ * {readonly kind: 'true' | 'false' | 'null' } |
10
+ * {readonly kind: '{' | '}' | ':' | ',' | '[' | ']' } |
7
11
  * jsTokenizer.StringToken |
8
12
  * jsTokenizer.NumberToken |
9
13
  * jsTokenizer.ErrorToken
10
14
  * } JsonToken
11
15
  */
12
16
 
13
- /** @type {(input: jsTokenizer.JsToken) => JsonToken} */
17
+ /**
18
+ * @typedef {|
19
+ * {readonly kind: 'def' | '-' }
20
+ * } ScanState
21
+ */
22
+
23
+ /**
24
+ * @typedef {|
25
+ * jsTokenizer.JsToken | null
26
+ * } ScanInput
27
+ */
28
+
29
+ /** @type {(input: jsTokenizer.JsToken) => list.List<JsonToken>} */
14
30
  const mapToken = input =>
15
31
  {
16
32
  switch(input.kind)
17
33
  {
18
- case "{":
19
- case "}":
20
- case ":":
21
- case ",":
22
- case "[":
23
- case "]":
24
- case "true":
25
- case "false":
26
- case "null":
27
- case "string":
28
- case "number":
29
- case "error": return input
30
- default: return { kind: "error", message: "invalid token" }
34
+ case '{':
35
+ case '}':
36
+ case ':':
37
+ case ',':
38
+ case '[':
39
+ case ']':
40
+ case 'true':
41
+ case 'false':
42
+ case 'null':
43
+ case 'string':
44
+ case 'number':
45
+ case 'error': return [input]
46
+ case 'ws': return empty
47
+ default: return [{ kind: 'error', message: 'invalid token' }]
48
+ }
49
+ }
50
+
51
+ /** @type {(input: ScanInput) => readonly [list.List<JsonToken>, ScanState]} */
52
+ const parseDefaultState = input =>
53
+ {
54
+ if (input === null) return [empty, { kind: 'def'}]
55
+ switch(input.kind)
56
+ {
57
+ case '-': return [empty, { kind: '-'}]
58
+ default: return [mapToken(input), { kind: 'def'}]
59
+ }
60
+ }
61
+
62
+ /** @type {(input: ScanInput) => readonly [list.List<JsonToken>, ScanState]} */
63
+ const parseMinusState = input =>
64
+ {
65
+ if (input === null) return [[{ kind: 'error', message: 'invalid token' }], { kind: 'def'}]
66
+ switch(input.kind)
67
+ {
68
+ case '-': return [[{ kind: 'error', message: 'invalid token' }], { kind: '-'}]
69
+ case 'number': return [[{ kind: 'number', bf: multiply(input.bf)(-1n), value: `-${input.value}` }], { kind: 'def'}]
70
+ default: return [{ first: { kind: 'error', message: 'invalid token' }, tail: mapToken(input)}, { kind: 'def'}]
71
+ }
72
+ }
73
+
74
+ /** @type {operator.StateScan<ScanInput, ScanState, list.List<JsonToken>>} */
75
+ const scanToken = state => input => {
76
+ switch(state.kind)
77
+ {
78
+ case '-': return parseMinusState(input)
79
+ default: return parseDefaultState(input)
31
80
  }
32
81
  }
33
82
 
34
83
  /** @type {(input: list.List<number>) => list.List<JsonToken>} */
35
- const tokenize = input => list.map(mapToken)(jsTokenizer.tokenize(input))
84
+ const tokenize = input =>
85
+ {
86
+ /** @type {list.List<ScanInput>} */
87
+ const jsTokens = jsTokenizer.tokenize(input)
88
+ return flat(stateScan(scanToken)({ kind: 'def' })(list.concat(jsTokens)([null])))
89
+ }
36
90
 
37
91
  module.exports = {
38
92
  /** @readonly */