functionalscript 0.0.497 → 0.0.499

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.
package/fsc/module.f.cjs CHANGED
@@ -12,7 +12,7 @@ const { toArray, map } = list
12
12
 
13
13
  /** @typedef {readonly[readonly string[], ToResult]} Result */
14
14
 
15
- /** @typedef {(a: number) => Result} ToResult */
15
+ /** @typedef {(codePoint: number) => Result} ToResult */
16
16
 
17
17
  /**
18
18
  * @template T
@@ -25,10 +25,10 @@ const { toArray, map } = list
25
25
  */
26
26
 
27
27
  /** @type {ToResult} */
28
- const unknownSymbol = a => [[`unknown symbol ${a}`], unknownSymbol]
28
+ const unexpectedSymbol = codePoint => [[`unexpected symbol ${codePoint}`], unexpectedSymbol]
29
29
 
30
- /** @type {<T>(a: T) => ToResult} */
31
- const def = () => unknownSymbol
30
+ /** @type {<T>(state: T) => ToResult} */
31
+ const def = () => unexpectedSymbol
32
32
 
33
33
  /** @type {<T>(a: CreateToResult<T>) => (b: CreateToResult<T>) => CreateToResult<T>} */
34
34
  const union = a => b => {
@@ -77,42 +77,46 @@ const create = a => {
77
77
 
78
78
  const terminal = -1
79
79
 
80
+ /** @type {() => ToResult} */
81
+ const toInit = () => () => [[], init]
82
+
80
83
  const init = create([
81
- codePointRange(one(terminal))(() => () => [[], unknownSymbol]),
82
- rangeSet(['\t', ' '])(() => () => [[' '], unknownSymbol]),
83
- rangeSet(['\n', '\r'])(() => () => [['\n'], unknownSymbol]),
84
- range('!')(() => () => [['!'], unknownSymbol]),
85
- range('"')(() => () => [['"'], unknownSymbol]),
86
- rangeSet(['$', '_', 'AZ', 'az'])(() => c => [[fromCharCode(c)], unknownSymbol]),
87
- range('%')(() => () => [['%'], unknownSymbol]),
88
- range('&')(() => () => [['&'], unknownSymbol]),
89
- range("'")(() => () => [["'"], unknownSymbol]),
90
- range('(')(() => () => [['('], unknownSymbol]),
91
- range(')')(() => () => [[')'], unknownSymbol]),
92
- range('*')(() => () => [['*'], unknownSymbol]),
93
- range('+')(() => () => [['+'], unknownSymbol]),
94
- range(',')(() => () => [[','], unknownSymbol]),
95
- range('-')(() => () => [['-'], unknownSymbol]),
96
- range('.')(() => () => [['.'], unknownSymbol]),
97
- range('/')(() => () => [['/'], unknownSymbol]),
98
- range('09')(() => a => [[fromCharCode(a)], unknownSymbol]),
99
- range(':')(() => () => [[':'], unknownSymbol]),
100
- range(';')(() => () => [[';'], unknownSymbol]),
101
- range('<')(() => () => [['<'], unknownSymbol]),
102
- range('=')(() => () => [['='], unknownSymbol]),
103
- range('>')(() => () => [['>'], unknownSymbol]),
104
- range('?')(() => () => [['?'], unknownSymbol]),
105
- range('[')(() => () => [['['], unknownSymbol]),
106
- range(']')(() => () => [[']'], unknownSymbol]),
107
- range('^')(() => () => [['^'], unknownSymbol]),
108
- range('`')(() => () => [['`'], unknownSymbol]),
109
- range('{')(() => () => [['{'], unknownSymbol]),
110
- range('|')(() => () => [['|'], unknownSymbol]),
111
- range('}')(() => () => [['}'], unknownSymbol]),
112
- range('~')(() => () => [['~'], unknownSymbol]),
113
- ])
84
+ codePointRange(one(terminal))(toInit),
85
+ rangeSet(['\t', ' ', '\n', '\r'])(toInit),
86
+ range('!')(() => () => [['!'], unexpectedSymbol]),
87
+ range('"')(() => () => [['"'], unexpectedSymbol]),
88
+ rangeSet(['$', '_', 'AZ', 'az'])(() => c => [[fromCharCode(c)], unexpectedSymbol]),
89
+ range('%')(() => () => [['%'], unexpectedSymbol]),
90
+ range('&')(() => () => [['&'], unexpectedSymbol]),
91
+ range("'")(() => () => [["'"], unexpectedSymbol]),
92
+ range('(')(() => () => [['('], unexpectedSymbol]),
93
+ range(')')(() => () => [[')'], unexpectedSymbol]),
94
+ range('*')(() => () => [['*'], unexpectedSymbol]),
95
+ range('+')(() => () => [['+'], unexpectedSymbol]),
96
+ range(',')(() => () => [[','], unexpectedSymbol]),
97
+ range('-')(() => () => [['-'], unexpectedSymbol]),
98
+ range('.')(() => () => [['.'], unexpectedSymbol]),
99
+ range('/')(() => () => [['/'], unexpectedSymbol]),
100
+ range('09')(() => a => [[fromCharCode(a)], unexpectedSymbol]),
101
+ range(':')(() => () => [[':'], unexpectedSymbol]),
102
+ range(';')(() => () => [[';'], unexpectedSymbol]),
103
+ range('<')(() => () => [['<'], unexpectedSymbol]),
104
+ range('=')(() => () => [['='], unexpectedSymbol]),
105
+ range('>')(() => () => [['>'], unexpectedSymbol]),
106
+ range('?')(() => () => [['?'], unexpectedSymbol]),
107
+ range('[')(() => () => [['['], unexpectedSymbol]),
108
+ range(']')(() => () => [[']'], unexpectedSymbol]),
109
+ range('^')(() => () => [['^'], unexpectedSymbol]),
110
+ range('`')(() => () => [['`'], unexpectedSymbol]),
111
+ range('{')(() => () => [['{'], unexpectedSymbol]),
112
+ range('|')(() => () => [['|'], unexpectedSymbol]),
113
+ range('}')(() => () => [['}'], unexpectedSymbol]),
114
+ range('~')(() => () => [['~'], unexpectedSymbol]),
115
+ ])(void 0)
114
116
 
