septima-lang 0.0.7 → 0.0.9
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/dist/src/ast-node.d.ts +103 -0
- package/dist/src/ast-node.js +156 -0
- package/dist/src/extract-message.d.ts +1 -0
- package/dist/src/extract-message.js +10 -0
- package/dist/src/fail-me.d.ts +1 -0
- package/dist/src/fail-me.js +11 -0
- package/dist/src/find-array-method.d.ts +15 -0
- package/dist/src/find-array-method.js +104 -0
- package/dist/src/find-string-method.d.ts +2 -0
- package/dist/src/find-string-method.js +88 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/location.d.ts +11 -0
- package/dist/src/location.js +3 -0
- package/dist/src/parser.d.ts +45 -0
- package/dist/src/parser.js +490 -0
- package/dist/src/result.d.ts +24 -0
- package/dist/src/result.js +29 -0
- package/dist/src/runtime.d.ts +28 -0
- package/dist/src/runtime.js +351 -0
- package/dist/src/scanner.d.ts +23 -0
- package/dist/src/scanner.js +88 -0
- package/dist/src/septima.d.ts +32 -0
- package/dist/src/septima.js +91 -0
- package/dist/src/should-never-happen.d.ts +1 -0
- package/dist/src/should-never-happen.js +9 -0
- package/dist/src/source-code.d.ts +19 -0
- package/dist/src/source-code.js +90 -0
- package/dist/src/stack.d.ts +11 -0
- package/dist/src/stack.js +19 -0
- package/dist/src/switch-on.d.ts +1 -0
- package/dist/src/switch-on.js +9 -0
- package/dist/src/symbol-table.d.ts +6 -0
- package/dist/src/symbol-table.js +3 -0
- package/dist/src/value.d.ts +128 -0
- package/dist/src/value.js +634 -0
- package/dist/tests/parser.spec.d.ts +1 -0
- package/dist/tests/parser.spec.js +35 -0
- package/dist/tests/septima-compute-module.spec.d.ts +1 -0
- package/dist/tests/septima-compute-module.spec.js +36 -0
- package/dist/tests/septima.spec.d.ts +1 -0
- package/dist/tests/septima.spec.js +857 -0
- package/dist/tests/value.spec.d.ts +1 -0
- package/dist/tests/value.spec.js +355 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +3 -3
- package/src/a.js +66 -0
- package/src/ast-node.ts +269 -0
- package/src/extract-message.ts +5 -0
- package/src/fail-me.ts +7 -0
- package/src/find-array-method.ts +115 -0
- package/src/find-string-method.ts +84 -0
- package/src/index.ts +1 -0
- package/src/location.ts +13 -0
- package/src/parser.ts +563 -0
- package/src/result.ts +45 -0
- package/src/runtime.ts +370 -0
- package/src/scanner.ts +106 -0
- package/src/septima.ts +121 -0
- package/src/should-never-happen.ts +4 -0
- package/src/source-code.ts +101 -0
- package/src/stack.ts +18 -0
- package/src/switch-on.ts +4 -0
- package/src/symbol-table.ts +7 -0
- package/src/value.ts +742 -0
- package/tests/parser.spec.ts +36 -0
- package/tests/septima-compute-module.spec.ts +41 -0
- package/tests/septima.spec.ts +933 -0
- package/tests/value.spec.ts +387 -0
- package/main.js +0 -1
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { Value } from '../src/value'
|
|
2
|
+
|
|
3
|
+
const err = () => {
|
|
4
|
+
throw new Error(`should not run`)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const fixed = (u: unknown) => () => Value.from(u)
|
|
8
|
+
|
|
9
|
+
const notFromHere = () => {
|
|
10
|
+
throw new Error('should not be called from this test')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('value', () => {
|
|
14
|
+
test('arithmetics', () => {
|
|
15
|
+
expect(Value.num(5).plus(Value.num(3)).export()).toEqual(8)
|
|
16
|
+
expect(Value.num(5).minus(Value.num(3)).export()).toEqual(2)
|
|
17
|
+
expect(Value.num(5).times(Value.num(3)).export()).toEqual(15)
|
|
18
|
+
expect(Value.num(14).over(Value.num(4)).export()).toEqual(3.5)
|
|
19
|
+
expect(Value.num(5).negate().export()).toEqual(-5)
|
|
20
|
+
expect(Value.num(-12).negate().export()).toEqual(12)
|
|
21
|
+
expect(Value.num(3).power(Value.num(4)).export()).toEqual(81)
|
|
22
|
+
expect(Value.num(2).power(Value.num(8)).export()).toEqual(256)
|
|
23
|
+
})
|
|
24
|
+
test('comparisons of numbers', () => {
|
|
25
|
+
expect(Value.num(5).order(Value.num(3)).export()).toEqual(1)
|
|
26
|
+
expect(Value.num(5).order(Value.num(4)).export()).toEqual(1)
|
|
27
|
+
expect(Value.num(5).order(Value.num(5)).export()).toEqual(0)
|
|
28
|
+
expect(Value.num(5).order(Value.num(6)).export()).toEqual(-1)
|
|
29
|
+
expect(Value.num(5).order(Value.num(7)).export()).toEqual(-1)
|
|
30
|
+
})
|
|
31
|
+
test('booleans', () => {
|
|
32
|
+
expect(Value.bool(true).export()).toEqual(true)
|
|
33
|
+
expect(Value.bool(false).export()).toEqual(false)
|
|
34
|
+
expect(Value.bool(false).not().export()).toEqual(true)
|
|
35
|
+
expect(Value.bool(true).not().export()).toEqual(false)
|
|
36
|
+
})
|
|
37
|
+
describe('boolean operators', () => {
|
|
38
|
+
test('or', () => {
|
|
39
|
+
expect(
|
|
40
|
+
Value.bool(false)
|
|
41
|
+
.or(() => Value.bool(false))
|
|
42
|
+
.export(),
|
|
43
|
+
).toEqual(false)
|
|
44
|
+
expect(
|
|
45
|
+
Value.bool(false)
|
|
46
|
+
.or(() => Value.bool(true))
|
|
47
|
+
.export(),
|
|
48
|
+
).toEqual(true)
|
|
49
|
+
expect(
|
|
50
|
+
Value.bool(true)
|
|
51
|
+
.or(() => Value.bool(false))
|
|
52
|
+
.export(),
|
|
53
|
+
).toEqual(true)
|
|
54
|
+
expect(
|
|
55
|
+
Value.bool(true)
|
|
56
|
+
.or(() => Value.bool(true))
|
|
57
|
+
.export(),
|
|
58
|
+
).toEqual(true)
|
|
59
|
+
})
|
|
60
|
+
test('and', () => {
|
|
61
|
+
expect(
|
|
62
|
+
Value.bool(false)
|
|
63
|
+
.and(() => Value.bool(false))
|
|
64
|
+
.export(),
|
|
65
|
+
).toEqual(false)
|
|
66
|
+
expect(
|
|
67
|
+
Value.bool(false)
|
|
68
|
+
.and(() => Value.bool(true))
|
|
69
|
+
.export(),
|
|
70
|
+
).toEqual(false)
|
|
71
|
+
expect(
|
|
72
|
+
Value.bool(true)
|
|
73
|
+
.and(() => Value.bool(false))
|
|
74
|
+
.export(),
|
|
75
|
+
).toEqual(false)
|
|
76
|
+
expect(
|
|
77
|
+
Value.bool(true)
|
|
78
|
+
.and(() => Value.bool(true))
|
|
79
|
+
.export(),
|
|
80
|
+
).toEqual(true)
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
test('comparisons of booleans', () => {
|
|
84
|
+
expect(Value.bool(false).order(Value.bool(false)).export()).toEqual(0)
|
|
85
|
+
expect(Value.bool(false).order(Value.bool(true)).export()).toEqual(-1)
|
|
86
|
+
expect(Value.bool(true).order(Value.bool(false)).export()).toEqual(1)
|
|
87
|
+
expect(Value.bool(true).order(Value.bool(true)).export()).toEqual(0)
|
|
88
|
+
})
|
|
89
|
+
test('strings', () => {
|
|
90
|
+
expect(Value.str('abc').export()).toEqual('abc')
|
|
91
|
+
expect(Value.str('').export()).toEqual('')
|
|
92
|
+
expect(Value.str('a').plus(Value.str('b')).export()).toEqual('ab')
|
|
93
|
+
expect(Value.str('').plus(Value.str('')).export()).toEqual('')
|
|
94
|
+
expect(Value.str('').plus(Value.str('xyz')).export()).toEqual('xyz')
|
|
95
|
+
expect(Value.str('pqr').plus(Value.str('')).export()).toEqual('pqr')
|
|
96
|
+
expect(Value.str('zxcvb').plus(Value.str('nm')).export()).toEqual('zxcvbnm')
|
|
97
|
+
})
|
|
98
|
+
test('comparisons of strings', () => {
|
|
99
|
+
expect(Value.str('e').order(Value.str('c')).export()).toEqual(1)
|
|
100
|
+
expect(Value.str('e').order(Value.str('d')).export()).toEqual(1)
|
|
101
|
+
expect(Value.str('e').order(Value.str('e')).export()).toEqual(0)
|
|
102
|
+
expect(Value.str('e').order(Value.str('f')).export()).toEqual(-1)
|
|
103
|
+
expect(Value.str('e').order(Value.str('g')).export()).toEqual(-1)
|
|
104
|
+
})
|
|
105
|
+
test('arrays', () => {
|
|
106
|
+
expect(Value.arr([Value.num(10), Value.num(20)]).export()).toEqual([10, 20])
|
|
107
|
+
expect(Value.arr([]).export()).toEqual([])
|
|
108
|
+
expect(Value.arr([Value.str('ab'), Value.num(500), Value.bool(true)]).export()).toEqual(['ab', 500, true])
|
|
109
|
+
})
|
|
110
|
+
test('objects', () => {
|
|
111
|
+
expect(Value.obj({ x: Value.num(10), y: Value.num(20) }).export()).toEqual({ x: 10, y: 20 })
|
|
112
|
+
expect(Value.obj({}).export()).toEqual({})
|
|
113
|
+
expect(Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) }).export()).toEqual({
|
|
114
|
+
the: 'ab',
|
|
115
|
+
quick: 500,
|
|
116
|
+
brown: true,
|
|
117
|
+
})
|
|
118
|
+
const o = Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) })
|
|
119
|
+
expect(o.access('the', notFromHere).export()).toEqual('ab')
|
|
120
|
+
expect(o.access('quick', notFromHere).export()).toEqual(500)
|
|
121
|
+
expect(o.access('brown', notFromHere).export()).toEqual(true)
|
|
122
|
+
expect(o.access(Value.str('quick'), notFromHere).export()).toEqual(500)
|
|
123
|
+
})
|
|
124
|
+
test('yells if access() is called with value which is neither string or num', () => {
|
|
125
|
+
const o = Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) })
|
|
126
|
+
expect(() => o.access(Value.arr([]), notFromHere).export()).toThrowError(
|
|
127
|
+
'value type error: expected either num or str but found []',
|
|
128
|
+
)
|
|
129
|
+
expect(() => o.access(Value.bool(false), notFromHere).export()).toThrowError(
|
|
130
|
+
'value type error: expected either num or str but found false',
|
|
131
|
+
)
|
|
132
|
+
expect(() => o.access(Value.obj({ x: Value.num(1) }), notFromHere).export()).toThrowError(
|
|
133
|
+
'value type error: expected either num or str but found {"x":1}',
|
|
134
|
+
)
|
|
135
|
+
})
|
|
136
|
+
test('json', () => {
|
|
137
|
+
const v = Value.obj({ x: Value.num(1) })
|
|
138
|
+
expect(JSON.stringify(v)).toEqual('{"x":1}')
|
|
139
|
+
})
|
|
140
|
+
describe('ifElse', () => {
|
|
141
|
+
test('when applied to true evaluates the positive branch', () => {
|
|
142
|
+
expect(Value.bool(true).ifElse(fixed('yes'), fixed('no')).export()).toEqual('yes')
|
|
143
|
+
})
|
|
144
|
+
test('when applied to false evaluates the positive branch', () => {
|
|
145
|
+
expect(Value.bool(false).ifElse(fixed('yes'), fixed('no')).export()).toEqual('no')
|
|
146
|
+
})
|
|
147
|
+
test('errors if applied to a non-boolean', () => {
|
|
148
|
+
expect(() => Value.num(1).ifElse(fixed('yes'), fixed('no')).export()).toThrowError('expected bool but found 1')
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
describe('sink', () => {
|
|
152
|
+
const sink = Value.sink()
|
|
153
|
+
test('exported as undefined', () => {
|
|
154
|
+
expect(sink.export()).toEqual(undefined)
|
|
155
|
+
})
|
|
156
|
+
test('arithmetic operations on sink evaluate to sink', () => {
|
|
157
|
+
expect(sink.plus(Value.num(5)).export()).toEqual(undefined)
|
|
158
|
+
expect(sink.minus(Value.num(5)).export()).toEqual(undefined)
|
|
159
|
+
expect(sink.times(Value.num(5)).export()).toEqual(undefined)
|
|
160
|
+
expect(sink.over(Value.num(5)).export()).toEqual(undefined)
|
|
161
|
+
expect(sink.power(Value.num(5)).export()).toEqual(undefined)
|
|
162
|
+
expect(sink.modulo(Value.num(5)).export()).toEqual(undefined)
|
|
163
|
+
expect(sink.negate().export()).toEqual(undefined)
|
|
164
|
+
|
|
165
|
+
expect(Value.num(5).plus(sink).export()).toEqual(undefined)
|
|
166
|
+
expect(Value.num(5).minus(sink).export()).toEqual(undefined)
|
|
167
|
+
expect(Value.num(5).times(sink).export()).toEqual(undefined)
|
|
168
|
+
expect(Value.num(5).over(sink).export()).toEqual(undefined)
|
|
169
|
+
expect(Value.num(5).power(sink).export()).toEqual(undefined)
|
|
170
|
+
expect(Value.num(5).modulo(sink).export()).toEqual(undefined)
|
|
171
|
+
})
|
|
172
|
+
test('boolean operations on sink evaluate to sink', () => {
|
|
173
|
+
expect(sink.and(fixed(true)).export()).toEqual(undefined)
|
|
174
|
+
expect(sink.or(fixed(true)).export()).toEqual(undefined)
|
|
175
|
+
expect(sink.not().export()).toEqual(undefined)
|
|
176
|
+
})
|
|
177
|
+
test('when sink is the right-hand-side of a boolean expression, the result is sink only if the left-hand-side dictates so', () => {
|
|
178
|
+
expect(Value.bool(true).and(fixed(sink)).export()).toEqual(undefined)
|
|
179
|
+
expect(Value.bool(false).and(fixed(sink)).export()).toEqual(false)
|
|
180
|
+
expect(Value.bool(true).or(fixed(sink)).export()).toEqual(true)
|
|
181
|
+
expect(Value.bool(false).or(fixed(sink)).export()).toEqual(undefined)
|
|
182
|
+
})
|
|
183
|
+
test('ifElse with sink condition evaluates to sink', () => {
|
|
184
|
+
expect(sink.ifElse(fixed('y'), fixed('n')).export()).toEqual(undefined)
|
|
185
|
+
})
|
|
186
|
+
test('ifElse with sink positive expression evaluates to sink only if the condition is true', () => {
|
|
187
|
+
expect(Value.bool(true).ifElse(fixed(sink), fixed(-200)).export()).toEqual(undefined)
|
|
188
|
+
expect(Value.bool(false).ifElse(fixed(sink), fixed(-200)).export()).toEqual(-200)
|
|
189
|
+
})
|
|
190
|
+
test('ifElse with sink negative expression evaluates to sink only if the condition is false', () => {
|
|
191
|
+
expect(Value.bool(true).ifElse(fixed(-300), fixed(sink)).export()).toEqual(-300)
|
|
192
|
+
expect(Value.bool(false).ifElse(fixed(-300), fixed(sink)).export()).toEqual(undefined)
|
|
193
|
+
})
|
|
194
|
+
test('access to an attribute of a sink evaluates to sink', () => {
|
|
195
|
+
expect(sink.access('foo', notFromHere).export()).toEqual(undefined)
|
|
196
|
+
})
|
|
197
|
+
test('calling a sink evaluates to sink', () => {
|
|
198
|
+
expect(sink.call([], err).export()).toEqual(undefined)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test('applying .keys() to sink evaluates to sink', () => {
|
|
202
|
+
expect(sink.keys().export()).toEqual(undefined)
|
|
203
|
+
})
|
|
204
|
+
test('applying .entries() to sink evaluates to sink', () => {
|
|
205
|
+
expect(sink.entries().export()).toEqual(undefined)
|
|
206
|
+
})
|
|
207
|
+
test('applying .fromEntries() to sink evaluates to sink', () => {
|
|
208
|
+
expect(sink.fromEntries().export()).toEqual(undefined)
|
|
209
|
+
})
|
|
210
|
+
describe('unsink()', () => {
|
|
211
|
+
test('when applied to a non-sink value evaluates to it', () => {
|
|
212
|
+
expect(Value.num(5).unsink(fixed('x')).export()).toEqual(5)
|
|
213
|
+
})
|
|
214
|
+
test('when applied to a sink value evaluates to its argument', () => {
|
|
215
|
+
expect(Value.num(5).unsink(fixed('x')).export()).toEqual(5)
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
describe('comparisons', () => {
|
|
219
|
+
test('comparing a sink with itself evaluates to true', () => {
|
|
220
|
+
expect(sink.equalsTo(sink).export()).toEqual(true)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
test('comparing a sink with other types evaluates to false', () => {
|
|
224
|
+
expect(sink.equalsTo(Value.arr([])).export()).toEqual(false)
|
|
225
|
+
expect(sink.equalsTo(Value.bool(false)).export()).toEqual(false)
|
|
226
|
+
expect(sink.equalsTo(Value.bool(true)).export()).toEqual(false)
|
|
227
|
+
expect(sink.equalsTo(Value.num(0)).export()).toEqual(false)
|
|
228
|
+
expect(sink.equalsTo(Value.num(5)).export()).toEqual(false)
|
|
229
|
+
expect(sink.equalsTo(Value.obj({})).export()).toEqual(false)
|
|
230
|
+
expect(sink.equalsTo(Value.str('')).export()).toEqual(false)
|
|
231
|
+
expect(sink.equalsTo(Value.str('s')).export()).toEqual(false)
|
|
232
|
+
})
|
|
233
|
+
test('erros when trying to order a sink with a non-sink', () => {
|
|
234
|
+
expect(() => sink.order(Value.arr([])).export()).toThrowError('Cannot compare a')
|
|
235
|
+
expect(() => sink.order(Value.bool(false)).export()).toThrowError('Cannot compare a')
|
|
236
|
+
expect(() => sink.order(Value.bool(true)).export()).toThrowError('Cannot compare a')
|
|
237
|
+
expect(() => sink.order(Value.num(0)).export()).toThrowError('Cannot compare a')
|
|
238
|
+
expect(() => sink.order(Value.num(5)).export()).toThrowError('Cannot compare a')
|
|
239
|
+
expect(() => sink.order(Value.obj({})).export()).toThrowError('Cannot compare a')
|
|
240
|
+
expect(() => sink.order(Value.str('')).export()).toThrowError('Cannot compare a')
|
|
241
|
+
expect(() => sink.order(Value.str('a')).export()).toThrowError('Cannot compare a')
|
|
242
|
+
|
|
243
|
+
expect(() => Value.arr([]).order(sink).export()).toThrowError('Cannot compare a')
|
|
244
|
+
expect(() => Value.bool(false).order(sink).export()).toThrowError('Cannot compare a')
|
|
245
|
+
expect(() => Value.bool(true).order(sink).export()).toThrowError('Cannot compare a')
|
|
246
|
+
expect(() => Value.num(0).order(sink).export()).toThrowError('Cannot compare a')
|
|
247
|
+
expect(() => Value.num(5).order(sink).export()).toThrowError('Cannot compare a')
|
|
248
|
+
expect(() => Value.obj({}).order(sink).export()).toThrowError('Cannot compare a')
|
|
249
|
+
expect(() => Value.str('').order(sink).export()).toThrowError('Cannot compare a')
|
|
250
|
+
expect(() => Value.str('a').order(sink).export()).toThrowError('Cannot compare a')
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
describe('type erros', () => {
|
|
255
|
+
const five = Value.num(1)
|
|
256
|
+
const t = Value.bool(true)
|
|
257
|
+
const f = Value.bool(false)
|
|
258
|
+
|
|
259
|
+
const check = (a: Value, b: Value | Value[], f: (lhs: Value, rhs: Value) => void) => {
|
|
260
|
+
const arr = Array.isArray(b) ? b : [b]
|
|
261
|
+
const r = /(^value type error: expected)|(^Cannot compare a )/
|
|
262
|
+
// /(^value type error: expected)|(^Type error: operator cannot be applied to operands of type)|(^Cannot compare when the left-hand-side value is of type)|(^Not a)/
|
|
263
|
+
for (const curr of arr) {
|
|
264
|
+
expect(() => f(a, curr)).toThrowError(r)
|
|
265
|
+
expect(() => f(curr, a)).toThrowError(r)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
test('emits erros when numeric operations are applied to a boolean (either lhs or rhs)', () => {
|
|
270
|
+
check(five, t, (x, y) => x.plus(y))
|
|
271
|
+
check(five, t, (x, y) => x.minus(y))
|
|
272
|
+
check(five, t, (x, y) => x.times(y))
|
|
273
|
+
check(five, t, (x, y) => x.over(y))
|
|
274
|
+
check(five, t, (x, y) => x.power(y))
|
|
275
|
+
check(five, t, (x, y) => x.modulo(y))
|
|
276
|
+
check(five, t, (x, y) => x.order(y))
|
|
277
|
+
check(t, t, x => x.negate())
|
|
278
|
+
expect(1).toEqual(1) // make the linter happy
|
|
279
|
+
})
|
|
280
|
+
test('emits erros when boolean operations are applied to a number (either lhs or rhs)', () => {
|
|
281
|
+
check(five, f, (x, y) => x.or(() => y))
|
|
282
|
+
check(five, t, (x, y) => x.and(() => y))
|
|
283
|
+
check(five, five, x => x.not())
|
|
284
|
+
expect(1).toEqual(1) // make the linter happy
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
describe('foreign code calls', () => {
|
|
288
|
+
test('invokes the given function', () => {
|
|
289
|
+
const indexOf = Value.foreign(s => 'the quick brown fox jumps over the lazy dog'.indexOf(s.assertStr()))
|
|
290
|
+
expect(indexOf.call([Value.str('quick')], err).export()).toEqual(4)
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
describe('string operatios', () => {
|
|
294
|
+
test('.length', () => {
|
|
295
|
+
expect(Value.str('four scores AND seven').access('length', notFromHere).export()).toEqual(21)
|
|
296
|
+
})
|
|
297
|
+
test.each([
|
|
298
|
+
['at', [Value.num(10)], 'e'],
|
|
299
|
+
['at', [Value.num(-4)], 'v'],
|
|
300
|
+
['charAt', [Value.num(10)], 'e'],
|
|
301
|
+
['concat', [Value.str('years')], ' four scores AND seven years'],
|
|
302
|
+
['endsWith', [Value.str('seven ')], true],
|
|
303
|
+
['endsWith', [Value.str('years')], false],
|
|
304
|
+
['includes', [Value.str('scores')], true],
|
|
305
|
+
['includes', [Value.str('years')], false],
|
|
306
|
+
['indexOf', [Value.str('e')], 10],
|
|
307
|
+
['lastIndexOf', [Value.str('e')], 20],
|
|
308
|
+
['match', [Value.str('r|f')], ['f']],
|
|
309
|
+
['matchAll', [Value.str('r|f')], [['f'], ['r'], ['r']]],
|
|
310
|
+
['padEnd', [Value.num(25), Value.str('#')], ' four scores AND seven ##'],
|
|
311
|
+
['padStart', [Value.num(25), Value.str('#')], '## four scores AND seven '],
|
|
312
|
+
['repeat', [Value.num(3)], ' four scores AND seven four scores AND seven four scores AND seven '],
|
|
313
|
+
['replace', [Value.str('o'), Value.str('#')], ' f#ur scores AND seven '],
|
|
314
|
+
['replaceAll', [Value.str('o'), Value.str('#')], ' f#ur sc#res AND seven '],
|
|
315
|
+
['search', [Value.str('sco..s')], 6],
|
|
316
|
+
['slice', [Value.num(13), Value.num(-7)], 'AND'],
|
|
317
|
+
['split', [Value.str(' ')], ['', 'four', 'scores', 'AND', 'seven', '']],
|
|
318
|
+
['startsWith', [Value.str(' four')], true],
|
|
319
|
+
['startsWith', [Value.str('seven')], false],
|
|
320
|
+
['substring', [Value.num(6), Value.num(12)], 'scores'],
|
|
321
|
+
['substring', [Value.num(13), Value.num(-7)], ' four scores '],
|
|
322
|
+
['toLowerCase', [], ' four scores and seven '],
|
|
323
|
+
['toUpperCase', [], ' FOUR SCORES AND SEVEN '],
|
|
324
|
+
['trim', [], 'four scores AND seven'],
|
|
325
|
+
['trimEnd', [], ' four scores AND seven'],
|
|
326
|
+
['trimStart', [], 'four scores AND seven '],
|
|
327
|
+
])('provides the .%s() method', (name, args, expected) => {
|
|
328
|
+
const callee = Value.str(' four scores AND seven ').access(name, notFromHere)
|
|
329
|
+
const actual = callee.call(args, err)
|
|
330
|
+
expect(actual.export()).toEqual(expected)
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
describe('array operations', () => {
|
|
334
|
+
test('.length', () => {
|
|
335
|
+
expect(
|
|
336
|
+
Value.arr([Value.str('foo'), Value.str('bar'), Value.str('foo'), Value.str('goo')])
|
|
337
|
+
.access('length', notFromHere)
|
|
338
|
+
.export(),
|
|
339
|
+
).toEqual(4)
|
|
340
|
+
})
|
|
341
|
+
test.each([
|
|
342
|
+
['at', [Value.num(-1)], 'goo'],
|
|
343
|
+
['at', [Value.num(4)], undefined],
|
|
344
|
+
['concat', [Value.arr([Value.str('boo'), Value.str('poo')])], ['foo', 'bar', 'foo', 'goo', 'boo', 'poo']],
|
|
345
|
+
[
|
|
346
|
+
'entries',
|
|
347
|
+
[],
|
|
348
|
+
[
|
|
349
|
+
[0, 'foo'],
|
|
350
|
+
[1, 'bar'],
|
|
351
|
+
[2, 'foo'],
|
|
352
|
+
[3, 'goo'],
|
|
353
|
+
],
|
|
354
|
+
],
|
|
355
|
+
// TODO(imaman): ['find', [Value.foreign(v => v.assertStr() === 'lorem ipsum')], ??]"",
|
|
356
|
+
['includes', [Value.str('bar')], true],
|
|
357
|
+
['includes', [Value.str('lorem-ipsum')], false],
|
|
358
|
+
['indexOf', [Value.str('goo')], 3],
|
|
359
|
+
['join', [Value.str('; ')], 'foo; bar; foo; goo'],
|
|
360
|
+
['lastIndexOf', [Value.str('foo')], 2],
|
|
361
|
+
['lastIndexOf', [Value.str('lorem ipsum')], -1],
|
|
362
|
+
['reverse', [], ['goo', 'foo', 'bar', 'foo']],
|
|
363
|
+
['slice', [Value.num(1), Value.num(2)], ['bar']],
|
|
364
|
+
['slice', [Value.num(1), Value.num(3)], ['bar', 'foo']],
|
|
365
|
+
['slice', [Value.num(2), Value.num(4)], ['foo', 'goo']],
|
|
366
|
+
])('provides the .%s() method', (name, args, expected) => {
|
|
367
|
+
const input = Value.arr([Value.str('foo'), Value.str('bar'), Value.str('foo'), Value.str('goo')])
|
|
368
|
+
const before = JSON.parse(JSON.stringify(input))
|
|
369
|
+
const callee = input.access(name, notFromHere)
|
|
370
|
+
const actual = callee.call(args, err)
|
|
371
|
+
expect(actual.export()).toEqual(expected)
|
|
372
|
+
// Make sure the input array was not accidentally mutated.
|
|
373
|
+
expect(JSON.parse(JSON.stringify(input))).toEqual(before)
|
|
374
|
+
})
|
|
375
|
+
test('.flat() flattens', () => {
|
|
376
|
+
const input = Value.arr([Value.arr([Value.str('a'), Value.str('b')]), Value.str('c')])
|
|
377
|
+
const callee = input.access('flat', notFromHere)
|
|
378
|
+
const actual = callee.call([], err)
|
|
379
|
+
expect(actual.export()).toEqual(['a', 'b', 'c'])
|
|
380
|
+
})
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
test.todo('array.sort()')
|
|
384
|
+
test.todo('what happens when we get an undefined from a foreign call (like Array.get())')
|
|
385
|
+
test.todo('access to non-existing string method (a sad path test)')
|
|
386
|
+
test.todo('access to non-existing array method (a sad path test)')
|
|
387
|
+
})
|
package/main.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(()=>{"use strict";var e={166:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.span=t.show=void 0;const n=r(29),s=r(434);t.show=function e(t){if(Array.isArray(t))return t.map((t=>e(t))).join(", ");if("arrayLiteral"===t.tag)return`[${t.parts.map((t=>"element"===t.tag?e(t.v):"spread"===t.tag?`...${e(t.v)}`:void(0,n.shouldNeverHappen)(t))).join(", ")}]`;if("binaryOperator"===t.tag)return`(${e(t.lhs)} ${t.operator} ${e(t.rhs)})`;if("dot"===t.tag)return`${e(t.receiver)}.${e(t.ident)}`;if("export*"===t.tag)return"(export*)";if("ternary"===t.tag)return`${e(t.condition)} ? ${e(t.positive)} : ${e(t.negative)}`;if("functionCall"===t.tag)return`${e(t.callee)}(${e(t.actualArgs)})`;if("ident"===t.tag)return t.t.text;if("if"===t.tag)return`if (${e(t.condition)}) ${e(t.positive)} else ${e(t.negative)}`;if("indexAccess"===t.tag)return`${e(t.receiver)}[${e(t.index)}]`;if("lambda"===t.tag)return`fun (${e(t.formalArgs)}) ${e(t.body)}`;if("literal"===t.tag)return(0,s.switchOn)(t.type,{bool:()=>t.t.text,num:()=>t.t.text,sink:()=>"sink","sink!":()=>"sink!","sink!!":()=>"sink!!",str:()=>`'${t.t.text}'`});if("objectLiteral"===t.tag)return`{${t.parts.map((t=>"computedName"===t.tag?`[${e(t.k)}]: ${e(t.v)}`:"hardName"===t.tag?`${e(t.k)}: ${e(t.v)}`:"spread"===t.tag?`...${e(t.o)}`:void(0,n.shouldNeverHappen)(t))).join(", ")}}`;if("topLevelExpression"===t.tag){const r=t.definitions.map((t=>`let ${e(t.ident)} = ${e(t.value)}`)).join("; ");return`${r?r+";":""}${r&&t.computation?" ":""}${t.computation?e(t.computation):""}`}if("unaryOperator"===t.tag)return`${t.operator}${e(t.operand)}`;if("unit"===t.tag){const r=t.imports.map((t=>`import * as ${e(t.ident)} from '${t.pathToImportFrom.text}';`)).join("\n");return`${r?r+"\n":""}${e(t.expression)}`}(0,n.shouldNeverHappen)(t)},t.span=function e(t){const r=(e,t)=>({from:e.from,to:t.to}),s=e=>({from:e.location,to:{offset:e.location.offset+e.text.length-1}});if("arrayLiteral"===t.tag)return r(s(t.start),s(t.end));if("binaryOperator"===t.tag)return r(e(t.lhs),e(t.rhs));if("dot"===t.tag)return r(e(t.receiver),e(t.ident));if("functionCall"===t.tag)return r(e(t.callee),s(t.end));if("ident"===t.tag)return s(t.t);if("export*"===t.tag)return{from:{offset:0},to:{offset:0}};if("if"===t.tag)return r(e(t.condition),e(t.negative));if("indexAccess"===t.tag)return r(e(t.receiver),e(t.index));if("lambda"===t.tag)return r(s(t.start),e(t.body));if("ternary"===t.tag)return r(e(t.condition),e(t.negative));if("literal"===t.tag)return s(t.t);if("objectLiteral"===t.tag)return r(s(t.start),s(t.end));if("topLevelExpression"===t.tag){if(t.computation){const n=t.definitions.find(Boolean),o=e(t.computation);return r(n?s(n.start):o,o)}if(t.definitions.length){const n=t.definitions[0],o=t.definitions[t.definitions.length-1];return r(s(n.start),e(o.value))}return{from:{offset:0},to:{offset:0}}}if("unaryOperator"===t.tag)return r(s(t.operatorToken),e(t.operand));if("unit"===t.tag){const n=t.imports.find(Boolean),o=e(t.expression);return r(n?s(n.start):o,o)}(0,n.shouldNeverHappen)(t)}},883:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.extractMessage=void 0,t.extractMessage=function(e){return e.message}},465:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.failMe=void 0,t.failMe=function(e){if(!e)throw new Error("This expression must never be evaluated");throw new Error(`Bad value: ${e}`)}},855:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.findArrayMethod=void 0;const n=r(669);function s(e){const t=[];for(const r of e){const e=n.Value.from(r),s=e.unwrap();Array.isArray(s)?t.push(...s):t.push(e)}return t}t.findArrayMethod=function(e,t,r){const o=e=>(...t)=>r(e,t.map((e=>n.Value.from(e)))),i=e=>(...t)=>r(e,t.map((e=>n.Value.from(e)))).assertBool();if("at"===t)return n.Value.foreign((t=>e.at(t.assertNum())));if("concat"===t)return n.Value.foreign((t=>e.concat(t.assertArr())));if("entries"===t)return n.Value.foreign((()=>[...e.entries()]));if("every"===t)return n.Value.foreign((t=>e.every(i(t))));if("filter"===t)return n.Value.foreign((t=>e.filter(i(t))));if("find"===t)return n.Value.foreign((t=>e.find(i(t))));if("findIndex"===t)return n.Value.foreign((t=>e.findIndex(i(t))));if("flatMap"===t)return n.Value.foreign((t=>s(e.map(o(t)))));if("flat"===t)return n.Value.foreign((()=>s(e)));if("includes"===t)return n.Value.foreign((t=>e.some((e=>n.Value.from(e).equalsTo(t).isTrue()))));if("indexOf"===t)return n.Value.foreign((t=>e.findIndex((e=>n.Value.from(e).equalsTo(t).isTrue()))));if("join"===t)return n.Value.foreign((t=>e.join(t.assertStr())));if("lastIndexOf"===t)return n.Value.foreign((t=>{for(let r=e.length-1;r>=0;--r)if(n.Value.from(e[r]).equalsTo(t).isTrue())return r;return-1}));if("length"===t)return n.Value.num(e.length);if("map"===t)return n.Value.foreign((t=>e.map(o(t))));if("reverse"===t)return n.Value.foreign((()=>[...e].reverse()));if("reduce"===t)return n.Value.foreign(((t,r)=>e.reduce(o(t),r)));if("reduceRight"===t)return n.Value.foreign(((t,r)=>e.reduceRight(o(t),r)));if("slice"===t)return n.Value.foreign(((t,r)=>e.slice(t?.assertNum(),r?.assertNum())));if("some"===t)return n.Value.foreign((t=>e.some(i(t))));throw new Error(`Unrecognized array method: ${t}`)}},794:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.findStringMethod=void 0;const n=r(669);t.findStringMethod=function(e,t){const r=n.Value.toStringOrNumber(t);if("number"==typeof r)throw new Error("Index is of type number - not supported");if("at"===r)return n.Value.foreign((t=>e.at(t.assertNum())));if("charAt"===r)return n.Value.foreign((t=>e.charAt(t.assertNum())));if("concat"===r)return n.Value.foreign((t=>e.concat(t.assertStr())));if("endsWith"===r)return n.Value.foreign((t=>e.endsWith(t.assertStr())));if("includes"===r)return n.Value.foreign((t=>e.includes(t.assertStr())));if("indexOf"===r)return n.Value.foreign((t=>e.indexOf(t.assertStr())));if("lastIndexOf"===r)return n.Value.foreign((t=>e.lastIndexOf(t.assertStr())));if("length"===r)return n.Value.num(e.length);if("match"===r)return n.Value.foreign((t=>e.match(t.assertStr())));if("matchAll"===r)return n.Value.foreign((t=>[...e.matchAll(new RegExp(t.assertStr(),"g"))]));if("padEnd"===r)return n.Value.foreign(((t,r)=>e.padEnd(t.assertNum(),r?.assertStr())));if("padStart"===r)return n.Value.foreign(((t,r)=>e.padStart(t.assertNum(),r?.assertStr())));if("repeat"===r)return n.Value.foreign((t=>e.repeat(t.assertNum())));if("replace"===r)return n.Value.foreign(((t,r)=>e.replace(t.assertStr(),r.assertStr())));if("replaceAll"===r)return n.Value.foreign(((t,r)=>e.replaceAll(t.assertStr(),r.assertStr())));if("search"===r)return n.Value.foreign((t=>e.search(t.assertStr())));if("slice"===r)return n.Value.foreign(((t,r)=>e.slice(t?.assertNum(),r?.assertNum())));if("split"===r)return n.Value.foreign((t=>e.split(t.assertStr())));if("startsWith"===r)return n.Value.foreign((t=>e.startsWith(t.assertStr())));if("substring"===r)return n.Value.foreign(((t,r)=>e.substring(t.assertNum(),r?.assertNum())));if("toLowerCase"===r)return n.Value.foreign((()=>e.toLowerCase()));if("toUpperCase"===r)return n.Value.foreign((()=>e.toUpperCase()));if("trim"===r)return n.Value.foreign((()=>e.trim()));if("trimEnd"===r)return n.Value.foreign((()=>e.trimEnd()));if("trimStart"===r)return n.Value.foreign((()=>e.trimStart()));throw new Error(`Unrecognized string method: ${r}`)}},326:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var s=Object.getOwnPropertyDescriptor(t,r);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||n(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),s(r(212),t)},270:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Parser=void 0;const n=r(166),s=r(434);t.Parser=class{constructor(e){this.scanner=e}parse(){const e=this.unit();if(!this.scanner.eof())throw new Error(`Loitering input ${this.scanner.sourceRef}`);return e}unit(){return{tag:"unit",imports:this.imports(),expression:this.expression("TOP_LEVEL")}}imports(){const e=[];for(;;){const t=this.scanner.consumeIf("import");if(!t)return e;this.scanner.consume("*"),this.scanner.consume("as");const r=this.identifier();this.scanner.consume("from");const o=this.maybePrimitiveLiteral();if(void 0===o)throw new Error(`Expected a literal ${this.scanner.sourceRef}`);const i=()=>{throw new Error(`Expected a string literal ${this.scanner.sourceCode.sourceRef((0,n.span)(o))}`)};(0,s.switchOn)(o.type,{bool:i,num:i,str:()=>{},sink:i,"sink!":i,"sink!!":i}),e.push({start:t,ident:r,pathToImportFrom:o.t}),this.scanner.consumeIf(";")}}definitions(e){const t=[];for(;;){if("NESTED"===e&&this.scanner.headMatches("export "))throw new Error(`non-top-level definition cannot be export ${this.scanner.sourceRef}`);let r=this.scanner.consumeIf("let ");if(r||"TOP_LEVEL"!==e||(r=this.scanner.consumeIf("export let ")),!r)return t;const n=this.identifier();this.scanner.consume("=");const s=this.lambda();if(t.push({start:r,ident:n,value:s}),this.scanner.consumeIf(";"),!this.scanner.headMatches("let "))return t}}expression(e="NESTED"){const t=this.definitions(e);if("TOP_LEVEL"===e&&this.scanner.eof())return{tag:"topLevelExpression",definitions:t};this.scanner.consumeIf("return");const r=this.lambda();return 0===t.length?r:{tag:"topLevelExpression",definitions:t,computation:r}}lambda(){const e=this.scanner.consumeIf("fun");if(!e)return this.arrowFunction();this.scanner.consume("(");const t=[];if(this.scanner.consumeIf(")"));else for(;;){const e=this.identifier();if(t.push(e),this.scanner.consumeIf(")"))break;this.scanner.consume(",")}return{tag:"lambda",start:e,formalArgs:t,body:this.expression()}}arrowFunction(){if(this.scanner.headMatches("(",")","=>")){const e=this.scanner.consume("(");return this.scanner.consume(")"),this.scanner.consume("=>"),{tag:"lambda",start:e,formalArgs:[],body:this.lambdaBody()}}if(this.scanner.headMatches(o,"=>")){const e=this.identifier();this.scanner.consume("=>");const t=this.lambdaBody();return{tag:"lambda",start:e.t,formalArgs:[e],body:t}}if(this.scanner.headMatches("(",o,")","=>")){const e=this.scanner.consume("("),t=this.identifier();return this.scanner.consume(")"),this.scanner.consume("=>"),{tag:"lambda",start:e,formalArgs:[t],body:this.lambdaBody()}}if(this.scanner.headMatches("(",o,",")){const e=this.scanner.consume("("),t=[];for(;;){const e=this.identifier();if(t.push(e),this.scanner.consumeIf(")"))break;this.scanner.consume(",")}return this.scanner.consume("=>"),{tag:"lambda",start:e,formalArgs:t,body:this.lambdaBody()}}return this.ifExpression()}lambdaBody(){if(this.scanner.consumeIf("{")){const e=this.expression();return this.scanner.consume("}"),e}return this.expression()}ifExpression(){if(!this.scanner.consumeIf("if"))return this.ternary();this.scanner.consume("(");const e=this.expression();this.scanner.consume(")");const t=this.expression();return this.scanner.consume("else"),{tag:"if",condition:e,positive:t,negative:this.expression()}}ternary(){const e=this.unsink();if(!this.scanner.consumeIf("? "))return e;const t=this.expression();return this.scanner.consume(":"),{tag:"ternary",condition:e,positive:t,negative:this.expression()}}unsink(){const e=this.or();return this.scanner.consumeIf("??")?{tag:"binaryOperator",operator:"??",lhs:e,rhs:this.unsink()}:e}or(){const e=this.and();return this.scanner.consumeIf("||")?{tag:"binaryOperator",operator:"||",lhs:e,rhs:this.or()}:e}and(){const e=this.equality();return this.scanner.consumeIf("&&")?{tag:"binaryOperator",operator:"&&",lhs:e,rhs:this.and()}:e}equality(){const e=this.comparison();return this.scanner.consumeIf("==")?{tag:"binaryOperator",operator:"==",lhs:e,rhs:this.equality()}:this.scanner.consumeIf("!=")?{tag:"binaryOperator",operator:"!=",lhs:e,rhs:this.equality()}:e}comparison(){const e=this.addition();return this.scanner.consumeIf(">=")?{tag:"binaryOperator",operator:">=",lhs:e,rhs:this.comparison()}:this.scanner.consumeIf("<=")?{tag:"binaryOperator",operator:"<=",lhs:e,rhs:this.comparison()}:this.scanner.consumeIf(">")?{tag:"binaryOperator",operator:">",lhs:e,rhs:this.comparison()}:this.scanner.consumeIf("<")?{tag:"binaryOperator",operator:"<",lhs:e,rhs:this.comparison()}:e}addition(){const e=this.multiplication();return this.scanner.consumeIf("+")?{tag:"binaryOperator",operator:"+",lhs:e,rhs:this.addition()}:this.scanner.consumeIf("-")?{tag:"binaryOperator",operator:"-",lhs:e,rhs:this.addition()}:e}multiplication(){const e=this.power();return this.scanner.consumeIf("*")?{tag:"binaryOperator",operator:"*",lhs:e,rhs:this.multiplication()}:this.scanner.consumeIf("/")?{tag:"binaryOperator",operator:"/",lhs:e,rhs:this.multiplication()}:this.scanner.consumeIf("%")?{tag:"binaryOperator",operator:"%",lhs:e,rhs:this.multiplication()}:e}power(){const e=this.unary();return this.scanner.consumeIf("**")?{tag:"binaryOperator",operator:"**",lhs:e,rhs:this.power()}:e}unary(){let e=this.scanner.consumeIf("!");return e?{tag:"unaryOperator",operand:this.unary(),operator:"!",operatorToken:e}:(e=this.scanner.consumeIf("+"),e?{tag:"unaryOperator",operand:this.unary(),operator:"+",operatorToken:e}:(e=this.scanner.consumeIf("-"),e?{tag:"unaryOperator",operand:this.unary(),operator:"-",operatorToken:e}:this.call()))}call(){const e=this.memberAccess();if(!this.scanner.consumeIf("("))return e;const{actualArgs:t,end:r}=this.actualArgList();return{tag:"functionCall",actualArgs:t,callee:e,end:r}}actualArgList(){const e=[],t=this.scanner.consumeIf(")");if(t)return{actualArgs:e,end:t};for(;;){const t=this.expression();e.push(t);let r=this.scanner.consumeIf(")");if(r)return{actualArgs:e,end:r};if(this.scanner.consume(","),r=this.scanner.consumeIf(")"),r)return{actualArgs:e,end:r}}}memberAccess(){let e=this.parenthesized();for(;;)if(this.scanner.consumeIf("."))e={tag:"dot",receiver:e,ident:this.identifier()};else if(this.scanner.consumeIf("["))e={tag:"indexAccess",receiver:e,index:this.expression()},this.scanner.consume("]");else{if(!this.scanner.consumeIf("("))return e;{const{actualArgs:t,end:r}=this.actualArgList();e={tag:"functionCall",actualArgs:t,callee:e,end:r}}}}parenthesized(){if(this.scanner.consumeIf("(")){const e=this.expression();return this.scanner.consume(")"),e}return this.literalOrIdent()}literalOrIdent(){const e=this.maybeLiteral()??this.maybeIdentifier();if(!e)throw new Error(`Unparsable input ${this.scanner.sourceRef}`);return e}maybeLiteral(){return this.maybePrimitiveLiteral()??this.maybeCompositeLiteral()}maybePrimitiveLiteral(){let e=this.scanner.consumeIf("sink!!")||this.scanner.consumeIf("undefined!!");return e?{tag:"literal",type:"sink!!",t:e}:(e=this.scanner.consumeIf("sink!")||this.scanner.consumeIf("undefined!"),e?{tag:"literal",type:"sink!",t:e}:(e=this.scanner.consumeIf("sink")||this.scanner.consumeIf("undefined"),e?{tag:"literal",type:"sink",t:e}:(e=this.scanner.consumeIf("true"),e?{tag:"literal",type:"bool",t:e}:(e=this.scanner.consumeIf("false"),e?{tag:"literal",type:"bool",t:e}:(e=this.scanner.consumeIf(/([0-9]*[.])?[0-9]+/),e?{tag:"literal",type:"num",t:e}:this.scanner.consumeIf('"',!1)?(e=this.scanner.consume(/[^"]*/),this.scanner.consume('"'),{tag:"literal",type:"str",t:e}):this.scanner.consumeIf("'",!1)?(e=this.scanner.consume(/[^']*/),this.scanner.consume("'"),{tag:"literal",type:"str",t:e}):void 0)))))}maybeCompositeLiteral(){let e=this.scanner.consumeIf("[");return e?this.arrayBody(e):(e=this.scanner.consumeIf("{"),e?this.objectBody(e):void 0)}arrayBody(e){const t=this.scanner.consumeIf("]");if(t)return{tag:"arrayLiteral",start:e,parts:[],end:t};const r=[];for(;;){if(this.scanner.consumeIf(",")){const t=this.scanner.consumeIf("]");if(t)return{tag:"arrayLiteral",start:e,parts:r,end:t};continue}if(this.scanner.consumeIf("..."))r.push({tag:"spread",v:this.expression()});else{const e=this.expression();r.push({tag:"element",v:e})}let t=this.scanner.consumeIf("]");if(t)return{tag:"arrayLiteral",start:e,parts:r,end:t};if(this.scanner.consume(","),t=this.scanner.consumeIf("]"),t)return{tag:"arrayLiteral",start:e,parts:r,end:t}}}objectBody(e){const t=this.scanner.consumeIf("}");if(t)return{tag:"objectLiteral",start:e,parts:[],end:t};const r=[];for(;;){if(this.scanner.consumeIf("..."))r.push({tag:"spread",o:this.expression()});else if(this.scanner.consumeIf("[")){const e=this.expression();this.scanner.consume("]"),this.scanner.consume(":");const t=this.expression();r.push({tag:"computedName",k:e,v:t})}else{const e=this.identifier();this.scanner.consume(":");const t=this.expression();r.push({tag:"hardName",k:e,v:t})}let t=this.scanner.consumeIf("}");if(t)return{tag:"objectLiteral",start:e,parts:r,end:t};if(this.scanner.consume(","),t=this.scanner.consumeIf("}"),t)return{tag:"objectLiteral",start:e,parts:r,end:t}}}identifier(){const e=this.maybeIdentifier();if(!e)throw new Error(`Expected an identifier ${this.scanner.sourceRef}`);return e}maybeIdentifier(){const e=this.scanner.consumeIf(o);if(e)return{tag:"ident",t:e}}};const o=/[a-zA-Z][0-9A-Za-z_]*/},351:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ResultSinkImpl=void 0,t.ResultSinkImpl=class{constructor(e,t){this.sink=e,this.sourceCode=t,this.tag="sink"}get where(){return this.sink.span()}get trace(){const e=this.sink.trace();if(e)return this.sourceCode.formatTrace(e)}get symbols(){return this.sink.symbols()?.export()}get message(){return`Evaluated to sink: ${this.trace??this.sourceCode.sourceRef(this.where)}`}}},257:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var s=Object.getOwnPropertyDescriptor(t,r);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&n(t,e,r);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Runtime=void 0;const i=r(166),a=r(883),u=r(465),c=r(29),l=o(r(884)),f=r(434),h=r(669);class p{constructor(e,t,r){this.symbol=e,this.placeholder=t,this.earlier=r}lookup(e){if(this.symbol===e){const e=this.placeholder.destination;if(void 0===e)throw new Error(`Unresolved definition: ${this.symbol}`);return e}return this.earlier.lookup(e)}export(){const e=this.earlier.export();return e[this.symbol]=this.placeholder.destination?.export()??(0,u.failMe)(`Unbounded symbol: ${this.symbol}`),e}exportValue(){const e=this.earlier.exportValue();return e[this.symbol]=this.placeholder.destination??(0,u.failMe)(`Unbounded symbol: ${this.symbol}`),e}}class d{lookup(e){throw new Error(`Symbol ${e} was not found`)}export(){return{}}exportValue(){return{}}}t.Runtime=class{constructor(e,t="quiet",r,n,s){this.root=e,this.verbosity=t,this.preimports=r,this.getAstOf=n,this.args=s,this.stack=void 0}buildInitialSymbolTable(e){const t=new d,r=h.Value.foreign((e=>e.keys())),n=h.Value.foreign((e=>e.entries())),s=h.Value.foreign((e=>e.fromEntries()));let o=new p("Object",{destination:h.Value.obj({keys:r,entries:n,fromEntries:s})},t);e&&(o=new p("args",{destination:h.Value.from(this.args)},o));for(const[e,t]of Object.entries(this.preimports))o=new p(e,{destination:t},o);return o}compute(){try{return{value:this.evalNode(this.root,this.buildInitialSymbolTable(!0))}}catch(e){const t=[];for(let e=this.stack;e;e=e?.next)t.push(e.ast);return{expressionTrace:t,errorMessage:(0,a.extractMessage)(e),stack:e.stack}}}evalNode(e,t){this.stack=l.push(e,this.stack);let r=this.evalNodeImpl(e,t);return r.isSink()&&!r.span()&&(r=r.bindToSpan((0,i.span)(e))),(0,f.switchOn)(this.verbosity,{quiet:()=>{},trace:()=>{console.log(`output of <|${(0,i.show)(e)}|> is ${JSON.stringify(r)} // ${e.tag}`)}}),this.stack=l.pop(this.stack),r}importDefinitions(e){const t=this.getAstOf(e),r=t.expression,n=t.imports;if("arrayLiteral"===r.tag||"binaryOperator"===r.tag||"dot"===r.tag||"export*"===r.tag||"functionCall"===r.tag||"ident"===r.tag||"if"===r.tag||"ternary"===r.tag||"indexAccess"===r.tag||"lambda"===r.tag||"literal"===r.tag||"objectLiteral"===r.tag||"unaryOperator"===r.tag||"unit"===r.tag)return h.Value.obj({});if("topLevelExpression"===r.tag){const e={tag:"unit",imports:n,expression:{tag:"topLevelExpression",definitions:r.definitions,computation:{tag:"export*"}}};return this.evalNode(e,this.buildInitialSymbolTable(!1))}(0,c.shouldNeverHappen)(r)}evalNodeImpl(e,t){if("unit"===e.tag){let r=t;for(const t of e.imports){const e=this.importDefinitions(t.pathToImportFrom.text);r=new p(t.ident.t.text,{destination:e},r)}return this.evalNode(e.expression,r)}if("topLevelExpression"===e.tag){let r=t;for(const t of e.definitions){const e=t.ident.t.text,n={destination:void 0};r=new p(e,n,r);const s=this.evalNode(t.value,r);n.destination=s}return e.computation?this.evalNode(e.computation,r):h.Value.str("")}if("export*"===e.tag)return h.Value.obj(t.exportValue());if("binaryOperator"===e.tag){const r=this.evalNode(e.lhs,t);if("||"===e.operator)return r.or((()=>this.evalNode(e.rhs,t)));if("&&"===e.operator)return r.and((()=>this.evalNode(e.rhs,t)));if("??"===e.operator)return r.unsink((()=>this.evalNode(e.rhs,t)));const n=this.evalNode(e.rhs,t);if("!="===e.operator)return r.equalsTo(n).not();if("=="===e.operator)return r.equalsTo(n);if("<="===e.operator)return r.order(n).isToZero("<=");if("<"===e.operator)return r.order(n).isToZero("<");if(">="===e.operator)return r.order(n).isToZero(">=");if(">"===e.operator)return r.order(n).isToZero(">");if("%"===e.operator)return r.modulo(n);if("*"===e.operator)return r.times(n);if("**"===e.operator)return r.power(n);if("+"===e.operator)return r.plus(n);if("-"===e.operator)return r.minus(n);if("/"===e.operator)return r.over(n);(0,c.shouldNeverHappen)(e.operator)}if("unaryOperator"===e.tag){const r=this.evalNode(e.operand,t);if("!"===e.operator)return r.not();if("+"===e.operator)return h.Value.num(0).plus(r);if("-"===e.operator)return r.negate();(0,c.shouldNeverHappen)(e.operator)}if("ident"===e.tag)return t.lookup(e.t.text);if("literal"===e.tag){if("bool"===e.type)return h.Value.bool("true"===e.t.text);if("num"===e.type)return h.Value.num(Number(e.t.text));if("sink!!"===e.type)return h.Value.sink(void 0,this.stack,t);if("sink!"===e.type)return h.Value.sink(void 0,this.stack);if("sink"===e.type)return h.Value.sink();if("str"===e.type)return h.Value.str(e.t.text);(0,c.shouldNeverHappen)(e.type)}if("arrayLiteral"===e.tag){const r=[];for(const n of e.parts)if("element"===n.tag)r.push(this.evalNode(n.v,t));else if("spread"===n.tag){const e=this.evalNode(n.v,t);r.push(...e.assertArr())}else(0,c.shouldNeverHappen)(n);return h.Value.arr(r)}if("objectLiteral"===e.tag){const r=e.parts.flatMap((e=>{if("hardName"===e.tag)return[[e.k.t.text,this.evalNode(e.v,t)]];if("computedName"===e.tag)return[[this.evalNode(e.k,t).assertStr(),this.evalNode(e.v,t)]];if("spread"===e.tag){const r=this.evalNode(e.o,t);return Object.entries(r.assertObj())}(0,c.shouldNeverHappen)(e)}));return h.Value.obj(Object.fromEntries(r))}if("lambda"===e.tag)return h.Value.lambda(e,t);if("functionCall"===e.tag){const r=e.actualArgs.map((e=>this.evalNode(e,t))),n=this.evalNode(e.callee,t);return this.call(n,r)}if("if"===e.tag||"ternary"===e.tag)return this.evalNode(e.condition,t).ifElse((()=>this.evalNode(e.positive,t)),(()=>this.evalNode(e.negative,t)));if("dot"===e.tag){const r=this.evalNode(e.receiver,t);if(null==r)throw new Error(`Cannot access attribute .${e.ident.t.text} of ${r}`);return r.access(e.ident.t.text,((e,t)=>this.call(e,t)))}if("indexAccess"===e.tag){const r=this.evalNode(e.receiver,t),n=this.evalNode(e.index,t);return r.access(n,((e,t)=>this.call(e,t)))}(0,c.shouldNeverHappen)(e)}call(e,t){return e.call(t,((e,r,n)=>{if(e.length>t.length)throw new Error(`Arg list length mismatch: expected ${e.length} but got ${t.length}`);const s=e.reduce(((e,r,n)=>new p(r,{destination:t[n]},e)),n);return this.evalNode(r,s)}))}}},756:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Scanner=void 0;class r{constructor(e,t=0){this.sourceCode=e,this.offset=t,0===this.offset&&this.eatWhitespace()}get sourceRef(){return this.sourceCode.sourceRef(this.sourceCode.expandToEndOfLine({offset:this.offset}))}curr(){return this.sourceCode.input.substring(this.offset)}eatWhitespace(){for(;;)if(!this.consumeIf(/\s*/,!1)){if(!this.consumeIf("//",!1))return;this.consume(/[^\n]*/,!1)}}eof(){return this.offset>=this.sourceCode.input.length}synopsis(){const e=this.curr();let t=e.substring(0,20);return t.length!==e.length&&(t=`${t}...`),{position:this.offset,lookingAt:t}}headMatches(...e){const t=new r(this.sourceCode,this.offset);for(const r of e)if(void 0===t.consumeIf(r,!0))return!1;return!0}consume(e,t=!0){const r=this.match(e);if(void 0===r)throw new Error(`Expected ${e} ${this.sourceRef}`);const n=this.offset;return this.offset+=r.length,t&&this.eatWhitespace(),{location:{offset:n},text:r}}consumeIf(e,t=!0){if(this.match(e))return this.consume(e,t)}match(e){if("string"==typeof e)return this.curr().startsWith(e)?e:void 0;const t=this.curr().match(e);return t&&0===t.index?t[0]:void 0}}t.Scanner=r},212:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.parse=t.Septima=void 0;const n=r(270),s=r(351),o=r(257),i=r(756),a=r(29),u=r(893);class c{static run(e,t,r={}){const n=t?.onSink??(e=>{throw new Error(e.message)}),s=(new c).compute(e,{},"quiet",r);return"ok"===s.tag?s.value:"sink"===s.tag?n(s):void(0,a.shouldNeverHappen)(s)}constructor(){}computeModule(e,t,r){const n=t(e),o=new u.SourceCode(n),i=this.computeImpl(o,"quiet",{},t,r);return i.isSink()?new s.ResultSinkImpl(i,o):{value:i.export(),tag:"ok"}}compute(e,t={},r="quiet",n){const o={};for(const[e,n]of Object.entries(t)){const t=new u.SourceCode(n),i=this.computeImpl(t,r,{},void 0,{});if(i.isSink()){const r=new s.ResultSinkImpl(i,t);throw new Error(`preimport (${e}) evaluated to sink: ${r.message}`)}o[e]=i}const i=new u.SourceCode(e),a=this.computeImpl(i,r,o,void 0,n);return a.isSink()?new s.ResultSinkImpl(a,i):{value:a.export(),tag:"ok"}}computeImpl(e,t,r,s,a){const u=new i.Scanner(e),c=l(new n.Parser(u)),f=new o.Runtime(c,t,r,(e=>{if(!s)throw new Error("cannot read modules");return l(s(e))}),a).compute();if(f.value)return f.value;const h=`${f.errorMessage} when evaluating:\n${e.formatTrace(f.expressionTrace)}`;throw new Error(h)}}function l(e){return("string"==typeof e?new n.Parser(new i.Scanner(new u.SourceCode(e))):e).parse()}t.Septima=c,t.parse=l},29:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.shouldNeverHappen=void 0,t.shouldNeverHappen=function(e){throw new Error(`This should never happen ${e}`)}},893:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SourceCode=void 0;const n=r(166);t.SourceCode=class{constructor(e){this.input=e}formatTrace(e){return` ${e.map((e=>this.sourceRef((0,n.span)(e)))).reverse().join("\n ")}`}sourceRefOfLocation(e){return this.sourceRef(this.expandToEndOfLine(e))}sourceRef(e){return e?`at ${this.formatSpan(e)} ${this.interestingPart(e)}`:"at <unknown location>"}formatSpan(e){const t=this.resolveLocation(e.from),r=this.resolveLocation(e.to);return t.line===r.line?`(${t.line+1}:${t.col+1}..${r.col+1})`:`(${t.line+1}:${t.col+1}..${r.line+1}:${r.col+1})`}interestingPart(e){const t=this.resolveLocation(e.from),r=this.resolveLocation(e.to),n=e=>e.replace(/^[\n]*/,"").replace(/[\n]*$/,""),s=this.lineAt(e.from);if(t.line!==r.line)return`${n(s).substring(0,80)}...`;const o=n(s.substring(t.col,r.col+1));return o.length<=80?o:`${o.substring(0,80)}...`}resolveLocation(e){const t=this.input.slice(0,e.offset);let r=0;for(let e=0;e<t.length;++e)"\n"===t[e]&&(r+=1);let n=0;for(let e=t.length-1;e>=0&&"\n"!==t[e];--e,++n);return{line:r,col:n}}expandToEndOfLine(e){let t=this.input.indexOf("\n",e.offset);return t<0&&(t=this.input.length-1),{from:e,to:{offset:t}}}lineAt(e){const t=this.input.lastIndexOf("\n",e.offset)+1,r=this.expandToEndOfLine(e).to;return this.input.substring(t,r.offset+1)}}},884:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.empty=t.pop=t.push=void 0,t.push=function(e,t){return{ast:e,next:t}},t.pop=function(e){if(void 0===e)throw new Error("Cannot pop from an empty stack");return e.next},t.empty=function(){}},434:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.switchOn=void 0,t.switchOn=function(e,t){return(0,t[e])()}},669:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Value=void 0;const n=r(166),s=r(465),o=r(855),i=r(794),a=r(29),u=r(434);function c(e){return JSON.stringify(e)}const l=(e,...t)=>(r,n,s)=>{if(0===t.length)throw new Error(`value type error: expected ${e} but found ${c(s)}`);throw new Error(`value type error: expected either ${t.join(", ")} or ${e} but found ${c(s)}`)};function f(e,t){const r=e.inner;if("arr"===r.tag)return t.arr(r.val,r.tag,e);if("bool"===r.tag)return t.bool(r.val,r.tag,e);if("foreign"===r.tag)return t.foreign(r.val,r.tag,e);if("lambda"===r.tag)return t.lambda(r.val,r.tag,e);if("num"===r.tag)return t.num(r.val,r.tag,e);if("obj"===r.tag)return t.obj(r.val,r.tag,e);if("sink"===r.tag){if(!t.sink)throw new Error("Cannot evaluate a sink value");return t.sink(r.val,r.tag,e)}if("str"===r.tag)return t.str(r.val,r.tag,e);(0,a.shouldNeverHappen)(r)}function h(e,t){return e.isSink()?e:p.from(f(e,t))}class p{constructor(e){this.inner=e}static bool(e){return new p({val:e,tag:"bool"})}static num(e){return new p({val:e,tag:"num"})}static sink(e,t,r){return new p({val:void 0,tag:"sink",...e?{span:e}:{},...t?{trace:t}:{},...r?{symbols:r}:{}})}static str(e){return new p({val:e,tag:"str"})}static arr(e){return new p({val:e,tag:"arr"})}static obj(e){return new p({val:e,tag:"obj"})}static lambda(e,t){return new p({val:{ast:e,table:t},tag:"lambda"})}static foreign(e){return new p({tag:"foreign",val:e})}isSink(){return"sink"===this.inner.tag}unwrap(){return this.inner.val}assertBool(){const e=l("bool");return f(this,{arr:e,bool:e=>e,foreign:e,lambda:e,num:e,obj:e,sink:e,str:e})}assertNum(){const e=l("num");return f(this,{arr:e,bool:e,foreign:e,lambda:e,num:e=>e,obj:e,sink:e,str:e})}assertStr(){const e=l("str");return f(this,{arr:e,bool:e,foreign:e,lambda:e,num:e,obj:e,sink:e,str:e=>e})}assertArr(){const e=l("arr");return f(this,{arr:e=>e,bool:e,foreign:e,lambda:e,num:e,obj:e,sink:e,str:e})}assertObj(){const e=l("obj");return f(this,{arr:e,bool:e,foreign:e,lambda:e,num:e,obj:e=>e,sink:e,str:e})}assertLambda(){const e=l("lambda");return f(this,{arr:e,bool:e,foreign:e,lambda:e=>e,num:e,obj:e,sink:e,str:e})}isLambda(){return"lambda"===this.inner.tag}ifElse(e,t){const r=l("bool");return h(this,{arr:r,bool:r=>r?e():t(),foreign:r,lambda:r,num:r,obj:r,str:r})}bindToSpan(e){const t=this.inner;if("sink"!==t.tag)throw new Error(`Not supported on type ${this.inner.tag}`);return p.sink(e,t.trace,t.symbols)}trace(){const e=this.inner;if("sink"!==e.tag)return;const t=[];for(let r=e.trace;void 0!==r;r=r?.next)t.push(r.ast);return 0===t.length?void 0:t}symbols(){const e=this.inner;if("sink"===e.tag)return e.symbols}span(){const e=this.inner;if("sink"===e.tag)return e.span}or(e){const t=l("bool");return h(this,{arr:t,bool:r=>r||h(e(),{arr:t,bool:e=>e,foreign:t,lambda:t,num:t,obj:t,str:t}),foreign:t,lambda:t,num:t,obj:t,str:t})}and(e){const t=l("bool");return h(this,{arr:t,bool:r=>r&&h(e(),{arr:t,bool:e=>e,foreign:t,lambda:t,num:t,obj:t,str:t}),foreign:t,lambda:t,num:t,obj:t,str:t})}unsink(e){return this.isSink()?e():this}equalsTo(e){if(this.inner.tag!==e.inner.tag)return p.bool(!1);const t=JSON.stringify(this.inner.val)===JSON.stringify(e.inner.val);return p.bool(t)}not(){const e=l("bool");return h(this,{arr:e,bool:e=>!e,foreign:e,lambda:e,num:e,obj:e,str:e})}binaryNumericOperator(e,t,r){const n=l("num");return h(e,{arr:n,bool:n,foreign:n,lambda:n,num:e=>h(t,{arr:n,bool:n,foreign:n,lambda:n,num:t=>r(e,t),obj:n,str:n}),obj:n,str:n})}plus(e){const t=l("num");return h(this,{arr:t,bool:t,foreign:t,lambda:t,num:r=>h(e,{arr:t,bool:t,foreign:t,lambda:t,num:e=>r+e,obj:t,str:t}),obj:t,str:t=>h(e,{arr:e=>t+e,bool:e=>t+e,foreign:e=>t+e,lambda:e=>t+e,num:e=>t+e,obj:e=>t+e,str:e=>t+e})})}minus(e){return this.binaryNumericOperator(this,e,((e,t)=>e-t))}times(e){return this.binaryNumericOperator(this,e,((e,t)=>e*t))}power(e){return this.binaryNumericOperator(this,e,((e,t)=>e**t))}over(e){return this.binaryNumericOperator(this,e,((e,t)=>e/t))}modulo(e){return this.binaryNumericOperator(this,e,((e,t)=>e%t))}negate(){return p.num(0).minus(this)}isToZero(e){const t=l("num");return h(this,{arr:t,bool:t,foreign:t,lambda:t,num:t=>(0,u.switchOn)(e,{"<":()=>p.bool(t<0),"<=":()=>p.bool(t<=0),"==":()=>p.bool(0==t),"!=":()=>p.bool(0!==t),">=":()=>p.bool(t>=0),">":()=>p.bool(t>0)}),obj:t,str:t})}isTrue(){const e=l("bool");return f(this,{arr:e,bool:e=>e,foreign:e,lambda:e,num:e,obj:e,sink:e,str:e})}isZero(){const e=l("num");return f(this,{arr:e,bool:e,foreign:e,lambda:e,num:e=>0===e,obj:e,sink:e,str:e})}order(e){const t=(e,t)=>{throw new Error(`Cannot compare a value of type ${t}`)};if(this.inner.tag!==e.inner.tag)throw new Error(`Cannot compare a ${this.inner.tag} value with a value of another type (${e.inner.tag})`);return h(this,{arr:t,bool:t=>{const r=e.assertBool();return t&&!r?1:!t&&r?-1:0},foreign:t,lambda:t,num:()=>{const t=this.minus(e).assertNum();return t<0?-1:t>0?1:0},obj:t,str:t=>{const r=e.assertStr(),n=t.localeCompare(r);return n<0?-1:n>0?1:0}})}static toStringOrNumber(e){if("string"==typeof e)return e;const t=l("str","num");return f(e,{arr:t,bool:t,foreign:t,lambda:t,num:e=>e,obj:t,sink:t,str:e=>e})}access(e,t){const r=l("obj","str","arr");return h(this,{arr:r=>{if("string"==typeof e)return(0,o.findArrayMethod)(r,e,t);const n=e.assertNum();if(n<0||n>r.length)throw new Error(`array index (${n}) is out of bounds (length = ${r.length})`);return r[n]},bool:r,foreign:r,lambda:r,num:r,obj:t=>t[p.toStringOrNumber(e)],str:t=>(0,i.findStringMethod)(t,e)})}call(e,t){const r=l("lambda","foreign");return h(this,{arr:r,bool:r,foreign:t=>d(t(...e)),lambda:e=>t(e.ast.formalArgs.map((e=>e.t.text)),e.ast.body,e.table),num:r,obj:r,str:r})}keys(){const e=l("obj");return h(this,{arr:e,bool:e,foreign:e,lambda:e,num:e,obj:e=>Object.keys(e),str:e})}entries(){const e=l("obj");return h(this,{arr:e,bool:e,foreign:e,lambda:e,num:e,obj:e=>Object.entries(e),str:e})}fromEntries(){const e=l("arr");return h(this,{arr:t=>Object.fromEntries(t.map((t=>f(t,{arr:e=>(2===e.length||(0,s.failMe)("each entry must be a [key, value] pair"),[e[0].assertStr(),e[1]]),bool:e,foreign:e,lambda:e,num:e,obj:e,sink:e,str:e})))),bool:e,foreign:e,lambda:e,num:e,obj:e,str:e})}toString(){return this.inner.val?.toString()??"sink"}toJSON(){const e=t=>f(t,{arr:t=>t.map((t=>e(t))),bool:e=>e,foreign:e=>e.toString(),lambda:e=>(0,n.show)(e.ast),num:e=>e,obj:t=>Object.fromEntries(Object.entries(t).map((([t,r])=>[t,e(r)]))),sink:()=>{},str:e=>e});return e(this)}export(){return this.toJSON()}static from(e){return d(e)}}function d(e){if(e instanceof p)return e;if("boolean"==typeof e)return p.bool(e);if("number"==typeof e)return p.num(e);if("string"==typeof e)return p.str(e);if(Array.isArray(e))return p.arr(e.map((e=>d(e))));if(void 0===e)return p.sink();if(e&&"object"==typeof e)return p.obj(Object.fromEntries(Object.entries(e).map((([e,t])=>[e,d(t)]))));throw new Error(`cannot convert ${JSON.stringify(e)} to Value`)}t.Value=p}},t={};!function r(n){var s=t[n];if(void 0!==s)return s.exports;var o=t[n]={exports:{}};return e[n].call(o.exports,o,o.exports,r),o.exports}(326)})();
|