septima-lang 0.0.5 → 0.0.7

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 (72) hide show
  1. package/main.js +1 -0
  2. package/package.json +3 -3
  3. package/dist/src/ast-node.d.ts +0 -98
  4. package/dist/src/ast-node.js +0 -139
  5. package/dist/src/extract-message.d.ts +0 -1
  6. package/dist/src/extract-message.js +0 -10
  7. package/dist/src/fail-me.d.ts +0 -1
  8. package/dist/src/fail-me.js +0 -11
  9. package/dist/src/find-array-method.d.ts +0 -15
  10. package/dist/src/find-array-method.js +0 -104
  11. package/dist/src/find-string-method.d.ts +0 -2
  12. package/dist/src/find-string-method.js +0 -88
  13. package/dist/src/index.d.ts +0 -1
  14. package/dist/src/index.js +0 -18
  15. package/dist/src/location.d.ts +0 -11
  16. package/dist/src/location.js +0 -3
  17. package/dist/src/parser.d.ts +0 -44
  18. package/dist/src/parser.js +0 -458
  19. package/dist/src/result.d.ts +0 -24
  20. package/dist/src/result.js +0 -29
  21. package/dist/src/runtime.d.ts +0 -27
  22. package/dist/src/runtime.js +0 -343
  23. package/dist/src/scanner.d.ts +0 -23
  24. package/dist/src/scanner.js +0 -88
  25. package/dist/src/septima.d.ts +0 -32
  26. package/dist/src/septima.js +0 -91
  27. package/dist/src/should-never-happen.d.ts +0 -1
  28. package/dist/src/should-never-happen.js +0 -9
  29. package/dist/src/source-code.d.ts +0 -19
  30. package/dist/src/source-code.js +0 -90
  31. package/dist/src/stack.d.ts +0 -11
  32. package/dist/src/stack.js +0 -19
  33. package/dist/src/switch-on.d.ts +0 -1
  34. package/dist/src/switch-on.js +0 -9
  35. package/dist/src/symbol-table.d.ts +0 -6
  36. package/dist/src/symbol-table.js +0 -3
  37. package/dist/src/value.d.ts +0 -128
  38. package/dist/src/value.js +0 -634
  39. package/dist/tests/parser.spec.d.ts +0 -1
  40. package/dist/tests/parser.spec.js +0 -31
  41. package/dist/tests/septima-compute-module.spec.d.ts +0 -1
  42. package/dist/tests/septima-compute-module.spec.js +0 -30
  43. package/dist/tests/septima.spec.d.ts +0 -1
  44. package/dist/tests/septima.spec.js +0 -774
  45. package/dist/tests/value.spec.d.ts +0 -1
  46. package/dist/tests/value.spec.js +0 -355
  47. package/dist/tsconfig.tsbuildinfo +0 -1
  48. package/jest-output.json +0 -1
  49. package/src/a.js +0 -66
  50. package/src/ast-node.ts +0 -249
  51. package/src/extract-message.ts +0 -5
  52. package/src/fail-me.ts +0 -7
  53. package/src/find-array-method.ts +0 -115
  54. package/src/find-string-method.ts +0 -84
  55. package/src/index.ts +0 -1
  56. package/src/location.ts +0 -13
  57. package/src/parser.ts +0 -526
  58. package/src/result.ts +0 -45
  59. package/src/runtime.ts +0 -360
  60. package/src/scanner.ts +0 -106
  61. package/src/septima.ts +0 -114
  62. package/src/should-never-happen.ts +0 -4
  63. package/src/source-code.ts +0 -101
  64. package/src/stack.ts +0 -18
  65. package/src/switch-on.ts +0 -4
  66. package/src/symbol-table.ts +0 -7
  67. package/src/value.ts +0 -742
  68. package/tests/parser.spec.ts +0 -30
  69. package/tests/septima-compute-module.spec.ts +0 -33
  70. package/tests/septima.spec.ts +0 -839
  71. package/tests/value.spec.ts +0 -387
  72. package/tsconfig.json +0 -11
