functionalscript 0.0.323 → 0.0.327

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.
@@ -10,13 +10,13 @@ const compileMap = {
10
10
  ':index.js': [
11
11
  'ok',
12
12
  require_ => m0 => {
13
- const [r1, m1] = require_('./b')(m0);
14
- if (r1[0] === 'error') { throw r1 }
15
- const [r2, m2] = require_('./a/')(m1);
16
- if (r2[0] === 'error') { throw r2 }
17
- const [r3, m3] = require_('x/r')(m2);
18
- if (r3[0] === 'error') { throw r3 }
19
- return [['ok', ':index.js'], m3]
13
+ let [r, m] = require_('./b')(m0);
14
+ if (r[0] === 'error') { throw r }
15
+ [r, m] = require_('./a/')(m);
16
+ if (r[0] === 'error') { throw r }
17
+ [r, m] = require_('x/r')(m);
18
+ if (r[0] === 'error') { throw r }
19
+ return [['ok', ':index.js'], m]
20
20
  }],
21
21
  ':b.js': [
22
22
  'ok',
@@ -32,7 +32,9 @@ const compileMap = {
32
32
  /** @type {function_.Compile} */
33
33
  const compile = source => compileMap[source] ?? ['error', 'invalid source']
34
34
 
35
- /** @type {{ readonly [k in string]?: { readonly dependencies: { readonly [k in string]?: string }, files:{ readonly [k in string]?: string } }}} */
35
+ /** @typedef {{ readonly [k in string]?: string }} StringMap */
36
+
37
+ /** @type {{ readonly [k in string]?: { readonly dependencies: StringMap, files: StringMap }}} */
36
38
  const packageMap = {
37
39
  '': {
38
40
  dependencies: {
@@ -68,10 +70,22 @@ const getOrBuild = _.getOrBuild
68
70
  (/** @type {module_.MapInterface<map.Map<module_.State>>} */(map))
69
71
 
70
72
  {
71
- const [r] = getOrBuild({ package: '', path: ['index.js'] })(undefined)
73
+ let [r, m] = getOrBuild({ package: '', path: ['index.js'] })(undefined)
72
74
  if (JSON.stringify(r) !==
73
75
  '["ok",{"exports":":index.js","requireMap":{"./a/":"/a/index.js","./b":"/b.js","x/r":"/node_modules/x/r.js"}}]'
74
76
  ) {
75
77
  throw r
76
78
  }
79
+ [r, m] = getOrBuild({ package: '', path: ['b.js'] })(m)
80
+ if (JSON.stringify(r) !==
81
+ '["ok",{"exports":":b.js","requireMap":{}}]'
82
+ ) {
83
+ throw r
84
+ }
85
+ [r, m] = getOrBuild({ package: '', path: ['c.js']})(m)
86
+ if (JSON.stringify(r) !==
87
+ '["error",["file not found"]]'
88
+ ) {
89
+ throw r
90
+ }
77
91
  }
@@ -0,0 +1,433 @@
1
+ const { todo } = require('../../dev')
2
+ const operator = require('../../types/function/operator')
3
+ const { concat } = require('../../types/list')
4
+ const list = require('../../types/list')
5
+
6
+ /** @typedef {{readonly kind: '{'}} LeftBraceToken */
7
+
8
+ /** @typedef {{readonly kind: '}'}} RightBraceToken */
9
+
10
+ /** @typedef {{readonly kind: ':'}} ColonToken */
11
+
12
+ /** @typedef {{readonly kind: ','}} CommaToken */
13
+
14
+ /** @typedef {{readonly kind: '['}} LeftBracketToken */
15
+
16
+ /** @typedef {{readonly kind: ']'}} RightBracketToken */
17
+
18
+ /**
19
+ * @typedef {{
20
+ * readonly kind: 'string'
21
+ * readonly value: string
22
+ * }} StringToken
23
+ * */
24
+
25
+ /**
26
+ * @typedef {{
27
+ * readonly kind: 'number'
28
+ * readonly value: string
29
+ * }} NumberToken
30
+ * */
31
+
32
+ /** @typedef {{readonly kind: 'true'}} TrueToken */
33
+
34
+ /** @typedef {{readonly kind: 'false'}} FalseToken */
35
+
36
+ /** @typedef {{readonly kind: 'null'}} NullToken */
37
+
38
+ /** @typedef {{readonly kind: 'error', message: ErrorMessage}} ErrorToken */
39
+
40
+ /**
41
+ * @typedef {|
42
+ * LeftBraceToken |
43
+ * RightBraceToken |
44
+ * ColonToken |
45
+ * CommaToken |
46
+ * LeftBracketToken |
47
+ * RightBracketToken |
48
+ * StringToken |
49
+ * NumberToken |
50
+ * TrueToken |
51
+ * FalseToken |
52
+ * NullToken |
53
+ * ErrorToken
54
+ * } JsonToken
55
+ */
56
+
57
+ const leftBrace = 0x7b
58
+ const rightBrace = 0x7d
59
+ const colon = 0x3a
60
+ const comma = 0x2c
61
+ const leftBracket = 0x5b
62
+ const rightBracket = 0x5d
63
+
64
+ const quotationMark = 0x22
65
+ const digit0 = 0x30
66
+ const digit1 = 0x31
67
+ const digit9 = 0x39
68
+ const signPlus = 0x2b
69
+ const signMinus = 0x2d
70
+ const decimalPoint = 0x2e
71
+
72
+ const horizontalTab = 0x09
73
+ const newLine = 0x0a
74
+ const carriageReturn = 0x0d
75
+ const space = 0x20
76
+
77
+ const backslach = 0x5c
78
+ const slash = 0x2f
79
+ const backspace = 0x08
80
+ const formfeed = 0x0c
81
+
82
+ const capitalLetterA = 0x41
83
+ const capitalLetterE = 0x45
84
+ const capitalLetterF = 0x46
85
+
86
+ const letterA = 0x61
87
+ const letterB = 0x62
88
+ const letterE = 0x65
89
+ const letterF = 0x66
90
+ const letterN = 0x6e
91
+ const letterR = 0x72
92
+ const letterT = 0x74
93
+ const letterU = 0x75
94
+ const letterZ = 0x7a
95
+
96
+ /**
97
+ * @typedef {|
98
+ * InitialState |
99
+ * ParseKeywordState |
100
+ * ParseStringState |
101
+ * ParseEscapeCharState |
102
+ * ParseUnicodeCharState |
103
+ * ParseNumberState |
104
+ * InvalidNumberState |
105
+ * EofState
106
+ * } TokenizerState
107
+ */
108
+
109
+ /**
110
+ * @typedef {|
111
+ * 'invalid keyword' |
112
+ * '" are missing' |
113
+ * 'unescaped character' |
114
+ * 'invalid hex value' |
115
+ * 'unexpected character' |
116
+ * 'invalid number' |
117
+ * 'eof'
118
+ * } ErrorMessage
119
+ */
120
+
121
+ /** @typedef {{ readonly kind: 'initial'}} InitialState */
122
+
123
+ /** @typedef {{ readonly kind: 'keyword', readonly value: string}} ParseKeywordState */
124
+
125
+ /** @typedef {{ readonly kind: 'string', readonly value: string}} ParseStringState */
126
+
127
+ /** @typedef {{ readonly kind: 'escapeChar', readonly value: string}} ParseEscapeCharState */
128
+
129
+ /** @typedef {{ readonly kind: 'unicodeChar', readonly value: string, readonly unicode: number, readonly hexIndex: number}} ParseUnicodeCharState */
130
+
131
+ /**
132
+ * @typedef {{
133
+ * readonly kind: 'number',
134
+ * readonly numberKind: '0' | '-' | 'int' | '.' | 'fractional' | 'e' | 'e+' | 'e-' | 'expDigits'
135
+ * readonly value: string
136
+ * }} ParseNumberState
137
+ * */
138
+
139
+ /** @typedef {{ readonly kind: 'invalidNumber'}} InvalidNumberState */
140
+
141
+ /** @typedef {{ readonly kind: 'eof'}} EofState */
142
+
143
+ /** @typedef {number|undefined} JsonCharacter */
144
+
145
+ /** @type {(old: string) => (input: JsonCharacter) => string} */
146
+ const appendChar = old => input => input === undefined ? old : operator.concat(charToString(input))(old)
147
+
148
+ /** @type {(input: JsonCharacter) => string} */
149
+ const charToString = input => input === undefined ? '' : String.fromCharCode(input)
150
+
151
+ /** @type {(state: InitialState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
152
+ const initialStateOp = initialState => input =>
153
+ {
154
+ if (input === undefined)
155
+ {
156
+ return[undefined, {kind: 'eof'}]
157
+ }
158
+ if (input >= digit1 && input <= digit9)
159
+ {
160
+ return [undefined, { kind: 'number', value: charToString(input), numberKind: 'int'}]
161
+ }
162
+ if (input >= letterA && input <= letterZ)
163
+ {
164
+ return [undefined, { kind: 'keyword', value: charToString(input)}]
165
+ }
166
+ switch(input)
167
+ {
168
+ case leftBrace: return [[{kind: '{'}], initialState]
169
+ case rightBrace: return [[{kind: '}'}], initialState]
170
+ case colon: return [[{kind: ':'}], initialState]
171
+ case comma: return [[{kind: ','}], initialState]
172
+ case leftBracket: return [[{kind: '['}], initialState]
173
+ case rightBracket: return [[{kind: ']'}], initialState]
174
+ case quotationMark: return[undefined, {kind: 'string', value: ''}]
175
+ case digit0: return [undefined, { kind: 'number', value: charToString(input), numberKind: '0'}]
176
+ case signMinus: return [undefined, { kind: 'number', value: charToString(input), numberKind: '-'}]
177
+ case horizontalTab:
178
+ case newLine:
179
+ case carriageReturn:
180
+ case space: return[undefined, initialState]
181
+ default: return [[{kind: 'error', message: 'unexpected character'}], initialState]
182
+ }
183
+ }
184
+
185
+ /** @type {(state: ParseNumberState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
186
+ const parseNumberStateOp = state => input =>
187
+ {
188
+ if (input === undefined)
189
+ {
190
+ switch (state.numberKind)
191
+ {
192
+ case '-':
193
+ case '.':
194
+ case 'e':
195
+ case 'e+':
196
+ case 'e-': return [[{kind: 'error', message: 'invalid number'}], {kind: 'invalidNumber', }]
197
+ default: return [[{kind: 'number', value: state.value}], {kind: 'eof'}]
198
+ }
199
+ }
200
+ if (input === decimalPoint)
201
+ {
202
+ switch (state.numberKind)
203
+ {
204
+ case '0':
205
+ case 'int': return [undefined, {kind: 'number', value: appendChar(state.value)(input), numberKind: '.'}]
206
+ default: return tokenizeOp({kind: 'invalidNumber'})(input)
207
+ }
208
+ }
209
+ if (input === digit0)
210
+ {
211
+ switch (state.numberKind)
212
+ {
213
+ case '0': return tokenizeOp({kind: 'invalidNumber'})(input)
214
+ case '-': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: '0'}]
215
+ case '.': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'fractional'}]
216
+ case 'e':
217
+ case 'e+':
218
+ case 'e-': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'expDigits'}]
219
+ default: return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: state.numberKind}]
220
+ }
221
+ }
222
+ if (input >= digit1 && input <= digit9)
223
+ {
224
+ switch (state.numberKind)
225
+ {
226
+ case '0': return tokenizeOp({kind: 'invalidNumber'})(input)
227
+ case '-': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'int'}]
228
+ case '.': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'fractional'}]
229
+ case 'e':
230
+ case 'e+':
231
+ case 'e-': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'expDigits'}]
232
+ default: return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: state.numberKind}]
233
+ }
234
+ }
235
+ if (input === letterE || input === capitalLetterE)
236
+ {
237
+ switch (state.numberKind)
238
+ {
239
+ case '0':
240
+ case 'int':
241
+ case 'fractional': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'e'}]
242
+ default: return tokenizeOp({kind: 'invalidNumber'})(input)
243
+ }
244
+ }
245
+ if (input === signMinus)
246
+ {
247
+ switch (state.numberKind)
248
+ {
249
+ case 'e': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'e-'}]
250
+ default: return tokenizeOp({kind: 'invalidNumber'})(input)
251
+ }
252
+ }
253
+ if (input === signPlus)
254
+ {
255
+ switch (state.numberKind)
256
+ {
257
+ case 'e': return [undefined, {kind:'number', value: appendChar(state.value)(input), numberKind: 'e+'}]
258
+ default: return tokenizeOp({kind: 'invalidNumber'})(input)
259
+ }
260
+ }
261
+ if (isTerminalForNumber(input))
262
+ {
263
+ switch (state.numberKind)
264
+ {
265
+ case '-':
266
+ case '.':
267
+ case 'e':
268
+ case 'e+':
269
+ case 'e-':
270
+ {
271
+ const next = tokenizeOp({kind: 'initial'})(input)
272
+ return [{first: {kind: 'error', message: 'invalid number'}, tail: next[0]}, next[1]]
273
+ }
274
+ default:
275
+ {
276
+ const next = tokenizeOp({kind: 'initial'})(input)
277
+ return [{first: {kind: 'number', value: state.value}, tail: next[0]}, next[1]]
278
+ }
279
+ }
280
+ }
281
+ return tokenizeOp({kind: 'invalidNumber'})(input)
282
+ }
283
+
284
+ /** @type {(char: number) => boolean} */
285
+ const isTerminalForNumber = char =>
286
+ {
287
+ switch (char)
288
+ {
289
+ case quotationMark:
290
+ case comma:
291
+ case leftBrace:
292
+ case rightBrace:
293
+ case leftBracket:
294
+ case rightBracket:
295
+ case colon: return true
296
+ default: return false
297
+ }
298
+ }
299
+
300
+ /** @type {(state: InvalidNumberState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
301
+ const invalidNumberStateOp = state => input =>
302
+ {
303
+ if (input === undefined)
304
+ {
305
+ return [[{kind: 'error', message: 'invalid number'}], {kind: 'eof'}]
306
+ }
307
+ if (isTerminalForNumber(input))
308
+ {
309
+ const next = tokenizeOp({kind: 'initial'})(input)
310
+ return [{first: {kind: 'error', message: 'invalid number'}, tail: next[0]}, next[1]]
311
+ }
312
+ return [undefined, {kind: 'invalidNumber'}]
313
+ }
314
+
315
+ /** @type {(state: ParseStringState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
316
+ const parseStringStateOp = state => input =>
317
+ {
318
+ switch(input)
319
+ {
320
+ case quotationMark: return[[{kind: 'string', value: state.value}], {kind: 'initial'}]
321
+ case backslach: return [undefined, {kind:'escapeChar', value: state.value}]
322
+ case undefined: return [[{kind: 'error', message: '" are missing'}], {kind: 'eof'}]
323
+ default: return [undefined, {kind:'string', value: appendChar(state.value)(input)}]
324
+ }
325
+ }
326
+
327
+ /** @type {(state: ParseEscapeCharState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
328
+ const parseEscapeCharStateOp = state => input =>
329
+ {
330
+ switch(input)
331
+ {
332
+ case quotationMark:
333
+ case backslach:
334
+ case slash: return [undefined, {kind: 'string', value: appendChar(state.value)(input)}]
335
+ case letterB: return [undefined, {kind: 'string', value: appendChar(state.value)(backspace)}]
336
+ case letterF: return [undefined, {kind: 'string', value: appendChar(state.value)(formfeed)}]
337
+ case letterN: return [undefined, {kind: 'string', value: appendChar(state.value)(newLine)}]
338
+ case letterR: return [undefined, {kind: 'string', value: appendChar(state.value)(carriageReturn)}]
339
+ case letterT: return [undefined, {kind: 'string', value: appendChar(state.value)(horizontalTab)}]
340
+ case letterU: return [undefined, {kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0}]
341
+ case undefined: return [[{kind: 'error', message: '" are missing'}], {kind: 'eof'}]
342
+ default: {
343
+ const next = tokenizeOp({kind: 'string', value: state.value})(input)
344
+ return [{first: {kind: 'error', message: 'unescaped character'}, tail: next[0]}, next[1]]
345
+ }
346
+ }
347
+ }
348
+
349
+ /** @type {(hex: number) => number|undefined} */
350
+ const hexDigitToNumber = hex =>
351
+ {
352
+ if (hex >= digit0 && hex <= digit9) { return hex - digit0 }
353
+ if (hex >= capitalLetterA && hex <= capitalLetterF) { return hex - capitalLetterA + 10 }
354
+ if (hex >= letterA && hex <= letterF) { return hex - letterA + 10 }
355
+ }
356
+
357
+ /** @type {(state: ParseUnicodeCharState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
358
+ const parseUnicodeCharStateOp = state => input =>
359
+ {
360
+ if (input === undefined)
361
+ {
362
+ return [[{kind: 'error', message: '" are missing'}], {kind: 'eof'}]
363
+ }
364
+ const hexValue = hexDigitToNumber(input)
365
+ if (hexValue === undefined)
366
+ {
367
+ const next = tokenizeOp({kind: 'string', value: state.value})(input)
368
+ return [{first: {kind: 'error', message: 'invalid hex value'}, tail: next[0]}, next[1]]
369
+ }
370
+ const newUnicode = state.unicode | (hexValue << (3 - state.hexIndex) * 4)
371
+ return [undefined, state.hexIndex === 3 ?
372
+ {kind: 'string', value: appendChar(state.value)(newUnicode)} :
373
+ {kind: 'unicodeChar', value: state.value, unicode: newUnicode, hexIndex: state.hexIndex + 1}]
374
+ }
375
+
376
+ /** @type {(s: string) => JsonToken} */
377
+ const stringToKeywordToken = s =>
378
+ {
379
+ switch(s)
380
+ {
381
+ case 'true': return {kind: 'true'}
382
+ case 'false': return {kind: 'false'}
383
+ case 'null': return {kind: 'null'}
384
+ default: return {kind: 'error', message: 'invalid keyword'}
385
+ }
386
+ }
387
+
388
+ /** @type {(state: ParseKeywordState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
389
+ const parseKeyWordStateOp = state => input =>
390
+ {
391
+ if (input === undefined)
392
+ {
393
+ const keyWordToken = stringToKeywordToken(state.value)
394
+ return [[keyWordToken], {kind: 'eof'}]
395
+ }
396
+ if (input >= letterA && input <= letterZ)
397
+ {
398
+ return [undefined, {kind: 'keyword', value: appendChar(state.value)(input)}]
399
+ }
400
+ const keyWordToken = stringToKeywordToken(state.value)
401
+ const next = tokenizeOp({kind: 'initial'})(input)
402
+ return [{first: keyWordToken, tail: next[0]}, next[1]]
403
+ }
404
+
405
+ /** @type {(state: EofState) => (input: JsonCharacter) => readonly[list.List<JsonToken>, TokenizerState]} */
406
+ const eofStateOp = state => input => [[{kind: 'error', message: 'eof'}], state]
407
+
408
+ /** @type {operator.StateScan<JsonCharacter, TokenizerState, list.List<JsonToken>>} */
409
+ const tokenizeOp = state => input =>
410
+ {
411
+ const f = () => {
412
+ switch(state.kind)
413
+ {
414
+ case 'initial': return initialStateOp(state)
415
+ case 'keyword': return parseKeyWordStateOp(state)
416
+ case 'string': return parseStringStateOp(state)
417
+ case 'escapeChar': return parseEscapeCharStateOp(state)
418
+ case 'unicodeChar': return parseUnicodeCharStateOp(state)
419
+ case 'invalidNumber': return invalidNumberStateOp(state)
420
+ case 'number': return parseNumberStateOp(state)
421
+ case 'eof': return eofStateOp(state)
422
+ }
423
+ }
424
+ return f()(input)
425
+ }
426
+
427
+ /** @type {(input: list.List<JsonCharacter>) => list.List<JsonToken>} */
428
+ const tokenize = input => list.flat(list.stateScan(tokenizeOp)({kind: 'initial'})(input))
429
+
430
+ module.exports = {
431
+ /** @readonly */
432
+ tokenize,
433
+ }
@@ -0,0 +1,307 @@
1
+ const tokenizer = require('.')
2
+ const list = require('../../types/list')
3
+ const json = require('..')
4
+ const { sort } = require('../../types/object')
5
+
6
+ /** @type {(s: string) => list.List<tokenizer.JsonCharacter>} */
7
+ const toCharacters = s =>
8
+ {
9
+ /** @type {list.List<tokenizer.JsonCharacter>} */
10
+ const charCodes = list.toCharCodes(s)
11
+ return list.concat(charCodes)([undefined])
12
+ }
13
+
14
+ /** @type {(s: string) => readonly tokenizer.JsonToken[]} */
15
+ const tokenizeString = s =>
16
+ {
17
+ const characters = toCharacters(s)
18
+ return list.toArray(tokenizer.tokenize(characters))
19
+ }
20
+
21
+ /** @type {(a: readonly tokenizer.JsonToken[]) => string} */
22
+ const stringify = a => json.stringify(sort)(a)
23
+
24
+ {
25
+ const result = tokenizeString('')
26
+ if (result.length !== 0) { throw result }
27
+ }
28
+
29
+ {
30
+ const result = stringify(tokenizeString('{'))
31
+ if (result !== '[{"kind":"{"}]') { throw result }
32
+ }
33
+
34
+ {
35
+ const result = stringify(tokenizeString('}'))
36
+ if (result !== '[{"kind":"}"}]') { throw result }
37
+ }
38
+
39
+ {
40
+ const result = stringify(tokenizeString(':'))
41
+ if (result !== '[{"kind":":"}]') { throw result }
42
+ }
43
+
44
+ {
45
+ const result = stringify(tokenizeString(','))
46
+ if (result !== '[{"kind":","}]') { throw result }
47
+ }
48
+
49
+ {
50
+ const result = stringify(tokenizeString('['))
51
+ if (result !== '[{"kind":"["}]') { throw result }
52
+ }
53
+
54
+ {
55
+ const result = stringify(tokenizeString(']'))
56
+ if (result !== '[{"kind":"]"}]') { throw result }
57
+ }
58
+
59
+ {
60
+ const result = stringify(tokenizeString('ᄑ'))
61
+ if (result !== '[{"kind":"error","message":"unexpected character"}]') { throw result }
62
+ }
63
+
64
+ {
65
+ const result = stringify(tokenizeString('err'))
66
+ if (result !== '[{"kind":"error","message":"invalid keyword"}]') { throw result }
67
+ }
68
+
69
+ {
70
+ const result = stringify(tokenizeString('{e}'))
71
+ if (result !== '[{"kind":"{"},{"kind":"error","message":"invalid keyword"},{"kind":"}"}]') { throw result }
72
+ }
73
+
74
+ {
75
+ const result = stringify(tokenizeString('{ \t\n\r}'))
76
+ if (result !== '[{"kind":"{"},{"kind":"}"}]') { throw result }
77
+ }
78
+
79
+ {
80
+ const result = stringify(tokenizeString('true'))
81
+ if (result !== '[{"kind":"true"}]') { throw result }
82
+ }
83
+
84
+ {
85
+ const result = stringify(tokenizeString('tru'))
86
+ if (result !== '[{"kind":"error","message":"invalid keyword"}]') { throw result }
87
+ }
88
+
89
+ {
90
+ const result = stringify(tokenizeString('false'))
91
+ if (result !== '[{"kind":"false"}]') { throw result }
92
+ }
93
+
94
+ {
95
+ const result = stringify(tokenizeString('null'))
96
+ if (result !== '[{"kind":"null"}]') { throw result }
97
+ }
98
+
99
+ {
100
+ const result = stringify(tokenizeString('[null]'))
101
+ if (result !== '[{"kind":"["},{"kind":"null"},{"kind":"]"}]') { throw result }
102
+ }
103
+
104
+ {
105
+ const result = stringify(tokenizeString('""'))
106
+ if (result !== '[{"kind":"string","value":""}]') { throw result }
107
+ }
108
+
109
+ {
110
+ const result = stringify(tokenizeString('"value"'))
111
+ if (result !== '[{"kind":"string","value":"value"}]') { throw result }
112
+ }
113
+
114
+ {
115
+ const result = stringify(tokenizeString('"value'))
116
+ if (result !== '[{"kind":"error","message":"\\" are missing"}]') { throw result }
117
+ }
118
+
119
+ {
120
+ const result = stringify(tokenizeString('"value1" "value2"'))
121
+ if (result !== '[{"kind":"string","value":"value1"},{"kind":"string","value":"value2"}]') { throw result }
122
+ }
123
+
124
+ {
125
+ const result = stringify(tokenizeString('"'))
126
+ if (result !== '[{"kind":"error","message":"\\" are missing"}]') { throw result }
127
+ }
128
+
129
+ {
130
+ const result = stringify(tokenizeString('"\\\\"'))
131
+ if (result !== '[{"kind":"string","value":"\\\\"}]') { throw result }
132
+ }
133
+
134
+ {
135
+ const result = stringify(tokenizeString('"\\""'))
136
+ if (result !== '[{"kind":"string","value":"\\""}]') { throw result }
137
+ }
138
+
139
+ {
140
+ const result = stringify(tokenizeString('"\\/"'))
141
+ if (result !== '[{"kind":"string","value":"/"}]') { throw result }
142
+ }
143
+
144
+ {
145
+ const result = stringify(tokenizeString('"\\x"'))
146
+ if (result !== '[{"kind":"error","message":"unescaped character"},{"kind":"string","value":"x"}]') { throw result }
147
+ }
148
+
149
+ {
150
+ const result = stringify(tokenizeString('"\\'))
151
+ if (result !== '[{"kind":"error","message":"\\" are missing"}]') { throw result }
152
+ }
153
+
154
+ {
155
+ const result = stringify(tokenizeString('"\\b\\f\\n\\r\\t"'))
156
+ if (result !== '[{"kind":"string","value":"\\b\\f\\n\\r\\t"}]') { throw result }
157
+ }
158
+
159
+ {
160
+ const result = stringify(tokenizeString('"\\u1234"'))
161
+ if (result !== '[{"kind":"string","value":"ሴ"}]') { throw result }
162
+ }
163
+
164
+ {
165
+ const result = stringify(tokenizeString('"\\uaBcDEeFf"'))
166
+ if (result !== '[{"kind":"string","value":"ꯍEeFf"}]') { throw result }
167
+ }
168
+
169
+ {
170
+ const result = stringify(tokenizeString('"\\uEeFg"'))
171
+ if (result !== '[{"kind":"error","message":"invalid hex value"},{"kind":"string","value":"g"}]') { throw result }
172
+ }
173
+
174
+ {
175
+ const result = stringify(tokenizeString('0'))
176
+ if (result !== '[{"kind":"number","value":"0"}]') { throw result }
177
+ }
178
+
179
+ {
180
+ const result = stringify(tokenizeString('[0]'))
181
+ if (result !== '[{"kind":"["},{"kind":"number","value":"0"},{"kind":"]"}]') { throw result }
182
+ }
183
+
184
+ {
185
+ const result = stringify(tokenizeString('00'))
186
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
187
+ }
188
+
189
+ {
190
+ const result = stringify(tokenizeString('0abc,'))
191
+ if (result !== '[{"kind":"error","message":"invalid number"},{"kind":","}]') { throw result }
192
+ }
193
+
194
+ {
195
+ const result = stringify(tokenizeString('1234567890'))
196
+ if (result !== '[{"kind":"number","value":"1234567890"}]') { throw result }
197
+ }
198
+
199
+ {
200
+ const result = stringify(tokenizeString('{90}'))
201
+ if (result !== '[{"kind":"{"},{"kind":"number","value":"90"},{"kind":"}"}]') { throw result }
202
+ }
203
+
204
+ {
205
+ const result = stringify(tokenizeString('10-0'))
206
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
207
+ }
208
+
209
+ {
210
+ const result = stringify(tokenizeString('9a:'))
211
+ if (result !== '[{"kind":"error","message":"invalid number"},{"kind":":"}]') { throw result }
212
+ }
213
+
214
+ {
215
+ const result = stringify(tokenizeString('-10'))
216
+ if (result !== '[{"kind":"number","value":"-10"}]') { throw result }
217
+ }
218
+
219
+ {
220
+ const result = stringify(tokenizeString('-0'))
221
+ if (result !== '[{"kind":"number","value":"-0"}]') { throw result }
222
+ }
223
+
224
+ {
225
+ const result = stringify(tokenizeString('-00'))
226
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
227
+ }
228
+
229
+ {
230
+ const result = stringify(tokenizeString('-.123'))
231
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
232
+ }
233
+
234
+ {
235
+ const result = stringify(tokenizeString('0.01'))
236
+ if (result !== '[{"kind":"number","value":"0.01"}]') { throw result }
237
+ }
238
+
239
+ {
240
+ const result = stringify(tokenizeString('-0.9'))
241
+ if (result !== '[{"kind":"number","value":"-0.9"}]') { throw result }
242
+ }
243
+
244
+ {
245
+ const result = stringify(tokenizeString('-0.'))
246
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
247
+ }
248
+
249
+ {
250
+ const result = stringify(tokenizeString('-0.]'))
251
+ if (result !== '[{"kind":"error","message":"invalid number"},{"kind":"]"}]') { throw result }
252
+ }
253
+
254
+ {
255
+ const result = stringify(tokenizeString('12.34'))
256
+ if (result !== '[{"kind":"number","value":"12.34"}]') { throw result }
257
+ }
258
+
259
+ {
260
+ const result = stringify(tokenizeString('-12.00'))
261
+ if (result !== '[{"kind":"number","value":"-12.00"}]') { throw result }
262
+ }
263
+
264
+ {
265
+ const result = stringify(tokenizeString('-12.'))
266
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
267
+ }
268
+
269
+ {
270
+ const result = stringify(tokenizeString('12.]'))
271
+ if (result !== '[{"kind":"error","message":"invalid number"},{"kind":"]"}]') { throw result }
272
+ }
273
+
274
+ {
275
+ const result = stringify(tokenizeString('0e1'))
276
+ if (result !== '[{"kind":"number","value":"0e1"}]') { throw result }
277
+ }
278
+
279
+ {
280
+ const result = stringify(tokenizeString('0e+2'))
281
+ if (result !== '[{"kind":"number","value":"0e+2"}]') { throw result }
282
+ }
283
+
284
+ {
285
+ const result = stringify(tokenizeString('0e-0'))
286
+ if (result !== '[{"kind":"number","value":"0e-0"}]') { throw result }
287
+ }
288
+
289
+ {
290
+ const result = stringify(tokenizeString('12e0000'))
291
+ if (result !== '[{"kind":"number","value":"12e0000"}]') { throw result }
292
+ }
293
+
294
+ {
295
+ const result = stringify(tokenizeString('-12e-0001'))
296
+ if (result !== '[{"kind":"number","value":"-12e-0001"}]') { throw result }
297
+ }
298
+
299
+ {
300
+ const result = stringify(tokenizeString('0e'))
301
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
302
+ }
303
+
304
+ {
305
+ const result = stringify(tokenizeString('0e-'))
306
+ if (result !== '[{"kind":"error","message":"invalid number"}]') { throw result }
307
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.323",
3
+ "version": "0.0.327",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/test.js CHANGED
@@ -5,6 +5,7 @@ require('./types/array/test')
5
5
  require('./types/btree/test')
6
6
  require('./sha2/test')
7
7
  require('./json/test')
8
+ require('./json/tokenizer/test')
8
9
  require('./types/object/test')
9
10
  require('./io/commonjs/test')
10
11
  require('./commonjs/package/dependencies/test')