functionalscript 0.1.607 → 0.1.609

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/Cargo.lock +4 -0
  3. package/Cargo.toml +4 -2
  4. package/README.md +1 -1
  5. package/com/rust/nanocom/src/cobject.rs +1 -1
  6. package/com/test/rust/src/lib.rs +4 -4
  7. package/dev/module.mjs +10 -33
  8. package/dev/test/module.f.mjs +1 -1
  9. package/djs/parser/module.f.d.mts +51 -31
  10. package/djs/parser/module.f.mjs +275 -122
  11. package/djs/parser/test.f.d.mts +4 -0
  12. package/djs/parser/test.f.mjs +179 -63
  13. package/djs/tokenizer/module.f.d.mts +1 -1
  14. package/djs/tokenizer/module.f.mjs +3 -1
  15. package/djs/tokenizer/test.f.mjs +1 -1
  16. package/doc/LANGUAGE.md +17 -16
  17. package/doc/README.md +14 -50
  18. package/fsc/README.md +0 -3
  19. package/fsm/README.md +1 -1
  20. package/html/README.md +24 -0
  21. package/issues/01-test-debug.md +3 -0
  22. package/issues/{publish.md → 05-publish.md} +8 -8
  23. package/issues/17-djs-extension.md +6 -0
  24. package/issues/README.md +20 -13
  25. package/issues/lang/1000-json.md +38 -0
  26. package/issues/lang/2110-default-export.md +2 -2
  27. package/issues/lang/2310-undefined.md +1 -1
  28. package/issues/lang/2330-property-accessor.md +225 -0
  29. package/issues/lang/2360-built-in.md +54 -47
  30. package/issues/lang/3240-export.md +44 -0
  31. package/issues/lang/README.md +64 -22
  32. package/issues/test.f.d.mts +16 -0
  33. package/issues/test.f.mjs +57 -0
  34. package/js/tokenizer/module.f.d.mts +8 -2
  35. package/js/tokenizer/module.f.mjs +29 -3
  36. package/js/tokenizer/test.f.mjs +9 -6
  37. package/json/tokenizer/module.f.mjs +2 -1
  38. package/jsr.json +1 -1
  39. package/nanvm-lib/Cargo.toml +6 -0
  40. package/nanvm-lib/src/extension.rs +119 -0
  41. package/nanvm-lib/src/interface.rs +136 -0
  42. package/nanvm-lib/src/lib.rs +7 -0
  43. package/nanvm-lib/src/naive.rs +229 -0
  44. package/nanvm-lib/src/nanenum.rs +230 -0
  45. package/nanvm-lib/src/nullish.rs +7 -0
  46. package/nanvm-lib/src/sign.rs +5 -0
  47. package/nanvm-lib/src/simple.rs +32 -0
  48. package/nanvm-lib/tests/test.f.d.mts +36 -0
  49. package/nanvm-lib/tests/test.f.mjs +79 -0
  50. package/nanvm-lib/tests/test.rs +108 -0
  51. package/package.json +1 -2
  52. package/text/README.md +2 -2
  53. package/index.f.d.mts +0 -83
  54. package/index.f.mjs +0 -83
  55. package/issues/lang/2351-property-accessor.md +0 -44
  56. package/issues/lang/2352-property-call.md +0 -43
  57. package/issues/lang/2353-property-at.md +0 -19
  58. package/issues/test-debug.md +0 -12
  59. /package/issues/{esm.md → 02-esm.md} +0 -0
  60. /package/issues/{djs.md → 03-djs.md} +0 -0
  61. /package/issues/{fs-load.md → 11-fs-load.md} +0 -0
  62. /package/issues/lang/{2330-grouping.md → 2350-grouping.md} +0 -0
@@ -2,156 +2,291 @@
2
2
 
3
3
  import result, * as Result from '../../types/result/module.f.mjs'
4
4
  import list, * as List from '../../types/list/module.f.mjs'
5
- const { fold, first, drop, toArray } = list
5
+ const { fold, first, drop, toArray, map: listMap, length } = list
6
6
  import * as Operator from '../../types/function/operator/module.f.mjs'