115
117
  module.exports = {
118
+ /** @readonly */
119
+ terminal,
116
120
  /** @readonly */
117
121
  init,
118
122
  }
package/fsc/test.f.cjs CHANGED
@@ -6,7 +6,7 @@ const s = stringify(i => i)
6
6
  /** @type {(v: string) => string} */
7
7
  const f = v => {
8
8
  const n = one(v)
9
- return s(_.init(null)(n)[0])
9
+ return s(_.init(n)[0])
10
10
  }
11
11
 
12
12
  module.exports = {
@@ -0,0 +1,235 @@
1
+ const result = require('../../types/result/module.f.cjs')
2
+ const list = require('../../types/list/module.f.cjs')
3
+ const { fold, isEmpty, first, drop, toArray } = list
4
+ const operator = require('../../types/function/operator/module.f.cjs')
5
+ const tokenizer = require('../tokenizer/module.f.cjs')
6
+ const map = require('../../types/map/module.f.cjs')
7
+ const { entries, setReplace } = map
8
+
9
+
10
+ /**
11
+ * @typedef {{
12
+ * readonly kind: 'object'
13
+ * readonly values: map.Map<any>
14
+ * readonly key: string
15
+ * }} JsonObject
16
+ * */
17
+
18
+ /**
19
+ * @typedef {{
20
+ * readonly kind: 'array'
21
+ * readonly values: list.List<any>
22
+ * }} JsonArray
23
+ * */
24
+
25
+ /**
26
+ * @typedef {|
27
+ * JsonObject |
28
+ * JsonArray
29
+ * } JsonStackElement
30
+ */
31
+
32
+ /** @typedef {list.List<JsonStackElement>} JsonStack */
33
+
34
+ /**
35
+ * @typedef {{
36
+ * readonly status: '' | '[' | '[v' | '[,' | '{' | '{k' | '{:' | '{v' | '{,'
37
+ * readonly top: JsonStackElement | null
38
+ * readonly stack: JsonStack
39
+ * }} StateParse
40
+ */
41
+
42
+ /**
43
+ * @typedef {{
44
+ * readonly status: 'result'
45
+ * readonly value: any
46
+ * }} StateResult
47
+ */
48
+
49
+ /**
50
+ * @typedef {{
51
+ * readonly status: 'error'
52
+ * readonly message: string
53
+ * }} StateError
54
+ */
55
+
56
+ /**
57
+ * @typedef {|
58
+ * StateParse |
59
+ * StateResult |
60
+ * StateError
61
+ * } JsonState
62
+ */
63
+
64
+ /** @type {(obj: JsonObject) => (key: string) => JsonObject} */
65
+ const addKeyToObject = obj => key => ({ kind: 'object', values: obj.values, key: key })
66
+
67
+ /** @type {(obj: JsonObject) => (value: any) => JsonObject} */
68
+ const addValueToObject = obj => value => ({ kind: 'object', values: setReplace(obj.key)(value)(obj.values), key: '' })
69
+
70
+ /** @type {(array: JsonArray) => (value: any) => JsonArray} */
71
+ const addToArray = array => value => ({ kind: 'array', values: list.concat(array.values)([value]) })
72
+
73
+ /** @type {(state: StateParse) => (key: string) => JsonState} */
74
+ const pushKey = state => value => {
75
+ if (state.top?.kind === 'object') { return { status: '{k', top: addKeyToObject(state.top)(value), stack: state.stack } }
76
+ return { status: 'error', message: 'error' }
77
+ }
78
+
79
+ /** @type {(state: StateParse) => (value: any) => JsonState} */
80
+ const pushValue = state => value => {
81
+ if (state.top === null) { return { status: 'result', value: value }}
82
+ if (state.top.kind === 'array') { return { status: '[v', top: addToArray(state.top)(value), stack: state.stack } }
83
+ return { status: '{v', top: addValueToObject(state.top)(value), stack: state.stack }
84
+ }
85
+
86
+ /** @type {(state: StateParse) => JsonState} */
87
+ const startArray = state => {
88
+ const newStack = state.top === null ? null : { first: state.top, tail: state.stack }
89
+ return { status: '[', top: { kind: 'array', values: null }, stack: newStack }
90
+ }
91
+
92
+ /** @type {(state: StateParse) => JsonState} */
93
+ const endArray = state => {
94
+ const array = state.top !== null ? toArray(state.top.values) : null
95
+ /** @type {StateParse} */
96
+ const newState = { status: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
97
+ return pushValue(newState)(array)
98
+ }
99
+
100
+ /** @type {(state: StateParse) => JsonState} */
101
+ const startObject = state => {
102
+ const newStack = state.top === null ? null : { first: state.top, tail: state.stack }
103
+ return { status: '{', top: { kind: 'object', values: null, key: '' }, stack: newStack }
104
+ }
105
+
106
+ /** @type {operator.Fold<map.Entry<any>, any>} */
107
+ const foldToObjectOp = ([k, v]) => obj => { return { ...obj, [k] : v } }
108
+
109
+ /** @type {(m: map.Map<any>) => any} */
110
+ const toObject = m => {
111
+ const e = entries(m)
112
+ return fold(foldToObjectOp)({})(e)
113
+ }
114
+
115
+ /** @type {(state: StateParse) => JsonState} */
116
+ const endObject = state => {
117
+ const obj = state.top?.kind === 'object' ? toObject(state.top.values) : null
118
+ /** @type {StateParse} */
119
+ const newState = { status: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
120
+ return pushValue(newState)(obj)
121
+ }
122
+
123
+ /** @type {(token: tokenizer.JsonToken) => any} */
124
+ const tokenToValue = token => {
125
+ switch(token.kind) {
126
+ case 'null': return null
127
+ case 'false': return false
128
+ case 'true': return true
129
+ case 'number': return Number(token.value)
130
+ case 'string': return token.value
131
+ default: return null
132
+ }
133
+ }
134
+
135
+ /** @type {(token: tokenizer.JsonToken) => boolean} */
136
+ const isValueToken = token => {
137
+ switch(token.kind) {
138
+ case 'null':
139
+ case 'false':
140
+ case 'true':
141
+ case 'number':
142
+ case 'string': return true
143
+ default: return false
144
+ }
145
+ }
146
+
147
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
148
+ const parseValueOp = token => state => {
149
+ if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
150
+ if (token.kind === '[') { return startArray(state) }
151
+ if (token.kind === '{') { return startObject(state) }
152
+ return { status: 'error', message: 'unexpected token' }
153
+ }
154
+
155
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
156
+ const parseArrayStartOp = token => state => {
157
+ if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
158
+ if (token.kind === '[') { return startArray(state) }
159
+ if (token.kind === ']') { return endArray(state) }
160
+ if (token.kind === '{') { return startObject(state) }
161
+ return { status: 'error', message: 'unexpected token' }
162
+ }
163
+
164
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
165
+ const parseArrayValueOp = token => state => {
166
+ if (token.kind === ']') { return endArray(state) }
167
+ if (token.kind === ',') { return { status: '[,', top: state.top, stack: state.stack } }
168
+ return { status: 'error', message: 'unexpected token' }
169
+ }
170
+
171
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
172
+ const parseObjectStartOp = token => state => {
173
+ if (token.kind === 'string') { return pushKey(state)(token.value) }
174
+ if (token.kind === '}') { return endObject(state) }
175
+ return { status: 'error', message: 'unexpected token' }
176
+ }
177
+
178
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
179
+ const parseObjectKeyOp = token => state => {
180
+ if (token.kind === ':') { return { status: '{:', top: state.top, stack: state.stack } }
181
+ return { status: 'error', message: 'unexpected token' }
182
+ }
183
+
184
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
185
+ const parseObjectColonOp = token => state => {
186
+ if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
187
+ if (token.kind === '[') { return startArray(state) }
188
+ if (token.kind === '{') { return startObject(state) }
189
+ return { status: 'error', message: 'unexpected token' }
190
+ }
191
+
192
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
193
+ const parseObjectNextOp = token => state => {
194
+ if (token.kind === '}') { return endObject(state) }
195
+ if (token.kind === ',') { return { status: '{,', top: state.top, stack: state.stack } }
196
+ return { status: 'error', message: 'unexpected token' }
197
+ }
198
+
199
+ /** @type {(token: tokenizer.JsonToken) => (state: StateParse) => JsonState}} */
200
+ const parseObjectCommaOp = token => state => {
201
+ if (token.kind === 'string') { return pushKey(state)(token.value) }
202
+ return { status: 'error', message: 'unexpected token' }
203
+ }
204
+
205
+ /** @type {operator.Fold<tokenizer.JsonToken, JsonState>} */
206
+ const foldOp = token => state => {
207
+ switch(state.status) {
208
+ case 'result': return { status: 'error', message: 'unexpected token' }
209
+ case 'error': return { status: 'error', message: state.message }
210
+ case '': return parseValueOp(token)(state)
211
+ case '[': return parseArrayStartOp(token)(state)
212
+ case '[v': return parseArrayValueOp(token)(state)
213
+ case '[,': return parseValueOp(token)(state)
214
+ case '{' : return parseObjectStartOp(token)(state)
215
+ case '{k' : return parseObjectKeyOp(token)(state)
216
+ case '{:' : return parseObjectColonOp(token)(state)
217
+ case '{v' : return parseObjectNextOp(token)(state)
218
+ case '{,' : return parseObjectCommaOp(token)(state)
219
+ }
220
+ }
221
+
222
+ /** @type {(tokenList: list.List<tokenizer.JsonToken>) => result.Result<any, string>} */
223
+ const parse = tokenList => {
224
+ const state = fold(foldOp)({ status: '', top: null, stack: null })(tokenList)
225
+ switch(state.status) {
226
+ case 'result': return result.ok(state.value)
227
+ case 'error': return result.error(state.message)
228
+ default: return result.error('unexpected end')
229
+ }
230
+ }
231
+
232
+ module.exports = {
233
+ /** @readonly */
234
+ parse
235
+ }
@@ -0,0 +1,240 @@
1
+ const parser = require('./module.f.cjs')
2
+ const tokenizer = require('../tokenizer/module.f.cjs')
3
+ const { toArray } = require('../../types/list/module.f.cjs')
4
+ const json = require('../module.f.cjs')
5
+ const { sort } = require('../../types/object/module.f.cjs')
6
+ const encoding = require('../../text/utf16/module.f.cjs');
7
+
8
+ /** @type {(s: string) => readonly tokenizer.JsonToken[]} */
9
+ const tokenizeString = s => toArray(tokenizer.tokenize(encoding.stringToList(s)))
10
+
11
+ const stringify = json.stringify(sort)
12
+
13
+ module.exports = {
14
+ valud: [
15
+ () => {
16
+ const tokenList = tokenizeString('null')
17
+ const obj = parser.parse(tokenList)
18
+ const result = stringify(obj)
19
+ if (result !== '["ok",null]') { throw result }
20
+ },
21
+ () => {
22
+ const tokenList = tokenizeString('true')
23
+ const obj = parser.parse(tokenList)
24
+ const result = stringify(obj)
25
+ if (result !== '["ok",true]') { throw result }
26
+ },
27
+ () => {
28
+ const tokenList = tokenizeString('false')
29
+ const obj = parser.parse(tokenList)
30
+ const result = stringify(obj)
31
+ if (result !== '["ok",false]') { throw result }
32
+ },
33
+ () => {
34
+ const tokenList = tokenizeString('0.1')
35
+ const obj = parser.parse(tokenList)
36
+ const result = stringify(obj)
37
+ if (result !== '["ok",0.1]') { throw result }
38
+ },
39
+ () => {
40
+ const tokenList = tokenizeString('1.1e+2')
41
+ const obj = parser.parse(tokenList)
42
+ const result = stringify(obj)
43
+ if (result !== '["ok",110]') { throw result }
44
+ },
45
+ () => {
46
+ const tokenList = tokenizeString('"abc"')
47
+ const obj = parser.parse(tokenList)
48
+ const result = stringify(obj)
49
+ if (result !== '["ok","abc"]') { throw result }
50
+ },
51
+ () => {
52
+ const tokenList = tokenizeString('[]')
53
+ const obj = parser.parse(tokenList)
54
+ const result = stringify(obj)
55
+ if (result !== '["ok",[]]') { throw result }
56
+ },
57
+ () => {
58
+ const tokenList = tokenizeString('[1]')
59
+ const obj = parser.parse(tokenList)
60
+ const result = stringify(obj)
61
+ if (result !== '["ok",[1]]') { throw result }
62
+ },
63
+ () => {
64
+ const tokenList = tokenizeString('[[]]')
65
+ const obj = parser.parse(tokenList)
66
+ const result = stringify(obj)
67
+ if (result !== '["ok",[[]]]') { throw result }
68
+ },
69
+ () => {
70
+ const tokenList = tokenizeString('[0,[1,[2,[]]],3]')
71
+ const obj = parser.parse(tokenList)
72
+ const result = stringify(obj)
73
+ if (result !== '["ok",[0,[1,[2,[]]],3]]') { throw result }
74
+ },
75
+ () => {
76
+ const tokenList = tokenizeString('{}')
77
+ const obj = parser.parse(tokenList)
78
+ const result = stringify(obj)
79
+ if (result !== '["ok",{}]') { throw result }
80
+ },
81
+ () => {
82
+ const tokenList = tokenizeString('[{}]')
83
+ const obj = parser.parse(tokenList)
84
+ const result = stringify(obj)
85
+ if (result !== '["ok",[{}]]') { throw result }
86
+ },
87
+ () => {
88
+ const tokenList = tokenizeString('{"a":true,"b":false,"c":null}')
89
+ const obj = parser.parse(tokenList)
90
+ const result = stringify(obj)
91
+ if (result !== '["ok",{"a":true,"b":false,"c":null}]') { throw result }
92
+ },
93
+ () => {
94
+ const tokenList = tokenizeString('{"a":{"b":{"c":["d"]}}}')
95
+ const obj = parser.parse(tokenList)
96
+ const result = stringify(obj)
97
+ if (result !== '["ok",{"a":{"b":{"c":["d"]}}}]') { throw result }
98
+ },
99
+ ],
100
+ invalid: [
101
+ () => {
102
+ const tokenList = tokenizeString('')
103
+ const obj = parser.parse(tokenList)
104
+ const result = stringify(obj)
105
+ if (result !== '["error","unexpected end"]') { throw result }
106
+ },
107
+ () => {
108
+ const tokenList = tokenizeString('"123')
109
+ const obj = parser.parse(tokenList)
110
+ const result = stringify(obj)
111
+ if (result !== '["error","unexpected token"]') { throw result }
112
+ },
113
+ () => {
114
+ const tokenList = tokenizeString('[,]')
115
+ const obj = parser.parse(tokenList)
116
+ const result = stringify(obj)
117
+ if (result !== '["error","unexpected token"]') { throw result }
118
+ },
119
+ () => {
120
+ const tokenList = tokenizeString('[1 2]')
121
+ const obj = parser.parse(tokenList)
122
+ const result = stringify(obj)
123
+ if (result !== '["error","unexpected token"]') { throw result }
124
+ },
125
+ () => {
126
+ const tokenList = tokenizeString('[1,,2]')
127
+ const obj = parser.parse(tokenList)
128
+ const result = stringify(obj)
129
+ if (result !== '["error","unexpected token"]') { throw result }
130
+ },
131
+ () => {
132
+ const tokenList = tokenizeString('[]]')
133
+ const obj = parser.parse(tokenList)
134
+ const result = stringify(obj)
135
+ if (result !== '["error","unexpected token"]') { throw result }
136
+ },
137
+ () => {
138
+ const tokenList = tokenizeString('["a"')
139
+ const obj = parser.parse(tokenList)
140
+ const result = stringify(obj)
141
+ if (result !== '["error","unexpected end"]') { throw result }
142
+ },
143
+ () => {
144
+ const tokenList = tokenizeString('[1,]')
145
+ const obj = parser.parse(tokenList)
146
+ const result = stringify(obj)
147
+ if (result !== '["error","unexpected token"]') { throw result }
148
+ },
149
+ () => {
150
+ const tokenList = tokenizeString('[,1]')
151
+ const obj = parser.parse(tokenList)
152
+ const result = stringify(obj)
153
+ if (result !== '["error","unexpected token"]') { throw result }
154
+ },
155
+ () => {
156
+ const tokenList = tokenizeString('[:]')
157
+ const obj = parser.parse(tokenList)
158
+ const result = stringify(obj)
159
+ if (result !== '["error","unexpected token"]') { throw result }
160
+ },
161
+ () => {
162
+ const tokenList = tokenizeString(']')
163
+ const obj = parser.parse(tokenList)
164
+ const result = stringify(obj)
165
+ if (result !== '["error","unexpected token"]') { throw result }
166
+ },
167
+ () => {
168
+ const tokenList = tokenizeString('{,}')
169
+ const obj = parser.parse(tokenList)
170
+ const result = stringify(obj)
171
+ if (result !== '["error","unexpected token"]') { throw result }
172
+ },
173
+ () => {
174
+ const tokenList = tokenizeString('{1:2}')
175
+ const obj = parser.parse(tokenList)
176
+ const result = stringify(obj)
177
+ if (result !== '["error","unexpected token"]') { throw result }
178
+ },
179
+ () => {
180
+ const tokenList = tokenizeString('{"1"2}')
181
+ const obj = parser.parse(tokenList)
182
+ const result = stringify(obj)
183
+ if (result !== '["error","unexpected token"]') { throw result }
184
+ },
185
+ () => {
186
+ const tokenList = tokenizeString('{"1"::2}')
187
+ const obj = parser.parse(tokenList)
188
+ const result = stringify(obj)
189
+ if (result !== '["error","unexpected token"]') { throw result }
190
+ },
191
+ () => {
192
+ const tokenList = tokenizeString('{"1":2,,"3":4')
193
+ const obj = parser.parse(tokenList)
194
+ const result = stringify(obj)
195
+ if (result !== '["error","unexpected token"]') { throw result }
196
+ },
197
+ () => {
198
+ const tokenList = tokenizeString('{}}')
199
+ const obj = parser.parse(tokenList)
200
+ const result = stringify(obj)
201
+ if (result !== '["error","unexpected token"]') { throw result }
202
+ },
203
+ () => {
204
+ const tokenList = tokenizeString('{"1":2')
205
+ const obj = parser.parse(tokenList)
206
+ const result = stringify(obj)
207
+ if (result !== '["error","unexpected end"]') { throw result }
208
+ },
209
+ () => {
210
+ const tokenList = tokenizeString('{"1":2,}')
211
+ const obj = parser.parse(tokenList)
212
+ const result = stringify(obj)
213
+ if (result !== '["error","unexpected token"]') { throw result }
214
+ },
215
+ () => {
216
+ const tokenList = tokenizeString('{,"1":2}')
217
+ const obj = parser.parse(tokenList)
218
+ const result = stringify(obj)
219
+ if (result !== '["error","unexpected token"]') { throw result }
220
+ },
221
+ () => {
222
+ const tokenList = tokenizeString('}')
223
+ const obj = parser.parse(tokenList)
224
+ const result = stringify(obj)
225
+ if (result !== '["error","unexpected token"]') { throw result }
226
+ },
227
+ () => {
228
+ const tokenList = tokenizeString('[{]}')
229
+ const obj = parser.parse(tokenList)
230
+ const result = stringify(obj)
231
+ if (result !== '["error","unexpected token"]') { throw result }
232
+ },
233
+ () => {
234
+ const tokenList = tokenizeString('{[}]')
235
+ const obj = parser.parse(tokenList)
236
+ const result = stringify(obj)
237
+ if (result !== '["error","unexpected token"]') { throw result }
238
+ },
239
+ ]
240
+ }
@@ -84,7 +84,7 @@ const rangeSetWhiteSpace = [
84
84
  one(space)
85
85
  ]
86
86
 
87
- const rangeSetTerminalForNumer = [
87
+ const rangeSetTerminalForNumber = [
88
88
  one(ht),
89
89
  one(lf),
90
90
  one(cr),
@@ -134,15 +134,22 @@ const rangeCapitalAF = range('AF')
134
134
 
135
135
  /** @typedef {{ readonly kind: 'escapeChar', readonly value: string}} ParseEscapeCharState */
136
136
 
137
- /** @typedef {{ readonly kind: 'unicodeChar', readonly value: string, readonly unicode: number, readonly hexIndex: number}} ParseUnicodeCharState */
137
+ /**
138
+ * @typedef {{
139
+ * readonly kind: 'unicodeChar'
140
+ * readonly value: string
141
+ * readonly unicode: number
142
+ * readonly hexIndex: number
143
+ * }} ParseUnicodeCharState
144
+ */
138
145
 
139
146
  /**
140
- * @typedef {{
141
- * readonly kind: 'number',
142
- * readonly numberKind: '0' | '-' | 'int' | '.' | 'fractional' | 'e' | 'e+' | 'e-' | 'expDigits'
143
- * readonly value: string
147
+ * @typedef {{
148
+ * readonly kind: 'number',
149
+ * readonly numberKind: '0' | '-' | 'int' | '.' | 'fractional' | 'e' | 'e+' | 'e-' | 'expDigits'
150
+ * readonly value: string
144
151
  * }} ParseNumberState
145
- * */
152
+ */
146
153
 
147
154
  /** @typedef {{ readonly kind: 'invalidNumber'}} InvalidNumberState */
148
155
 
@@ -323,12 +330,12 @@ const parseNumberStateOp = create(invalidNumberToToken)([
323
330
  rangeSetFunc([one(latinSmallLetterE), one(latinCapitalLetterE)])(expToToken),
324
331
  rangeFunc(one(hyphenMinus))(hyphenMinusToToken),
325
332
  rangeFunc(one(plusSign))(plusSignToToken),
326
- rangeSetFunc(rangeSetTerminalForNumer)(terminalToToken)
333
+ rangeSetFunc(rangeSetTerminalForNumber)(terminalToToken)
327
334
  ])
328
335
 
329
336
  /** @type {(state: InvalidNumberState) => (input: number) => readonly[list.List<JsonToken>, TokenizerState]} */
330
337
  const invalidNumberStateOp = create(() => () => [empty, { kind: 'invalidNumber' }])([
331
- rangeSetFunc(rangeSetTerminalForNumer)(() => input => {
338
+ rangeSetFunc(rangeSetTerminalForNumber)(() => input => {
332
339
  const next = tokenizeOp({ kind: 'initial' })(input)
333
340
  return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
334
341
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.497",
3
+ "version": "0.0.499",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "homepage": "https://github.com/functionalscript/functionalscript#readme",
32
32
  "devDependencies": {
33
- "@types/node": "^18.11.15",
33
+ "@types/node": "^18.11.18",
34
34
  "typescript": "^4.9.4"
35
35
  }
36
36
  }