@@ -1,84 +0,0 @@
1
- import { Value } from './value'
2
-
3
- export function findStringMethod(s: string, indexValue: string | Value) {
4
- const index = Value.toStringOrNumber(indexValue)
5
- if (typeof index === 'number') {
6
- throw new Error(`Index is of type number - not supported`)
7
- }
8
- if (index === 'at') {
9
- return Value.foreign(n => s.at(n.assertNum()))
10
- }
11
- if (index === 'charAt') {
12
- return Value.foreign(n => s.charAt(n.assertNum()))
13
- }
14
- if (index === 'concat') {
15
- return Value.foreign(arg => s.concat(arg.assertStr()))
16
- }
17
- if (index === 'endsWith') {
18
- return Value.foreign(arg => s.endsWith(arg.assertStr()))
19
- }
20
- if (index === 'includes') {
21
- return Value.foreign(arg => s.includes(arg.assertStr()))
22
- }
23
- if (index === 'indexOf') {
24
- return Value.foreign(searchString => s.indexOf(searchString.assertStr()))
25
- }
26
- if (index === 'lastIndexOf') {
27
- return Value.foreign(searchString => s.lastIndexOf(searchString.assertStr()))
28
- }
29
- if (index === 'length') {
30
- return Value.num(s.length)
31
- }
32
- if (index === 'match') {
33
- return Value.foreign(r => s.match(r.assertStr()))
34
- }
35
- if (index === 'matchAll') {
36
- return Value.foreign(r => [...s.matchAll(new RegExp(r.assertStr(), 'g'))])
37
- }
38
- if (index === 'padEnd') {
39
- return Value.foreign((maxLength, fillString) => s.padEnd(maxLength.assertNum(), fillString?.assertStr()))
40
- }
41
- if (index === 'padStart') {
42
- return Value.foreign((maxLength, fillString) => s.padStart(maxLength.assertNum(), fillString?.assertStr()))
43
- }
44
- if (index === 'repeat') {
45
- return Value.foreign(count => s.repeat(count.assertNum()))
46
- }
47
- if (index === 'replace') {
48
- return Value.foreign((searchValue, replacer) => s.replace(searchValue.assertStr(), replacer.assertStr()))
49
- }
50
- if (index === 'replaceAll') {
51
- return Value.foreign((searchValue, replacer) => s.replaceAll(searchValue.assertStr(), replacer.assertStr()))
52
- }
53
- if (index === 'search') {
54
- return Value.foreign(searcher => s.search(searcher.assertStr()))
55
- }
56
- if (index === 'slice') {
57
- return Value.foreign((start, end) => s.slice(start?.assertNum(), end?.assertNum()))
58
- }
59
- if (index === 'split') {
60
- return Value.foreign(splitter => s.split(splitter.assertStr()))
61
- }
62
- if (index === 'startsWith') {
63
- return Value.foreign(arg => s.startsWith(arg.assertStr()))
64
- }
65
- if (index === 'substring') {
66
- return Value.foreign((start, end) => s.substring(start.assertNum(), end?.assertNum()))
67
- }
68
- if (index === 'toLowerCase') {
69
- return Value.foreign(() => s.toLowerCase())
70
- }
71
- if (index === 'toUpperCase') {
72
- return Value.foreign(() => s.toUpperCase())
73
- }
74
- if (index === 'trim') {
75
- return Value.foreign(() => s.trim())
76
- }
77
- if (index === 'trimEnd') {
78
- return Value.foreign(() => s.trimEnd())
79
- }
80
- if (index === 'trimStart') {
81
- return Value.foreign(() => s.trimStart())
82
- }
83
- throw new Error(`Unrecognized string method: ${index}`)
84
- }
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './septima'
package/src/location.ts DELETED
@@ -1,13 +0,0 @@
1
- export interface Location {
2
- readonly offset: number
3
- }
4
-
5
- export interface Span {
6
- from: Location
7
- to: Location
8
- }
9
-
10
- export interface Location2d {
11
- line: number
12
- col: number
13
- }
package/src/parser.ts DELETED
@@ -1,526 +0,0 @@
1
- import { ArrayLiteralPart, AstNode, Ident, Import, Let, Literal, ObjectLiteralPart, span, Unit } from './ast-node'
2
- import { Scanner, Token } from './scanner'
3
- import { switchOn } from './switch-on'
4
-
5
- export class Parser {
6
- constructor(private readonly scanner: Scanner) {}
7
-
8
- parse(): Unit {
9
- const ret = this.unit()
10
- if (!this.scanner.eof()) {
11
- throw new Error(`Loitering input ${this.scanner.sourceRef}`)
12
- }
13
- return ret
14
- }
15
-
16
- unit(): Unit {
17
- const imports = this.imports()
18
- const expression = this.expression()
19
- return { tag: 'unit', imports, expression }
20
- }
21
-
22
- imports(): Import[] {
23
- const ret: Import[] = []
24
- while (true) {
25
- const start = this.scanner.consumeIf('import')
26
- if (!start) {
27
- return ret
28
- }
29
-
30
- this.scanner.consume('*')
31
- this.scanner.consume('as')
32
- const ident = this.identifier()
33
- this.scanner.consume('from')
34
- const pathToImportFrom = this.maybePrimitiveLiteral()
35
- if (pathToImportFrom === undefined) {
36
- throw new Error(`Expected a literal ${this.scanner.sourceRef}`)
37
- }
38
-
39
- const notString = () => {
40
- throw new Error(`Expected a string literal ${this.scanner.sourceCode.sourceRef(span(pathToImportFrom))}`)
41
- }
42
- switchOn(pathToImportFrom.type, {
43
- bool: notString,
44
- num: notString,
45
- str: () => {},
46
- sink: notString,
47
- 'sink!': notString,
48
- 'sink!!': notString,
49
- })
50
- ret.push({ start, ident, pathToImportFrom: pathToImportFrom.t })
51
-
52
- this.scanner.consumeIf(';')
53
- }
54
- }
55
-
56
- definitions(): Let[] {
57
- const ret: Let[] = []
58
- while (true) {
59
- const start = this.scanner.consumeIf('let ')
60
- if (!start) {
61
- return ret
62
- }
63
- const ident = this.identifier()
64
- this.scanner.consume('=')
65
- const value = this.lambda()
66
- ret.push({ start, ident, value })
67
-
68
- this.scanner.consumeIf(';')
69
- if (!this.scanner.headMatches('let ')) {
70
- return ret
71
- }
72
- }
73
- }
74
-
75
- expression(): AstNode {
76
- const definitions = this.definitions()
77
- this.scanner.consumeIf('return')
78
- const computation = this.lambda()
79
-
80
- if (definitions.length === 0) {
81
- return computation
82
- }
83
-
84
- return { tag: 'topLevelExpression', definitions, computation }
85
- }
86
-
87
- lambda(): AstNode {
88
- const start = this.scanner.consumeIf('fun')
89
- if (!start) {
90
- return this.arrowFunction()
91
- }
92
-
93
- this.scanner.consume('(')
94
- const args: Ident[] = []
95
-
96
- if (this.scanner.consumeIf(')')) {
97
- // no formal args
98
- } else {
99
- while (true) {
100
- const arg = this.identifier()
101
- args.push(arg)
102
- if (this.scanner.consumeIf(')')) {
103
- break
104
- }
105
-
106
- this.scanner.consume(',')
107
- }
108
- }
109
-
110
- const body = this.expression()
111
- return { tag: 'lambda', start, formalArgs: args, body }
112
- }
113
-
114
- arrowFunction(): AstNode {
115
- if (this.scanner.headMatches('(', ')', '=>')) {
116
- const start = this.scanner.consume('(')
117
- this.scanner.consume(')')
118
- this.scanner.consume('=>')
119
- const body = this.lambdaBody()
120
- return { tag: 'lambda', start, formalArgs: [], body }
121
- }
122
- if (this.scanner.headMatches(IDENT_PATTERN, '=>')) {
123
- const ident = this.identifier()
124
- this.scanner.consume('=>')
125
- const body = this.lambdaBody()
126
- return { tag: 'lambda', start: ident.t, formalArgs: [ident], body }
127
- }
128
- if (this.scanner.headMatches('(', IDENT_PATTERN, ')', '=>')) {
129
- const start = this.scanner.consume('(')
130
- const ident = this.identifier()
131
- this.scanner.consume(')')
132
- this.scanner.consume('=>')
133
- const body = this.lambdaBody()
134
- return { tag: 'lambda', start, formalArgs: [ident], body }
135
- }
136
- if (this.scanner.headMatches('(', IDENT_PATTERN, ',')) {
137
- const start = this.scanner.consume('(')
138
- const formalArgs: Ident[] = []
139
- while (true) {
140
- const ident = this.identifier()
141
- formalArgs.push(ident)
142
-
143
- if (this.scanner.consumeIf(')')) {
144
- break
145
- }
146
-
147
- this.scanner.consume(',')
148
- }
149
-
150
- this.scanner.consume('=>')
151
- const body = this.lambdaBody()
152
- return { tag: 'lambda', start, formalArgs, body }
153
- }
154
-
155
- return this.ifExpression()
156
- }
157
-
158
- private lambdaBody() {
159
- if (this.scanner.consumeIf('{')) {
160
- const ret = this.expression()
161
- this.scanner.consume('}')
162
- return ret
163
- }
164
-
165
- return this.expression()
166
- }
167
-
168
- ifExpression(): AstNode {
169
- if (!this.scanner.consumeIf('if')) {
170
- return this.unsink()
171
- }
172
-
173
- this.scanner.consume('(')
174
- const condition = this.expression()
175
- this.scanner.consume(')')
176
-
177
- const positive = this.expression()
178
-
179
- this.scanner.consume('else')
180
-
181
- const negative = this.expression()
182
-
183
- return { tag: 'if', condition, positive, negative }
184
- }
185
-
186
- unsink(): AstNode {
187
- const lhs = this.or()
188
- if (this.scanner.consumeIf('??')) {
189
- return { tag: 'binaryOperator', operator: '??', lhs, rhs: this.unsink() }
190
- }
191
- return lhs
192
- }
193
-
194
- or(): AstNode {
195
- const lhs = this.and()
196
- if (this.scanner.consumeIf('||')) {
197
- return { tag: 'binaryOperator', operator: '||', lhs, rhs: this.or() }
198
- }
199
- return lhs
200
- }
201
-
202
- and(): AstNode {
203
- const lhs = this.equality()
204
- if (this.scanner.consumeIf('&&')) {
205
- return { tag: 'binaryOperator', operator: '&&', lhs, rhs: this.and() }
206
- }
207
- return lhs
208
- }
209
-
210
- equality(): AstNode {
211
- const lhs = this.comparison()
212
- if (this.scanner.consumeIf('==')) {
213
- return { tag: 'binaryOperator', operator: '==', lhs, rhs: this.equality() }
214
- }
215
- if (this.scanner.consumeIf('!=')) {
216
- return { tag: 'binaryOperator', operator: '!=', lhs, rhs: this.equality() }
217
- }
218
- return lhs
219
- }
220
-
221
- comparison(): AstNode {
222
- const lhs = this.addition()
223
- if (this.scanner.consumeIf('>=')) {
224
- return { tag: 'binaryOperator', operator: '>=', lhs, rhs: this.comparison() }
225
- }
226
- if (this.scanner.consumeIf('<=')) {
227
- return { tag: 'binaryOperator', operator: '<=', lhs, rhs: this.comparison() }
228
- }
229
- if (this.scanner.consumeIf('>')) {
230
- return { tag: 'binaryOperator', operator: '>', lhs, rhs: this.comparison() }
231
- }
232
- if (this.scanner.consumeIf('<')) {
233
- return { tag: 'binaryOperator', operator: '<', lhs, rhs: this.comparison() }
234
- }
235
- return lhs
236
- }
237
-
238
- addition(): AstNode {
239
- const lhs = this.multiplication()
240
- if (this.scanner.consumeIf('+')) {
241
- return { tag: 'binaryOperator', operator: '+', lhs, rhs: this.addition() }
242
- }
243
- if (this.scanner.consumeIf('-')) {
244
- return { tag: 'binaryOperator', operator: '-', lhs, rhs: this.addition() }
245
- }
246
- return lhs
247
- }
248
-
249
- multiplication(): AstNode {
250
- const lhs = this.power()
251
- if (this.scanner.consumeIf('*')) {
252
- return { tag: 'binaryOperator', operator: '*', lhs, rhs: this.multiplication() }
253
- }
254
- if (this.scanner.consumeIf('/')) {
255
- return { tag: 'binaryOperator', operator: '/', lhs, rhs: this.multiplication() }
256
- }
257
- if (this.scanner.consumeIf('%')) {
258
- return { tag: 'binaryOperator', operator: '%', lhs, rhs: this.multiplication() }
259
- }
260
- return lhs
261
- }
262
-
263
- power(): AstNode {
264
- const lhs = this.unary()
265
- if (this.scanner.consumeIf('**')) {
266
- return { tag: 'binaryOperator', operator: '**', lhs, rhs: this.power() }
267
- }
268
- return lhs
269
- }
270
-
271
- unary(): AstNode {
272
- let operatorToken = this.scanner.consumeIf('!')
273
- if (operatorToken) {
274
- return { tag: 'unaryOperator', operand: this.unary(), operator: '!', operatorToken }
275
- }
276
- operatorToken = this.scanner.consumeIf('+')
277
- if (operatorToken) {
278
- return { tag: 'unaryOperator', operand: this.unary(), operator: '+', operatorToken }
279
- }
280
- operatorToken = this.scanner.consumeIf('-')
281
- if (operatorToken) {
282
- return { tag: 'unaryOperator', operand: this.unary(), operator: '-', operatorToken }
283
- }
284
-
285
- return this.call()
286
- }
287
-
288
- call(): AstNode {
289
- const callee = this.memberAccess()
290
-
291
- if (!this.scanner.consumeIf('(')) {
292
- return callee
293
- }
294
-
295
- const { actualArgs, end } = this.actualArgList()
296
- return { tag: 'functionCall', actualArgs, callee, end }
297
- }
298
-
299
- private actualArgList() {
300
- const actualArgs: AstNode[] = []
301
- const endEmpty = this.scanner.consumeIf(')')
302
- if (endEmpty) {
303
- // no actual args
304
- return { actualArgs, end: endEmpty }
305
- }
306
-
307
- while (true) {
308
- const arg = this.expression()
309
- actualArgs.push(arg)
310
- const end = this.scanner.consumeIf(')')
311
- if (end) {
312
- return { actualArgs, end }
313
- }
314
- this.scanner.consume(',')
315
- }
316
- }
317
-
318
- memberAccess(): AstNode {
319
- let ret = this.parenthesized()
320
-
321
- while (true) {
322
- if (this.scanner.consumeIf('.')) {
323
- ret = { tag: 'dot', receiver: ret, ident: this.identifier() }
324
- continue
325
- }
326
-
327
- if (this.scanner.consumeIf('[')) {
328
- ret = { tag: 'indexAccess', receiver: ret, index: this.expression() }
329
- this.scanner.consume(']')
330
- continue
331
- }
332
-
333
- if (this.scanner.consumeIf('(')) {
334
- const { actualArgs, end } = this.actualArgList()
335
- ret = { tag: 'functionCall', actualArgs, callee: ret, end }
336
- continue
337
- }
338
-
339
- return ret
340
- }
341
- }
342
-
343
- parenthesized(): AstNode {
344
- if (this.scanner.consumeIf('(')) {
345
- const ret = this.expression()
346
- this.scanner.consume(')')
347
- return ret
348
- }
349
-
350
- return this.literalOrIdent()
351
- }
352
-
353
- literalOrIdent(): AstNode {
354
- const ret = this.maybeLiteral() ?? this.maybeIdentifier()
355
- if (!ret) {
356
- throw new Error(`Unparsable input ${this.scanner.sourceRef}`)
357
- }
358
- return ret
359
- }
360
-
361
- maybeLiteral(): AstNode | undefined {
362
- return this.maybePrimitiveLiteral() ?? this.maybeCompositeLiteral()
363
- }
364
-
365
- maybePrimitiveLiteral(): Literal | undefined {
366
- let t = this.scanner.consumeIf('sink!!')
367
- if (t) {
368
- return { tag: 'literal', type: 'sink!!', t }
369
- }
370
-
371
- t = this.scanner.consumeIf('sink!')
372
- if (t) {
373
- return { tag: 'literal', type: 'sink!', t }
374
- }
375
-
376
- t = this.scanner.consumeIf('sink')
377
- if (t) {
378
- return { tag: 'literal', type: 'sink', t }
379
- }
380
-
381
- t = this.scanner.consumeIf('true')
382
- if (t) {
383
- return { tag: 'literal', type: 'bool', t }
384
- }
385
- t = this.scanner.consumeIf('false')
386
- if (t) {
387
- return { tag: 'literal', type: 'bool', t }
388
- }
389
-
390
- t = this.scanner.consumeIf(/([0-9]*[.])?[0-9]+/)
391
- if (t) {
392
- return { tag: 'literal', type: 'num', t }
393
- }
394
-
395
- // double-quotes-enclosd string
396
- if (this.scanner.consumeIf(`"`, false)) {
397
- t = this.scanner.consume(/[^"]*/)
398
- this.scanner.consume(`"`)
399
- return { tag: 'literal', type: 'str', t }
400
- }
401
-
402
- // single-quotes-enclosd string
403
- if (this.scanner.consumeIf(`'`, false)) {
404
- t = this.scanner.consume(/[^']*/)
405
- this.scanner.consume(`'`)
406
- return { tag: 'literal', type: 'str', t }
407
- }
408
-
409
- return undefined
410
- }
411
-
412
- maybeCompositeLiteral(): AstNode | undefined {
413
- let t = this.scanner.consumeIf('[')
414
- if (t) {
415
- return this.arrayBody(t)
416
- }
417
-
418
- t = this.scanner.consumeIf('{')
419
- if (t) {
420
- return this.objectBody(t)
421
- }
422
-
423
- return undefined
424
- }
425
-
426
- /**
427
- * This method assumes that the caller consumed the opening '[' token. It consumes the array's elements
428
- * (comma-separated list of expressions) as well as the closing ']' token.
429
- */
430
- arrayBody(start: Token): AstNode {
431
- const t = this.scanner.consumeIf(']')
432
- if (t) {
433
- // an empty array literal
434
- return { tag: 'arrayLiteral', start, parts: [], end: t }
435
- }
436
-
437
- const parts: ArrayLiteralPart[] = []
438
- while (true) {
439
- if (this.scanner.consumeIf(',')) {
440
- const end = this.scanner.consumeIf(']')
441
- if (end) {
442
- return { tag: 'arrayLiteral', start, parts, end }
443
- }
444
- continue
445
- }
446
- if (this.scanner.consumeIf('...')) {
447
- parts.push({ tag: 'spread', v: this.expression() })
448
- } else {
449
- const exp = this.expression()
450
- parts.push({ tag: 'element', v: exp })
451
- }
452
-
453
- let end = this.scanner.consumeIf(']')
454
- if (end) {
455
- return { tag: 'arrayLiteral', start, parts, end }
456
- }
457
-
458
- this.scanner.consume(',')
459
- end = this.scanner.consumeIf(']')
460
- if (end) {
461
- return { tag: 'arrayLiteral', start, parts, end }
462
- }
463
- }
464
- }
465
-
466
- /**
467
- * This method assumes that the caller consumed the opening '{' token. It consumes the object's attributes
468
- * (comma-separated list of key:value parirs) as well as the closing '}' token.
469
- */
470
- objectBody(start: Token): AstNode {
471
- const t = this.scanner.consumeIf('}')
472
- if (t) {
473
- // an empty array literal
474
- return { tag: 'objectLiteral', start, parts: [], end: t }
475
- }
476
-
477
- const parts: ObjectLiteralPart[] = []
478
- while (true) {
479
- if (this.scanner.consumeIf('...')) {
480
- parts.push({ tag: 'spread', o: this.expression() })
481
- } else if (this.scanner.consumeIf('[')) {
482
- const k = this.expression()
483
- this.scanner.consume(']')
484
- this.scanner.consume(':')
485
- const v = this.expression()
486
- parts.push({ tag: 'computedName', k, v })
487
- } else {
488
- const k = this.identifier()
489
- this.scanner.consume(':')
490
- const v = this.expression()
491
- parts.push({ tag: 'hardName', k, v })
492
- }
493
-
494
- let end = this.scanner.consumeIf('}')
495
- if (end) {
496
- return { tag: 'objectLiteral', start, parts, end }
497
- }
498
-
499
- this.scanner.consume(',')
500
- end = this.scanner.consumeIf('}')
501
- if (end) {
502
- return { tag: 'objectLiteral', start, parts, end }
503
- }
504
- }
505
- }
506
-
507
- private identifier(): Ident {
508
- const ret = this.maybeIdentifier()
509
- if (!ret) {
510
- throw new Error(`Expected an identifier ${this.scanner.sourceRef}`)
511
- }
512
-
513
- return ret
514
- }
515
-
516
- private maybeIdentifier(): Ident | undefined {
517
- const t = this.scanner.consumeIf(IDENT_PATTERN)
518
- if (t) {
519
- return { tag: 'ident', t }
520
- }
521
-
522
- return undefined
523
- }
524
- }
525
-
526
- const IDENT_PATTERN = /[a-zA-Z][0-9A-Za-z_]*/
package/src/result.ts DELETED
@@ -1,45 +0,0 @@
1
- import { Span } from './location'
2
- import { SourceCode } from './source-code'
3
- import { Value } from './value'
4
-
5
- export type ResultSink = {
6
- tag: 'sink'
7
- where: Span | undefined
8
- trace: string | undefined
9
- symbols: Record<string, unknown> | undefined
10
- message: string
11
- }
12
-
13
- export type Result =
14
- | {
15
- tag: 'ok'
16
- value: unknown
17
- }
18
- | ResultSink
19
-
20
- export class ResultSinkImpl {
21
- readonly tag = 'sink'
22
- constructor(private readonly sink: Value, private readonly sourceCode: SourceCode) {}
23
-
24
- get where(): Span | undefined {
25
- return this.sink.span()
26
- }
27
-
28
- get trace() {
29
- const trace = this.sink.trace()
30
- if (trace) {
31
- return this.sourceCode.formatTrace(trace)
32
- }
33
-
34
- return undefined
35
- }
36
-
37
- get symbols() {
38
- return this.sink.symbols()?.export()
39
- }
40
-
41
- get message(): string {
42
- const at = this.trace ?? this.sourceCode.sourceRef(this.where)
43
- return `Evaluated to sink: ${at}`
44
- }
45
- }