7
7
  import * as tokenizerT from '../tokenizer/module.f.mjs'
8
8
  import map, * as Map from '../../types/map/module.f.mjs'
9
- const { setReplace } = map
10
- import * as Djs from '../module.f.mjs'
11
- import o from '../../types/object/module.f.mjs'
9
+ const { setReplace, at } = map
10
+ import o, * as O from '../../types/object/module.f.mjs'
12
11
  const { fromMap } = o
13
12
 
13
+ /** @typedef {[readonly string[], readonly DjsConst[]] } DjsModule */
14
+
15
+ /** @typedef {boolean|string|number|null|bigint|DjsModuleRef|DjsArray|DjsObject} DjsConst */
16
+
17
+ /** @typedef {['aref' | 'cref', number]} DjsModuleRef */
18
+
19
+ /** @typedef {['array', readonly DjsConst[]]} DjsArray */
20
+
14
21
  /**
15
22
  * @typedef {{
16
- * readonly kind: 'object'
17
- * readonly values: Map.Map<Djs.Unknown>
18
- * readonly key: string
19
- * }} JsonObject
20
- * */
23
+ * readonly [k in string]: DjsConst
24
+ * }} DjsObject
25
+ */
26
+
27
+ /** @typedef {['array', List.List<DjsConst>]} DjsStackArray */
28
+
29
+ /** @typedef {['object', Map.Map<DjsConst>, string]} DjsStackObject */
30
+
31
+
32
+ /**
33
+ * @typedef {|
34
+ * DjsStackArray |
35
+ * DjsStackObject
36
+ * } DjsStackElement
37
+ */
38
+
39
+ /** @typedef {List.List<DjsStackElement>} DjsStack */
40
+
41
+ /** @typedef {InitialState | NewLineRequiredState | ImportState | ConstState | ExportState | ParseValueState | ResultState | ErrorState} ParserState */
21
42
 
22
43
  /**
23
44
  * @typedef {{
24
- * readonly kind: 'array'
25
- * readonly values: List.List<Djs.Unknown>
26
- * }} JsonArray
27
- * */
45
+ * readonly refs: Map.Map<DjsModuleRef>
46
+ * readonly modules: List.List<string>
47
+ * readonly consts: List.List<DjsConst>
48
+ * }} ModuleState
49
+ */
28
50
 
29
51
  /**
30
- * @typedef {|
31
- * JsonObject |
32
- * JsonArray
33
- * } JsonStackElement
52
+ * @typedef {{
53
+ * readonly state: ''
54
+ * readonly module: ModuleState
55
+ * }} InitialState
34
56
  */
35
57
 
36
- /** @typedef {List.List<JsonStackElement>} JsonStack */
58
+ /**
59
+ * @typedef {{
60
+ * readonly state: 'nl'
61
+ * readonly module: ModuleState
62
+ * }} NewLineRequiredState
63
+ */
37
64
 
38
65
  /**
39
66
  * @typedef {{
40
- * readonly status: 'module'
41
- * readonly stage: 'module' | '.' | 'exports' | '='
42
- * }} StateModule
67
+ * readonly state: 'import' | 'import+name' | 'import+from'
68
+ * readonly module: ModuleState
69
+ * }} ImportState
43
70
  */
44
71
 
45
72
  /**
46
73
  * @typedef {{
47
- * readonly status: '' | '[' | '[v' | '[,' | '{' | '{k' | '{:' | '{v' | '{,'
48
- * readonly top: JsonStackElement | null
49
- * readonly stack: JsonStack
50
- * }} StateParse
74
+ * readonly state: 'const' | 'const+name'
75
+ * readonly module: ModuleState
76
+ * }} ConstState
51
77
  */
52
78
 
53
79
  /**
54
80
  * @typedef {{
55
- * readonly status: 'result'
56
- * readonly value: Djs.Unknown
57
- * }} StateResult
81
+ * readonly state: 'export'
82
+ * readonly module: ModuleState
83
+ * }} ExportState
58
84
  */
59
85
 
60
86
  /**
61
87
  * @typedef {{
62
- * readonly status: 'error'
63
- * readonly message: string
64
- * }} StateError
88
+ * readonly state: 'constValue' | 'exportValue'
89
+ * readonly module: ModuleState
90
+ * readonly valueState: '' | '[' | '[v' | '[,' | '{' | '{k' | '{:' | '{v' | '{,'
91
+ * readonly top: DjsStackElement | null
92
+ * readonly stack: DjsStack
93
+ * }} ParseValueState
65
94
  */
66
95
 
67
96
  /**
68
- * @typedef {|
69
- * StateModule |
70
- * StateParse |
71
- * StateResult |
72
- * StateError
73
- * } DjsState
97
+ * @typedef {{
98
+ * readonly state: 'result'
99
+ * readonly module: ModuleState
100
+ * }} ResultState
101
+ */
102
+
103
+ /**
104
+ * @typedef {{
105
+ * readonly state: 'error'
106
+ * readonly message: string
107
+ * }} ErrorState
74
108
  */
75
109
 
76
- /** @type {(token: tokenizerT.DjsToken) => (state: StateModule) => DjsState}} */
77
- const parseModuleOp = token => state => {
78
- switch(state.stage)
110
+
111
+ /** @type {(token: tokenizerT.DjsToken) => (state: InitialState) => ParserState}} */
112
+ const parseInitialOp = token => state => {
113
+ switch (token.kind)
79
114
  {
80
- case 'module':
81
- {
82
- if (token.kind === 'id' && token.value === 'module') return { status: 'module', stage: '.' }
83
- break;
115
+ case 'ws':
116
+ case 'nl': return state
117
+ case 'id': {
118
+ switch (token.value) {
119
+ case 'import': return { ... state, state: 'import' }
120
+ case 'const': return { ... state, state: 'const' }
121
+ case 'export': return { ... state, state: 'export' }
122
+ }
84
123
  }
85
- case '.':
86
- {
87
- if (token.kind === '.') return { status: 'module', stage: 'exports' }
88
- break;
124
+ }
125
+ return { state: 'error', message: 'unexpected token' }
126
+ }
127
+
128
+ /** @type {(token: tokenizerT.DjsToken) => (state: NewLineRequiredState) => ParserState}} */
129
+ const parseNewLineRequiredOp = token => state => {
130
+ switch (token.kind) {
131
+ case 'ws': return state
132
+ case 'nl': return { ... state, state: '' }
133
+ default: return { state: 'error', message: 'unexpected token' }
134
+ }
135
+ }
136
+
137
+ /** @type {(token: tokenizerT.DjsToken) => (state: ExportState) => ParserState}} */
138
+ const parseExportOp = token => state => {
139
+ switch (token.kind) {
140
+ case 'ws':
141
+ case 'nl': return state
142
+ case 'id': {
143
+ if (token.value === 'default') return { ... state, state: 'exportValue', valueState: '', top: null, stack: null }
89
144
  }
90
- case 'exports':
91
- {
92
- if (token.kind === 'id' && token.value === 'exports') return { status: 'module', stage: '=' }
93
- break;
145
+ }
146
+ return { state: 'error', message: 'unexpected token' }
147
+ }
148
+
149
+ /** @type {(token: tokenizerT.DjsToken) => (state: ConstState) => ParserState}} */
150
+ const parseConstOp = token => state => {
151
+ switch (token.kind) {
152
+ case 'ws':
153
+ case 'nl': return state
154
+ case 'id': {
155
+ if (map.at(token.value)(state.module.refs) !== null)
156
+ return { state: 'error', message: 'duplicate id' }
157
+ /** @type {DjsModuleRef} */
158
+ let cref = ['cref', length(state.module.consts)]
159
+ let refs = map.setReplace(token.value)(cref)(state.module.refs)
160
+ return { ... state, state: 'const+name', module: { ...state.module, refs: refs } }
94
161
  }
95
- case '=':
96
- {
97
- if (token.kind === '=') return { status: '', top: null, stack: null }
98
- if (token.kind === 'ws') return state
162
+ default: return { state: 'error', message: 'unexpected token' }
163
+ }
164
+ }
165
+
166
+ /** @type {(token: tokenizerT.DjsToken) => (state: ConstState) => ParserState}} */
167
+ const parseConstNameOp = token => state => {
168
+ switch (token.kind) {
169
+ case 'ws':
170
+ case 'nl': return state
171
+ case '=': return { ... state, state: 'constValue', valueState: '', top: null, stack: null }
172
+ default: return { state: 'error', message: 'unexpected token' }
173
+ }
174
+ }
175
+
176
+ /** @type {(token: tokenizerT.DjsToken) => (state: ImportState) => ParserState}} */
177
+ const parseImportOp = token => state => {
178
+ switch (token.kind) {
179
+ case 'ws':
180
+ case 'nl': return state
181
+ case 'id': {
182
+ if (map.at(token.value)(state.module.refs) !== null)
183
+ return { state: 'error', message: 'duplicate id' }
184
+ /** @type {DjsModuleRef} */
185
+ let aref = ['aref', length(state.module.modules)]
186
+ let refs = map.setReplace(token.value)(aref)(state.module.refs)
187
+ return { ... state, state: 'import+name', module: { ...state.module, refs: refs } }
188
+ }
189
+ default: return { state: 'error', message: 'unexpected token' }
190
+ }
191
+ }
192
+
193
+ /** @type {(token: tokenizerT.DjsToken) => (state: ImportState) => ParserState}} */
194
+ const parseImportNameOp = token => state => {
195
+ switch (token.kind) {
196
+ case 'ws':
197
+ case 'nl': return state
198
+ case 'id': {
199
+ if (token.value === 'from') return { ... state, state: 'import+from' }
99
200
  }
100
201
  }
101
- return { status: 'error', message: 'unexpected token' }
202
+ return { state: 'error', message: 'unexpected token' }
102
203
  }
103
204
 
104
- /** @type {(obj: JsonObject) => (key: string) => JsonObject} */
105
- const addKeyToObject = obj => key => ({ kind: 'object', values: obj.values, key: key })
205
+ /** @type {(token: tokenizerT.DjsToken) => (state: ImportState) => ParserState}} */
206
+ const parseImportFromOp = token => state => {
207
+ switch (token.kind) {
208
+ case 'ws':
209
+ case 'nl': return state
210
+ case 'string': {
211
+ const modules = list.concat(state.module.modules)([token.value])
212
+ return { ... state, state: 'nl', module: { ...state.module, modules: modules } }
213
+ }
214
+ default: return { state: 'error', message: 'unexpected token' }
215
+ }
216
+ }
106
217
 
107
- /** @type {(obj: JsonObject) => (value: Djs.Unknown) => JsonObject} */
108
- const addValueToObject = obj => value => ({ kind: 'object', values: setReplace(obj.key)(value)(obj.values), key: '' })
218
+ /** @type {(obj: DjsStackObject) => (key: string) => DjsStackObject} */
219
+ const addKeyToObject = obj => key => ([ 'object', obj[1], key])
109
220
 
110
- /** @type {(array: JsonArray) => (value: Djs.Unknown) => JsonArray} */
111
- const addToArray = array => value => ({ kind: 'array', values: list.concat(array.values)([value]) })
221
+ /** @type {(obj: DjsStackObject) => (value: DjsConst) => DjsStackObject} */
222
+ const addValueToObject = obj => value => ([ 'object', setReplace(obj[2])(value)(obj[1]), '' ])
112
223
 
113
- /** @type {(state: StateParse) => (key: string) => DjsState} */
114
- const pushKey = state => value => {
115
- if (state.top?.kind === 'object') { return { status: '{k', top: addKeyToObject(state.top)(value), stack: state.stack } }
116
- return { status: 'error', message: 'error' }
224
+ /** @type {(array: DjsStackArray) => (value: DjsConst) => DjsStackArray} */
225
+ const addToArray = array => value => ([ 'array', list.concat(array[1])([value]) ])
226
+
227
+ /** @type {(state: ParseValueState) => (key: string) => ParserState} */
228
+ const pushKey = state => key => {
229
+ if (state.top?.[0] === 'object') { return { ... state, valueState: '{k', top: addKeyToObject(state.top)(key), stack: state.stack } }
230
+ return { state: 'error', message: 'error' }
117
231
  }
118
232
 
119
- /** @type {(state: StateParse) => (value: Djs.Unknown) => DjsState} */
233
+ /** @type {(state: ParseValueState) => (value: DjsConst) => ParserState} */
120
234
  const pushValue = state => value => {
121
- if (state.top === null) { return { status: 'result', value: value } }
122
- if (state.top.kind === 'array') { return { status: '[v', top: addToArray(state.top)(value), stack: state.stack } }
123
- return { status: '{v', top: addValueToObject(state.top)(value), stack: state.stack }
235
+ if (state.top === null) {
236
+ let consts = list.concat(state.module.consts)([value])
237
+ switch(state.state)
238
+ {
239
+ case 'exportValue': return { ... state, state: 'result', module: { ...state.module, consts: consts }}
240
+ case 'constValue': return { ... state, state: 'nl', module: { ...state.module, consts: consts }}
241
+ }
242
+ }
243
+ if (state.top?.[0] === 'array') { return { ... state, valueState: '[v', top: addToArray(state.top)(value), stack: state.stack } }
244
+ return { ... state, valueState: '{v', top: addValueToObject(state.top)(value), stack: state.stack }
124
245
  }
125
246
 
126
- /** @type {(state: StateParse) => DjsState} */
247
+ /** @type {(state: ParseValueState) => (name: string) => ParserState} */
248
+ const pushRef = state => name => {
249
+ const ref = at(name)(state.module.refs)
250
+ if (ref === null)
251
+ return { state: 'error', message: 'const not found' }
252
+ return pushValue(state)(ref)
253
+ }
254
+
255
+ /** @type {(state: ParseValueState) => ParserState} */
127
256
  const startArray = state => {
128
257
  const newStack = state.top === null ? null : { first: state.top, tail: state.stack }
129
- return { status: '[', top: { kind: 'array', values: null }, stack: newStack }
258
+ return { ... state, valueState: '[', top: ['array', null ], stack: newStack }
130
259
  }
131
260
 
132
- /** @type {(state: StateParse) => DjsState} */
261
+ /** @type {(state: ParseValueState) => ParserState} */
133
262
  const endArray = state => {
134
- const array = state.top !== null ? toArray(state.top.values) : null
135
- /** @type {StateParse} */
136
- const newState = { status: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
137
- return pushValue(newState)(array)
263
+ const top = state.top;
264
+ /** @type {ParseValueState} */
265
+ const newState = { ... state, valueState: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
266
+ if (top !== null && top[0] === 'array')
267
+ {
268
+ /** @type {DjsArray} */
269
+ const array = ['array', toArray(top[1])];
270
+ return pushValue(newState)(array)
271
+ }
272
+ return pushValue(newState)(null)
138
273
  }
139
274
 
140
- /** @type {(state: StateParse) => DjsState} */
275
+ /** @type {(state: ParseValueState) => ParserState} */
141
276
  const startObject = state => {
142
277
  const newStack = state.top === null ? null : { first: state.top, tail: state.stack }
143
- return { status: '{', top: { kind: 'object', values: null, key: '' }, stack: newStack }
278
+ return { ... state, valueState: '{', top: ['object', null, ''], stack: newStack }
144
279
  }
145
280
 
146
- /** @type {(state: StateParse) => DjsState} */
281
+ /** @type {(state: ParseValueState) => ParserState} */
147
282
  const endObject = state => {
148
- const obj = state.top?.kind === 'object' ? fromMap(state.top.values) : null
149
- /** @type {StateParse} */
150
- const newState = { status: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
283
+ const obj = state?.top !== null && state?.top[0] === 'object' ? fromMap(state.top[1]) : null;
284
+ /** @type {ParseValueState} */
285
+ const newState = { ... state, valueState: '', top: first(null)(state.stack), stack: drop(1)(state.stack) }
151
286
  return pushValue(newState)(obj)
152
287
  }
153
288
 
154
- /** @type {(token: tokenizerT.DjsToken) => Djs.Unknown} */
289
+ /** @type {(token: tokenizerT.DjsToken) => DjsConst} */
155
290
  const tokenToValue = token => {
156
291
  switch (token.kind) {
157
292
  case 'null': return null
@@ -177,100 +312,118 @@ const isValueToken = token => {
177
312
  }
178
313
  }
179
314
 
180
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
315
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
181
316
  const parseValueOp = token => state => {
182
317
  if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
318
+ if (token.kind === 'id') { return pushRef(state)(token.value) }
183
319
  if (token.kind === '[') { return startArray(state) }
184
320
  if (token.kind === '{') { return startObject(state) }
185
321
  if (token.kind === 'ws') { return state }
186
- return { status: 'error', message: 'unexpected token' }
322
+ return { state: 'error', message: 'unexpected token' }
187
323
  }
188
324
 
189
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
325
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
190
326
  const parseArrayStartOp = token => state => {
191
327
  if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
328
+ if (token.kind === 'id') { return pushRef(state)(token.value) }
192
329
  if (token.kind === '[') { return startArray(state) }
193
330
  if (token.kind === ']') { return endArray(state) }
194
331
  if (token.kind === '{') { return startObject(state) }
195
332
  if (token.kind === 'ws') { return state }
196
- return { status: 'error', message: 'unexpected token' }
333
+ return { state: 'error', message: 'unexpected token' }
197
334
  }
198
335
 
199
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
336
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
200
337
  const parseArrayValueOp = token => state => {
201
338
  if (token.kind === ']') { return endArray(state) }
202
- if (token.kind === ',') { return { status: '[,', top: state.top, stack: state.stack } }
339
+ if (token.kind === ',') { return { ... state, valueState: '[,', top: state.top, stack: state.stack } }
203
340
  if (token.kind === 'ws') { return state }
204
- return { status: 'error', message: 'unexpected token' }
341
+ return { state: 'error', message: 'unexpected token' }
205
342
  }
206
343
 
207
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
344
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
208
345
  const parseObjectStartOp = token => state => {
209
346
  if (token.kind === 'string') { return pushKey(state)(token.value) }
210
347
  if (token.kind === '}') { return endObject(state) }
211
348
  if (token.kind === 'ws') { return state }
212
- return { status: 'error', message: 'unexpected token' }
349
+ return { state: 'error', message: 'unexpected token' }
213
350
  }
214
351
 
215
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
352
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
216
353
  const parseObjectKeyOp = token => state => {
217
- if (token.kind === ':') { return { status: '{:', top: state.top, stack: state.stack } }
354
+ if (token.kind === ':') { return { ... state, valueState: '{:', top: state.top, stack: state.stack } }
218
355
  if (token.kind === 'ws') { return state }
219
- return { status: 'error', message: 'unexpected token' }
356
+ return { state: 'error', message: 'unexpected token' }
220
357
  }
221
358
 
222
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
359
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
223
360
  const parseObjectColonOp = token => state => {
224
361
  if (isValueToken(token)) { return pushValue(state)(tokenToValue(token)) }
362
+ if (token.kind === 'id') { return pushRef(state)(token.value) }
225
363
  if (token.kind === '[') { return startArray(state) }
226
364
  if (token.kind === '{') { return startObject(state) }
227
365
  if (token.kind === 'ws') { return state }
228
- return { status: 'error', message: 'unexpected token' }
366
+ return { state: 'error', message: 'unexpected token' }
229
367
  }
230
368
 
231
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
369
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
232
370
  const parseObjectNextOp = token => state => {
233
371
  if (token.kind === '}') { return endObject(state) }
234
- if (token.kind === ',') { return { status: '{,', top: state.top, stack: state.stack } }
372
+ if (token.kind === ',') { return { ... state, valueState: '{,', top: state.top, stack: state.stack } }
235
373
  if (token.kind === 'ws') { return state }
236
- return { status: 'error', message: 'unexpected token' }
374
+ return { state: 'error', message: 'unexpected token' }
237
375
  }
238
376
 
239
- /** @type {(token: tokenizerT.DjsToken) => (state: StateParse) => DjsState}} */
377
+ /** @type {(token: tokenizerT.DjsToken) => (state: ParseValueState) => ParserState}} */
240
378
  const parseObjectCommaOp = token => state => {
241
379
  if (token.kind === 'string') { return pushKey(state)(token.value) }
242
380
  if (token.kind === 'ws') { return state }
243
- return { status: 'error', message: 'unexpected token' }
381
+ return { state: 'error', message: 'unexpected token' }
244
382
  }
245
383
 
246
- /** @type {Operator.Fold<tokenizerT.DjsToken, DjsState>} */
384
+ /** @type {Operator.Fold<tokenizerT.DjsToken, ParserState>} */
247
385
  const foldOp = token => state => {
248
- switch (state.status) {
249
- case 'module': return parseModuleOp(token)(state)
250
- case 'result': return { status: 'error', message: 'unexpected token' }
251
- case 'error': return { status: 'error', message: state.message }
252
- case '': return parseValueOp(token)(state)
253
- case '[': return parseArrayStartOp(token)(state)
254
- case '[v': return parseArrayValueOp(token)(state)
255
- case '[,': return parseValueOp(token)(state)
256
- case '{': return parseObjectStartOp(token)(state)
257
- case '{k': return parseObjectKeyOp(token)(state)
258
- case '{:': return parseObjectColonOp(token)(state)
259
- case '{v': return parseObjectNextOp(token)(state)
260
- case '{,': return parseObjectCommaOp(token)(state)
386
+ switch (state.state) {
387
+ case '': return parseInitialOp(token)(state)
388
+ case 'nl': return parseNewLineRequiredOp(token)(state)
389
+ case 'import': return parseImportOp(token)(state)
390
+ case 'import+name': return parseImportNameOp(token)(state)
391
+ case 'import+from': return parseImportFromOp(token)(state)
392
+ case 'const': return parseConstOp(token)(state)
393
+ case 'const+name': return parseConstNameOp(token)(state)
394
+ case 'export': return parseExportOp(token)(state)
395
+ case 'result': return { state: 'error', message: 'unexpected token' }
396
+ case 'error': return { state: 'error', message: state.message }
397
+ case 'constValue':
398
+ case 'exportValue':
399
+ {
400
+ switch (state.valueState)
401
+ {
402
+ case '': return parseValueOp(token)(state)
403
+ case '[': return parseArrayStartOp(token)(state)
404
+ case '[v': return parseArrayValueOp(token)(state)
405
+ case '[,': return parseValueOp(token)(state)
406
+ case '{': return parseObjectStartOp(token)(state)
407
+ case '{k': return parseObjectKeyOp(token)(state)
408
+ case '{:': return parseObjectColonOp(token)(state)
409
+ case '{v': return parseObjectNextOp(token)(state)
410
+ case '{,': return parseObjectCommaOp(token)(state)
411
+ }
412
+ }
261
413
  }
262
414
  }
263
415
 
264
- /** @type {(tokenList: List.List<tokenizerT.DjsToken>) => Result.Result<Djs.Unknown, string>} */
416
+ /** @type {(tokenList: List.List<tokenizerT.DjsToken>) => Result.Result<DjsModule, string>} */
265
417
  const parse = tokenList => {
266
- const state = fold(foldOp)({ status: 'module', stage: 'module' })(tokenList)
267
- switch (state.status) {
268
- case 'result': return result.ok(state.value)
418
+ const state = fold(foldOp)({ state: '', module: { refs: null, modules: null, consts: null }})(tokenList)
419
+ switch (state.state) {
420
+ case 'result': return result.ok([ toArray(state.module.modules), toArray(state.module.consts) ])
269
421
  case 'error': return result.error(state.message)
270
422
  default: return result.error('unexpected end')
271
423
  }
272
424
  }
273
425
 
426
+
274
427
  export default {
275
428
  /** @readonly */
276
429
  parse
@@ -4,5 +4,9 @@ declare namespace _default {
4
4
  let validWhiteSpaces: (() => void)[];
5
5
  let validModule: (() => void)[];
6
6
  let invalidModule: (() => void)[];
7
+ let validWithConst: (() => void)[];
8
+ let invalidWithConst: (() => void)[];
9
+ let validWithArgs: (() => void)[];
10
+ let invalidWithArgs: (() => void)[];
7
11
  }
8
12
  export default _default;