fez-lisp 1.0.7 → 1.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/README.md +18 -18
- package/lib/baked/std.js +1 -1
- package/package.json +2 -2
- package/src/compiler.js +16 -3
- package/src/enums.js +1 -0
- package/src/interpreter.js +3 -3
- package/src/parser.js +2 -1
- package/src/tokeniser.js +197 -119
- package/src/utils.js +5 -5
package/src/tokeniser.js
CHANGED
@@ -17,14 +17,14 @@ const keywords = {
|
|
17
17
|
keywords.CONCATENATION
|
18
18
|
}), expected > 1 but got ${args.length}. (${
|
19
19
|
keywords.CONCATENATION
|
20
|
-
} ${stringifyArgs(args)})
|
20
|
+
} ${stringifyArgs(args)})`
|
21
21
|
)
|
22
22
|
const operands = args.map((x) => evaluate(x, env))
|
23
23
|
if (operands.some((x) => typeof x !== 'string'))
|
24
24
|
throw new TypeError(
|
25
25
|
`Not all arguments of (${KEYWORDS.CONCATENATION}) are (${
|
26
26
|
KEYWORDS.STRING_TYPE
|
27
|
-
}) (${KEYWORDS.CONCATENATION} ${stringifyArgs(args)})
|
27
|
+
}) (${KEYWORDS.CONCATENATION} ${stringifyArgs(args)})`
|
28
28
|
)
|
29
29
|
return operands.reduce((a, b) => a + b, '')
|
30
30
|
},
|
@@ -35,14 +35,14 @@ const keywords = {
|
|
35
35
|
KEYWORDS.REMAINDER_OF_DIVISION
|
36
36
|
}), expected > 1 but got ${args.length}. (${
|
37
37
|
KEYWORDS.REMAINDER_OF_DIVISION
|
38
|
-
} ${stringifyArgs(args)})
|
38
|
+
} ${stringifyArgs(args)})`
|
39
39
|
)
|
40
40
|
const [a, b] = args.map((x) => evaluate(x, env))
|
41
41
|
if (typeof a !== 'number' || typeof b !== 'number')
|
42
42
|
throw new TypeError(
|
43
43
|
`Not all arguments of (${KEYWORDS.REMAINDER_OF_DIVISION}) are (${
|
44
44
|
KEYWORDS.NUMBER_TYPE
|
45
|
-
}) (${KEYWORDS.REMAINDER_OF_DIVISION} ${stringifyArgs(args)})
|
45
|
+
}) (${KEYWORDS.REMAINDER_OF_DIVISION} ${stringifyArgs(args)})`
|
46
46
|
)
|
47
47
|
if (b === 0)
|
48
48
|
throw new TypeError(
|
@@ -50,7 +50,7 @@ const keywords = {
|
|
50
50
|
KEYWORDS.REMAINDER_OF_DIVISION
|
51
51
|
}) can't be a (0) (division by 0 is not allowed) (${
|
52
52
|
KEYWORDS.REMAINDER_OF_DIVISION
|
53
|
-
} ${stringifyArgs(args)})
|
53
|
+
} ${stringifyArgs(args)})`
|
54
54
|
)
|
55
55
|
|
56
56
|
return a % b
|
@@ -63,7 +63,7 @@ const keywords = {
|
|
63
63
|
throw new TypeError(
|
64
64
|
`Arguments of (${KEYWORDS.DIVISION}) is not a (${
|
65
65
|
KEYWORDS.NUMBER_TYPE
|
66
|
-
}) (${KEYWORDS.DIVISION} ${stringifyArgs(args)})
|
66
|
+
}) (${KEYWORDS.DIVISION} ${stringifyArgs(args)})`
|
67
67
|
)
|
68
68
|
if (number === 0)
|
69
69
|
throw new TypeError(
|
@@ -71,7 +71,7 @@ const keywords = {
|
|
71
71
|
KEYWORDS.DIVISION
|
72
72
|
}) can't be a (0) (division by 0 is not allowed) (${
|
73
73
|
KEYWORDS.DIVISION
|
74
|
-
} ${stringifyArgs(args)})
|
74
|
+
} ${stringifyArgs(args)})`
|
75
75
|
)
|
76
76
|
return 1 / number
|
77
77
|
}
|
@@ -80,7 +80,7 @@ const keywords = {
|
|
80
80
|
throw new TypeError(
|
81
81
|
`Not all arguments of (${KEYWORDS.DIVISION}) are (${
|
82
82
|
KEYWORDS.NUMBER_TYPE
|
83
|
-
}) (${KEYWORDS.DIVISION} ${stringifyArgs(args)})
|
83
|
+
}) (${KEYWORDS.DIVISION} ${stringifyArgs(args)})`
|
84
84
|
)
|
85
85
|
return operands.reduce((a, b) => a / b)
|
86
86
|
},
|
@@ -91,7 +91,7 @@ const keywords = {
|
|
91
91
|
KEYWORDS.ARRAY_OR_STRING_LENGTH
|
92
92
|
}) (1 required) (${KEYWORDS.ARRAY_OR_STRING_LENGTH} ${stringifyArgs(
|
93
93
|
args
|
94
|
-
)})
|
94
|
+
)})`
|
95
95
|
)
|
96
96
|
const array = evaluate(args[0], env)
|
97
97
|
if (!(Array.isArray(array) || typeof array === 'string'))
|
@@ -100,7 +100,7 @@ const keywords = {
|
|
100
100
|
KEYWORDS.ARRAY_OR_STRING_LENGTH
|
101
101
|
}) must be an (or ${KEYWORDS.ARRAY_TYPE} ${KEYWORDS.STRING_TYPE}) (${
|
102
102
|
KEYWORDS.ARRAY_OR_STRING_LENGTH
|
103
|
-
} ${stringifyArgs(args)})
|
103
|
+
} ${stringifyArgs(args)})`
|
104
104
|
)
|
105
105
|
return array.length
|
106
106
|
},
|
@@ -109,7 +109,7 @@ const keywords = {
|
|
109
109
|
throw new RangeError(
|
110
110
|
`Invalid number of arguments for (${KEYWORDS.IS_ARRAY}) (1 required) (${
|
111
111
|
KEYWORDS.IS_ARRAY
|
112
|
-
} ${stringifyArgs(args)})
|
112
|
+
} ${stringifyArgs(args)})`
|
113
113
|
)
|
114
114
|
const array = evaluate(args[0], env)
|
115
115
|
return +Array.isArray(array)
|
@@ -119,7 +119,7 @@ const keywords = {
|
|
119
119
|
throw new RangeError(
|
120
120
|
`Invalid number of arguments for (${
|
121
121
|
KEYWORDS.IS_NUMBER
|
122
|
-
}) (1 required) (${KEYWORDS.IS_NUMBER} ${stringifyArgs(args)})
|
122
|
+
}) (1 required) (${KEYWORDS.IS_NUMBER} ${stringifyArgs(args)})`
|
123
123
|
)
|
124
124
|
return +(typeof evaluate(args[0], env) === 'number')
|
125
125
|
},
|
@@ -128,7 +128,7 @@ const keywords = {
|
|
128
128
|
throw new RangeError(
|
129
129
|
`Invalid number of arguments for (${
|
130
130
|
KEYWORDS.IS_STRING
|
131
|
-
}) (1 required) (${KEYWORDS.IS_STRING} ${stringifyArgs(args)})
|
131
|
+
}) (1 required) (${KEYWORDS.IS_STRING} ${stringifyArgs(args)})`
|
132
132
|
)
|
133
133
|
return +(typeof evaluate(args[0], env) === 'string')
|
134
134
|
},
|
@@ -137,30 +137,31 @@ const keywords = {
|
|
137
137
|
throw new RangeError(
|
138
138
|
`Invalid number of arguments for (${
|
139
139
|
KEYWORDS.IS_FUNCTION
|
140
|
-
}) (1 required) (${KEYWORDS.IS_FUNCTION} ${stringifyArgs(args)})
|
140
|
+
}) (1 required) (${KEYWORDS.IS_FUNCTION} ${stringifyArgs(args)})`
|
141
141
|
)
|
142
142
|
return +(typeof evaluate(args[0], env) === 'function')
|
143
143
|
},
|
144
144
|
[KEYWORDS.ADDITION]: (args, env) => {
|
145
|
+
if (!args.length) return 0 // identity
|
145
146
|
if (args.length < 2)
|
146
147
|
throw new RangeError(
|
147
148
|
`Invalid number of arguments for (${
|
148
149
|
KEYWORDS.ADDITION
|
149
|
-
}), expected > 1 but got ${args.length}. (${
|
150
|
+
}), expected (or (> 1) (= 0)) but got ${args.length}. (${
|
150
151
|
KEYWORDS.ADDITION
|
151
|
-
} ${stringifyArgs(args)})
|
152
|
+
} ${stringifyArgs(args)})`
|
152
153
|
)
|
153
154
|
const operands = args.map((x) => evaluate(x, env))
|
154
155
|
if (operands.some((x) => typeof x !== 'number'))
|
155
156
|
throw new TypeError(
|
156
157
|
`Not all arguments of (${KEYWORDS.ADDITION}) are (${
|
157
158
|
KEYWORDS.NUMBER_TYPE
|
158
|
-
}) (${KEYWORDS.ADDITION} ${stringifyArgs(args)})
|
159
|
+
}) (${KEYWORDS.ADDITION} ${stringifyArgs(args)})`
|
159
160
|
)
|
160
161
|
return operands.reduce((a, b) => a + b)
|
161
162
|
},
|
162
163
|
[KEYWORDS.MULTIPLICATION]: (args, env) => {
|
163
|
-
if (!args.length) return 1
|
164
|
+
if (!args.length) return 1 // identity
|
164
165
|
if (args.length < 2)
|
165
166
|
throw new RangeError(
|
166
167
|
`Invalid number of arguments for (${KEYWORDS.MULTIPLICATION}), expected (or (> 1) (= 0)) but got ${args.length}.`
|
@@ -170,7 +171,7 @@ const keywords = {
|
|
170
171
|
throw new TypeError(
|
171
172
|
`Not all arguments of (${KEYWORDS.MULTIPLICATION}) are (${
|
172
173
|
KEYWORDS.NUMBER_TYPE
|
173
|
-
}) (${KEYWORDS.MULTIPLICATION} ${stringifyArgs(args)})
|
174
|
+
}) (${KEYWORDS.MULTIPLICATION} ${stringifyArgs(args)})`
|
174
175
|
)
|
175
176
|
return operands.reduce((a, b) => a * b)
|
176
177
|
},
|
@@ -181,14 +182,14 @@ const keywords = {
|
|
181
182
|
KEYWORDS.SUBTRACTION
|
182
183
|
}), expected >= 1 but got ${args.length}. (${
|
183
184
|
KEYWORDS.SUBTRACTION
|
184
|
-
} ${stringifyArgs(args)})
|
185
|
+
} ${stringifyArgs(args)})`
|
185
186
|
)
|
186
187
|
const operands = args.map((x) => evaluate(x, env))
|
187
188
|
if (operands.some((x) => typeof x !== 'number'))
|
188
189
|
throw new TypeError(
|
189
190
|
`Not all arguments of (${KEYWORDS.SUBTRACTION}) are (${
|
190
191
|
KEYWORDS.NUMBER_TYPE
|
191
|
-
}) (${KEYWORDS.SUBTRACTION} ${stringifyArgs(args)})
|
192
|
+
}) (${KEYWORDS.SUBTRACTION} ${stringifyArgs(args)})`
|
192
193
|
)
|
193
194
|
return args.length === 1 ? -operands[0] : operands.reduce((a, b) => a - b)
|
194
195
|
},
|
@@ -199,7 +200,7 @@ const keywords = {
|
|
199
200
|
KEYWORDS.IF
|
200
201
|
}), expected (= 3) but got ${args.length} (${
|
201
202
|
KEYWORDS.IF
|
202
|
-
} ${stringifyArgs(args)})
|
203
|
+
} ${stringifyArgs(args)})`
|
203
204
|
)
|
204
205
|
return evaluate(args[0], env)
|
205
206
|
? evaluate(args[1], env)
|
@@ -212,7 +213,7 @@ const keywords = {
|
|
212
213
|
KEYWORDS.UNLESS
|
213
214
|
}), expected (= 3) but got ${args.length} (${
|
214
215
|
KEYWORDS.UNLESS
|
215
|
-
} ${stringifyArgs(args)})
|
216
|
+
} ${stringifyArgs(args)})`
|
216
217
|
)
|
217
218
|
return evaluate(args[0], env)
|
218
219
|
? evaluate(args[2], env)
|
@@ -225,7 +226,7 @@ const keywords = {
|
|
225
226
|
KEYWORDS.WHEN
|
226
227
|
}), expected 2 but got ${args.length} (${KEYWORDS.WHEN} ${stringifyArgs(
|
227
228
|
args
|
228
|
-
)})
|
229
|
+
)})`
|
229
230
|
)
|
230
231
|
return evaluate(args[0], env) ? evaluate(args[1], env) : 0
|
231
232
|
},
|
@@ -236,7 +237,7 @@ const keywords = {
|
|
236
237
|
KEYWORDS.OTHERWISE
|
237
238
|
}), expected 2 but got ${args.length} (${
|
238
239
|
KEYWORDS.OTHERWISE
|
239
|
-
} ${stringifyArgs(args)})
|
240
|
+
} ${stringifyArgs(args)})`
|
240
241
|
)
|
241
242
|
return evaluate(args[0], env) ? 0 : evaluate(args[1], env)
|
242
243
|
},
|
@@ -247,7 +248,7 @@ const keywords = {
|
|
247
248
|
KEYWORDS.CONDITION
|
248
249
|
}), expected (> 2 required) but got ${args.length} (${
|
249
250
|
KEYWORDS.CONDITION
|
250
|
-
} ${stringifyArgs(args)})
|
251
|
+
} ${stringifyArgs(args)})`
|
251
252
|
)
|
252
253
|
for (let i = 0; i < args.length; i += 2) {
|
253
254
|
if (evaluate(args[i], env)) return evaluate(args[i + 1], env)
|
@@ -274,14 +275,14 @@ const keywords = {
|
|
274
275
|
)
|
275
276
|
return new Array(N).fill(0)
|
276
277
|
}
|
277
|
-
return
|
278
|
+
return args.map((x) => evaluate(x, env))
|
278
279
|
},
|
279
280
|
[KEYWORDS.IS_ATOM]: (args, env) => {
|
280
281
|
if (args.length !== 1)
|
281
282
|
throw new RangeError(
|
282
283
|
`Invalid number of arguments for (${KEYWORDS.IS_ATOM}) (1 required) (${
|
283
284
|
KEYWORDS.IS_ATOM
|
284
|
-
} ${stringifyArgs(args)})
|
285
|
+
} ${stringifyArgs(args)})`
|
285
286
|
)
|
286
287
|
return isAtom(args[0], env)
|
287
288
|
},
|
@@ -290,27 +291,27 @@ const keywords = {
|
|
290
291
|
throw new RangeError(
|
291
292
|
`Invalid number of arguments for (${
|
292
293
|
KEYWORDS.FIRST_ARRAY
|
293
|
-
}) (1 required) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})
|
294
|
+
}) (1 required) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})`
|
294
295
|
)
|
295
296
|
const array = evaluate(args[0], env)
|
296
297
|
if (!Array.isArray(array))
|
297
298
|
throw new TypeError(
|
298
299
|
`Argument of (${KEYWORDS.FIRST_ARRAY}) must be an (${
|
299
300
|
KEYWORDS.ARRAY_TYPE
|
300
|
-
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})
|
301
|
+
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})`
|
301
302
|
)
|
302
303
|
if (array.length === 0)
|
303
304
|
throw new RangeError(
|
304
305
|
`Argument of (${KEYWORDS.FIRST_ARRAY}) is an empty (${
|
305
306
|
KEYWORDS.ARRAY_TYPE
|
306
|
-
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})
|
307
|
+
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})`
|
307
308
|
)
|
308
309
|
const value = array.at(0)
|
309
310
|
if (value == undefined)
|
310
311
|
throw new RangeError(
|
311
312
|
`Trying to get a null value in (${KEYWORDS.ARRAY_TYPE}) at (${
|
312
313
|
KEYWORDS.FIRST_ARRAY
|
313
|
-
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})
|
314
|
+
}) (${KEYWORDS.FIRST_ARRAY} ${stringifyArgs(args)})`
|
314
315
|
)
|
315
316
|
return value
|
316
317
|
},
|
@@ -326,13 +327,13 @@ const keywords = {
|
|
326
327
|
throw new TypeError(
|
327
328
|
`Argument of (${KEYWORDS.REST_ARRAY}) must be an (${
|
328
329
|
KEYWORDS.ARRAY_TYPE
|
329
|
-
}) (${KEYWORDS.REST_ARRAY} ${stringifyArgs(args)})
|
330
|
+
}) (${KEYWORDS.REST_ARRAY} ${stringifyArgs(args)})`
|
330
331
|
)
|
331
332
|
if (array.length === 0)
|
332
333
|
throw new RangeError(
|
333
334
|
`Argument of (${KEYWORDS.REST_ARRAY}) is an empty (${
|
334
335
|
KEYWORDS.ARRAY_TYPE
|
335
|
-
}) (${KEYWORDS.REST_ARRAY} ${stringifyArgs(args)})
|
336
|
+
}) (${KEYWORDS.REST_ARRAY} ${stringifyArgs(args)})`
|
336
337
|
)
|
337
338
|
return array.slice(1)
|
338
339
|
},
|
@@ -348,33 +349,33 @@ const keywords = {
|
|
348
349
|
throw new TypeError(
|
349
350
|
`First argument of (${KEYWORDS.GET_ARRAY}) must be an (${
|
350
351
|
KEYWORDS.ARRAY_TYPE
|
351
|
-
})) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})
|
352
|
+
})) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})`
|
352
353
|
)
|
353
354
|
if (array.length === 0)
|
354
355
|
throw new RangeError(
|
355
356
|
`First argument of (${KEYWORDS.GET_ARRAY}) is an empty (${
|
356
357
|
KEYWORDS.ARRAY_TYPE
|
357
|
-
})) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)}))
|
358
|
+
})) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)}))`
|
358
359
|
)
|
359
360
|
const index = evaluate(args[1], env)
|
360
361
|
if (!Number.isInteger(index))
|
361
362
|
throw new TypeError(
|
362
363
|
`Second argument of (${KEYWORDS.GET_ARRAY}) must be an (32 bit ${
|
363
364
|
KEYWORDS.NUMBER_TYPE
|
364
|
-
}) (${index}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})
|
365
|
+
}) (${index}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})`
|
365
366
|
)
|
366
367
|
if (index > array.length - 1 || index * -1 > array.length)
|
367
368
|
throw new RangeError(
|
368
369
|
`Second argument of (${KEYWORDS.GET_ARRAY}) is outside of (${
|
369
370
|
KEYWORDS.ARRAY_TYPE
|
370
|
-
}) bounds (${index}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})
|
371
|
+
}) bounds (${index}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})`
|
371
372
|
)
|
372
373
|
const value = array.at(index)
|
373
374
|
if (value == undefined)
|
374
375
|
throw new RangeError(
|
375
376
|
`Trying to get a null value in (${KEYWORDS.ARRAY_TYPE}) at (${
|
376
377
|
KEYWORDS.GET_ARRAY
|
377
|
-
}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})
|
378
|
+
}) (${KEYWORDS.GET_ARRAY} ${stringifyArgs(args)})`
|
378
379
|
)
|
379
380
|
return value
|
380
381
|
},
|
@@ -389,20 +390,6 @@ const keywords = {
|
|
389
390
|
console.log(...expressions)
|
390
391
|
return expressions.at(-1)
|
391
392
|
},
|
392
|
-
[KEYWORDS.READ]: (args, env) => {
|
393
|
-
if (args.length)
|
394
|
-
throw new RangeError(
|
395
|
-
`Invalid number of arguments to (${KEYWORDS.READ}) (= 0 required) (${
|
396
|
-
KEYWORDS.READ
|
397
|
-
} ${stringifyArgs(args)})`
|
398
|
-
)
|
399
|
-
const inp = env[KEYWORDS.INPUT]
|
400
|
-
if (inp.length) return inp
|
401
|
-
else
|
402
|
-
throw new ReferenceError(
|
403
|
-
`${KEYWORDS.INPUT} is empty! at (${KEYWORDS.READ})`
|
404
|
-
)
|
405
|
-
},
|
406
393
|
[KEYWORDS.BLOCK]: (args, env) => {
|
407
394
|
if (!args.length)
|
408
395
|
throw new RangeError(
|
@@ -454,15 +441,16 @@ const keywords = {
|
|
454
441
|
)
|
455
442
|
const a = evaluate(args[0], env)
|
456
443
|
const b = evaluate(args[1], env)
|
457
|
-
if (
|
458
|
-
Array.isArray(a) ||
|
459
|
-
Array.isArray(b) ||
|
460
|
-
typeof a === 'function' ||
|
461
|
-
typeof b === 'function'
|
462
|
-
)
|
444
|
+
if (typeof a !== 'number')
|
463
445
|
throw new TypeError(
|
464
|
-
`Invalid use of (${KEYWORDS.EQUAL}),
|
465
|
-
KEYWORDS.
|
446
|
+
`Invalid use of (${KEYWORDS.EQUAL}), first arguments are not an ${
|
447
|
+
KEYWORDS.NUMBER_TYPE
|
448
|
+
} (${KEYWORDS.EQUAL} ${stringifyArgs(args)})`
|
449
|
+
)
|
450
|
+
if (typeof b !== 'number')
|
451
|
+
throw new TypeError(
|
452
|
+
`Invalid use of (${KEYWORDS.EQUAL}), second argument are not an ${
|
453
|
+
KEYWORDS.NUMBER_TYPE
|
466
454
|
} (${KEYWORDS.EQUAL} ${stringifyArgs(args)})`
|
467
455
|
)
|
468
456
|
return +(a === b)
|
@@ -476,15 +464,16 @@ const keywords = {
|
|
476
464
|
)
|
477
465
|
const a = evaluate(args[0], env)
|
478
466
|
const b = evaluate(args[1], env)
|
479
|
-
if (
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
467
|
+
if (typeof a !== 'number')
|
468
|
+
throw new TypeError(
|
469
|
+
`Invalid use of (${KEYWORDS.LESS_THAN}), first arguments are not an ${
|
470
|
+
KEYWORDS.NUMBER_TYPE
|
471
|
+
} (${KEYWORDS.LESS_THAN} ${stringifyArgs(args)})`
|
472
|
+
)
|
473
|
+
if (typeof b !== 'number')
|
485
474
|
throw new TypeError(
|
486
|
-
`Invalid use of (${KEYWORDS.LESS_THAN}),
|
487
|
-
KEYWORDS.
|
475
|
+
`Invalid use of (${KEYWORDS.LESS_THAN}), second argument are not an ${
|
476
|
+
KEYWORDS.NUMBER_TYPE
|
488
477
|
} (${KEYWORDS.LESS_THAN} ${stringifyArgs(args)})`
|
489
478
|
)
|
490
479
|
return +(a < b)
|
@@ -498,16 +487,19 @@ const keywords = {
|
|
498
487
|
)
|
499
488
|
const a = evaluate(args[0], env)
|
500
489
|
const b = evaluate(args[1], env)
|
501
|
-
if (
|
502
|
-
Array.isArray(a) ||
|
503
|
-
Array.isArray(b) ||
|
504
|
-
typeof a === 'function' ||
|
505
|
-
typeof b === 'function'
|
506
|
-
)
|
490
|
+
if (typeof a !== 'number')
|
507
491
|
throw new TypeError(
|
508
492
|
`Invalid use of (${
|
509
493
|
KEYWORDS.GREATHER_THAN
|
510
|
-
}),
|
494
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
495
|
+
KEYWORDS.GREATHER_THAN
|
496
|
+
} ${stringifyArgs(args)})`
|
497
|
+
)
|
498
|
+
if (typeof b !== 'number')
|
499
|
+
throw new TypeError(
|
500
|
+
`Invalid use of (${
|
501
|
+
KEYWORDS.GREATHER_THAN
|
502
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
511
503
|
KEYWORDS.GREATHER_THAN
|
512
504
|
} ${stringifyArgs(args)})`
|
513
505
|
)
|
@@ -524,16 +516,19 @@ const keywords = {
|
|
524
516
|
)
|
525
517
|
const a = evaluate(args[0], env)
|
526
518
|
const b = evaluate(args[1], env)
|
527
|
-
if (
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
519
|
+
if (typeof a !== 'number')
|
520
|
+
throw new TypeError(
|
521
|
+
`Invalid use of (${
|
522
|
+
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
523
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
524
|
+
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
525
|
+
} ${stringifyArgs(args)})`
|
526
|
+
)
|
527
|
+
if (typeof b !== 'number')
|
533
528
|
throw new TypeError(
|
534
529
|
`Invalid use of (${
|
535
530
|
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
536
|
-
}),
|
531
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
537
532
|
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
538
533
|
} ${stringifyArgs(args)})`
|
539
534
|
)
|
@@ -548,16 +543,19 @@ const keywords = {
|
|
548
543
|
)
|
549
544
|
const a = evaluate(args[0], env)
|
550
545
|
const b = evaluate(args[1], env)
|
551
|
-
if (
|
552
|
-
Array.isArray(a) ||
|
553
|
-
Array.isArray(b) ||
|
554
|
-
typeof a === 'function' ||
|
555
|
-
typeof b === 'function'
|
556
|
-
)
|
546
|
+
if (typeof a !== 'number')
|
557
547
|
throw new TypeError(
|
558
548
|
`Invalid use of (${
|
559
549
|
KEYWORDS.LESS_THAN_OR_EQUAL
|
560
|
-
}),
|
550
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
551
|
+
KEYWORDS.LESS_THAN_OR_EQUAL
|
552
|
+
} ${stringifyArgs(args)})`
|
553
|
+
)
|
554
|
+
if (typeof b !== 'number')
|
555
|
+
throw new TypeError(
|
556
|
+
`Invalid use of (${
|
557
|
+
KEYWORDS.LESS_THAN_OR_EQUAL
|
558
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
561
559
|
KEYWORDS.LESS_THAN_OR_EQUAL
|
562
560
|
} ${stringifyArgs(args)})`
|
563
561
|
)
|
@@ -671,7 +669,7 @@ const keywords = {
|
|
671
669
|
KEYWORDS.NUMBER_TYPE
|
672
670
|
} ("${value}") to a ${KEYWORDS.NUMBER_TYPE} at (${
|
673
671
|
KEYWORDS.CAST_TYPE
|
674
|
-
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})
|
672
|
+
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})`
|
675
673
|
)
|
676
674
|
return num
|
677
675
|
}
|
@@ -681,14 +679,14 @@ const keywords = {
|
|
681
679
|
return +!!value
|
682
680
|
case KEYWORDS.ARRAY_TYPE: {
|
683
681
|
if (typeof value === 'number')
|
684
|
-
return
|
682
|
+
return [...Number(value).toString()].map(Number)
|
685
683
|
else if (typeof value[Symbol.iterator] !== 'function')
|
686
684
|
throw new TypeError(
|
687
685
|
`Arguments are not iterable for ${KEYWORDS.ARRAY_TYPE} at (${
|
688
686
|
KEYWORDS.CAST_TYPE
|
689
|
-
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})
|
687
|
+
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})`
|
690
688
|
)
|
691
|
-
return
|
689
|
+
return [...value]
|
692
690
|
}
|
693
691
|
case KEYWORDS.CHAR_TYPE: {
|
694
692
|
const index = evaluate(args[0], env)
|
@@ -698,7 +696,7 @@ const keywords = {
|
|
698
696
|
KEYWORDS.CHAR_TYPE
|
699
697
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
700
698
|
KEYWORDS.CAST_TYPE
|
701
|
-
} ${stringifyArgs(args)})
|
699
|
+
} ${stringifyArgs(args)})`
|
702
700
|
)
|
703
701
|
return String.fromCharCode(index)
|
704
702
|
}
|
@@ -710,7 +708,7 @@ const keywords = {
|
|
710
708
|
KEYWORDS.CHAR_CODE_TYPE
|
711
709
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
712
710
|
KEYWORDS.CAST_TYPE
|
713
|
-
} ${stringifyArgs(args)})
|
711
|
+
} ${stringifyArgs(args)})`
|
714
712
|
)
|
715
713
|
if (string.length !== 1)
|
716
714
|
throw new RangeError(
|
@@ -718,7 +716,7 @@ const keywords = {
|
|
718
716
|
KEYWORDS.CHAR_CODE_TYPE
|
719
717
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
720
718
|
KEYWORDS.CAST_TYPE
|
721
|
-
} ${stringifyArgs(args)})
|
719
|
+
} ${stringifyArgs(args)})`
|
722
720
|
)
|
723
721
|
return string.charCodeAt(0)
|
724
722
|
}
|
@@ -730,7 +728,7 @@ const keywords = {
|
|
730
728
|
KEYWORDS.CHAR_TYPE
|
731
729
|
} ${KEYWORDS.CHAR_CODE_TYPE}) at (${KEYWORDS.CAST_TYPE}) (${
|
732
730
|
KEYWORDS.CAST_TYPE
|
733
|
-
} ${stringifyArgs(args)})
|
731
|
+
} ${stringifyArgs(args)})`
|
734
732
|
)
|
735
733
|
}
|
736
734
|
}
|
@@ -747,7 +745,7 @@ const keywords = {
|
|
747
745
|
throw new TypeError(
|
748
746
|
`Not all arguments of (${KEYWORDS.BITWISE_AND}) are ${
|
749
747
|
KEYWORDS.NUMBER_TYPE
|
750
|
-
} (${KEYWORDS.BITWISE_AND} ${stringifyArgs(args)})
|
748
|
+
} (${KEYWORDS.BITWISE_AND} ${stringifyArgs(args)})`
|
751
749
|
)
|
752
750
|
return operands.reduce((acc, x) => acc & x)
|
753
751
|
},
|
@@ -763,7 +761,7 @@ const keywords = {
|
|
763
761
|
throw new TypeError(
|
764
762
|
`Argument of (${KEYWORDS.BITWISE_NOT}) is not a (${
|
765
763
|
KEYWORDS.NUMBER_TYPE
|
766
|
-
}) (${KEYWORDS.BITWISE_NOT} ${stringifyArgs(args)})
|
764
|
+
}) (${KEYWORDS.BITWISE_NOT} ${stringifyArgs(args)})`
|
767
765
|
)
|
768
766
|
return ~operand
|
769
767
|
},
|
@@ -779,7 +777,7 @@ const keywords = {
|
|
779
777
|
throw new TypeError(
|
780
778
|
`Not all arguments of (${KEYWORDS.BITWISE_OR}) are (${
|
781
779
|
KEYWORDS.NUMBER_TYPE
|
782
|
-
}) (${KEYWORDS.BITWISE_OR} ${stringifyArgs(args)})
|
780
|
+
}) (${KEYWORDS.BITWISE_OR} ${stringifyArgs(args)})`
|
783
781
|
)
|
784
782
|
return operands.reduce((acc, x) => acc | x)
|
785
783
|
},
|
@@ -788,14 +786,14 @@ const keywords = {
|
|
788
786
|
throw new RangeError(
|
789
787
|
`Invalid number of arguments to (${
|
790
788
|
KEYWORDS.BITWISE_XOR
|
791
|
-
}) (>= 2 required). (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})
|
789
|
+
}) (>= 2 required). (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})`
|
792
790
|
)
|
793
791
|
const operands = args.map((a) => evaluate(a, env))
|
794
792
|
if (operands.some((x) => typeof x !== 'number'))
|
795
793
|
throw new TypeError(
|
796
794
|
`Not all arguments of (${KEYWORDS.BITWISE_XOR}) are (${
|
797
795
|
KEYWORDS.NUMBER_TYPE
|
798
|
-
}) (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})
|
796
|
+
}) (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})`
|
799
797
|
)
|
800
798
|
return operands.reduce((acc, x) => acc ^ x)
|
801
799
|
},
|
@@ -806,14 +804,14 @@ const keywords = {
|
|
806
804
|
KEYWORDS.BITWISE_LEFT_SHIFT
|
807
805
|
}) (>= 2 required). (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(
|
808
806
|
args
|
809
|
-
)})
|
807
|
+
)})`
|
810
808
|
)
|
811
809
|
const operands = args.map((a) => evaluate(a, env))
|
812
810
|
if (operands.some((x) => typeof x !== 'number'))
|
813
811
|
throw new TypeError(
|
814
812
|
`Not all arguments of (${KEYWORDS.BITWISE_LEFT_SHIFT}) are (${
|
815
813
|
KEYWORDS.NUMBER_TYPE
|
816
|
-
}) (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(args)})
|
814
|
+
}) (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(args)})`
|
817
815
|
)
|
818
816
|
return operands.reduce((acc, x) => acc << x)
|
819
817
|
},
|
@@ -824,14 +822,14 @@ const keywords = {
|
|
824
822
|
KEYWORDS.BITWISE_RIGHT_SHIFT
|
825
823
|
}) (>= 2 required). (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(
|
826
824
|
args
|
827
|
-
)})
|
825
|
+
)})`
|
828
826
|
)
|
829
827
|
const operands = args.map((a) => evaluate(a, env))
|
830
828
|
if (operands.some((x) => typeof x !== 'number'))
|
831
829
|
throw new TypeError(
|
832
830
|
`Not all arguments of (${KEYWORDS.BITWISE_RIGHT_SHIFT}) are (${
|
833
831
|
KEYWORDS.NUMBER_TYPE
|
834
|
-
}) (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(args)})
|
832
|
+
}) (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(args)})`
|
835
833
|
)
|
836
834
|
return operands.reduce((acc, x) => acc >> x)
|
837
835
|
},
|
@@ -842,14 +840,14 @@ const keywords = {
|
|
842
840
|
KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT
|
843
841
|
}) (>= 2 required). (${
|
844
842
|
KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT
|
845
|
-
} ${stringifyArgs(args)})
|
843
|
+
} ${stringifyArgs(args)})`
|
846
844
|
)
|
847
845
|
const operands = args.map((a) => evaluate(a, env))
|
848
846
|
if (operands.some((x) => typeof x !== 'number'))
|
849
847
|
throw new TypeError(
|
850
848
|
`Not all arguments of (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT}) are (${
|
851
849
|
KEYWORDS.NUMBER_TYPE
|
852
|
-
}) (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT} ${stringifyArgs(args)})
|
850
|
+
}) (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT} ${stringifyArgs(args)})`
|
853
851
|
)
|
854
852
|
return operands.reduce((acc, x) => acc >>> x)
|
855
853
|
},
|
@@ -879,14 +877,14 @@ const keywords = {
|
|
879
877
|
throw new RangeError(
|
880
878
|
`Invalid number of arguments to (${
|
881
879
|
KEYWORDS.THROW_ERROR
|
882
|
-
}) (1 required). (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})
|
880
|
+
}) (1 required). (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})`
|
883
881
|
)
|
884
882
|
const string = evaluate(args[0], env)
|
885
883
|
if (typeof string !== 'string')
|
886
884
|
throw new TypeError(
|
887
885
|
`First argument of (${KEYWORDS.THROW_ERROR}) must be an (${
|
888
886
|
KEYWORDS.STRING_TYPE
|
889
|
-
}) (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})
|
887
|
+
}) (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})`
|
890
888
|
)
|
891
889
|
throw new Error(string)
|
892
890
|
},
|
@@ -895,16 +893,16 @@ const keywords = {
|
|
895
893
|
throw new RangeError(
|
896
894
|
`Invalid number of arguments to (${KEYWORDS.MERGE}) (>= 2 required). (${
|
897
895
|
KEYWORDS.MERGE
|
898
|
-
} ${stringifyArgs(args)})
|
896
|
+
} ${stringifyArgs(args)})`
|
899
897
|
)
|
900
898
|
const arrays = args.map((arg) => evaluate(arg, env))
|
901
899
|
if (arrays.some((maybe) => !Array.isArray(maybe)))
|
902
900
|
throw new TypeError(
|
903
901
|
`Arguments of (${KEYWORDS.MERGE}) must be (${KEYWORDS.ARRAY_TYPE}) (${
|
904
902
|
KEYWORDS.MERGE
|
905
|
-
} ${stringifyArgs(args)})
|
903
|
+
} ${stringifyArgs(args)})`
|
906
904
|
)
|
907
|
-
return
|
905
|
+
return arrays.reduce((a, b) => a.concat(b), [])
|
908
906
|
},
|
909
907
|
[KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION]: (args, env) => {
|
910
908
|
if (!args.length)
|
@@ -913,7 +911,7 @@ const keywords = {
|
|
913
911
|
KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION
|
914
912
|
}) (>= 2 required). (${
|
915
913
|
KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION
|
916
|
-
} ${stringifyArgs(args)})
|
914
|
+
} ${stringifyArgs(args)})`
|
917
915
|
)
|
918
916
|
// TODO: Add validation for TCO recursion
|
919
917
|
return keywords[KEYWORDS.DEFINE_VARIABLE](args, env)
|
@@ -925,7 +923,7 @@ const keywords = {
|
|
925
923
|
KEYWORDS.IMMUTABLE_FUNCTION
|
926
924
|
}) (>= 2 required). (${KEYWORDS.IMMUTABLE_FUNCTION} ${stringifyArgs(
|
927
925
|
args
|
928
|
-
)})
|
926
|
+
)})`
|
929
927
|
)
|
930
928
|
const [definition, ...functionArgs] = args
|
931
929
|
const token = definition[VALUE]
|
@@ -1024,14 +1022,14 @@ const keywords = {
|
|
1024
1022
|
throw new TypeError(
|
1025
1023
|
`First argument of (${KEYWORDS.SET_ARRAY}) must be an (${
|
1026
1024
|
KEYWORDS.ARRAY_TYPE
|
1027
|
-
}) but got (${array}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})
|
1025
|
+
}) but got (${array}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})`
|
1028
1026
|
)
|
1029
1027
|
const index = evaluate(args[1], env)
|
1030
1028
|
if (!Number.isInteger(index))
|
1031
1029
|
throw new TypeError(
|
1032
1030
|
`Second argument of (${KEYWORDS.SET_ARRAY}) must be an (${
|
1033
1031
|
KEYWORDS.NUMBER_TYPE
|
1034
|
-
} integer) (${index}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})
|
1032
|
+
} integer) (${index}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})`
|
1035
1033
|
)
|
1036
1034
|
if (index > array.length)
|
1037
1035
|
throw new RangeError(
|
@@ -1039,7 +1037,7 @@ const keywords = {
|
|
1039
1037
|
KEYWORDS.ARRAY_TYPE
|
1040
1038
|
}) bounds (index ${index} bounds ${array.length}) (${
|
1041
1039
|
KEYWORDS.SET_ARRAY
|
1042
|
-
} ${stringifyArgs(args)})
|
1040
|
+
} ${stringifyArgs(args)})`
|
1043
1041
|
)
|
1044
1042
|
if (index < 0) {
|
1045
1043
|
if (args.length !== 2)
|
@@ -1080,6 +1078,86 @@ const keywords = {
|
|
1080
1078
|
}
|
1081
1079
|
return array
|
1082
1080
|
},
|
1081
|
+
|
1082
|
+
[KEYWORDS.SET_IMMUTABLE_ARRAY]: (args, env) => {
|
1083
|
+
if (args.length !== 2 && args.length !== 3)
|
1084
|
+
throw new RangeError(
|
1085
|
+
`Invalid number of arguments for (${
|
1086
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1087
|
+
}) (or 2 3) required (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1088
|
+
args
|
1089
|
+
)})`
|
1090
|
+
)
|
1091
|
+
let array = evaluate(args[0], env)
|
1092
|
+
if (!Array.isArray(array))
|
1093
|
+
throw new TypeError(
|
1094
|
+
`First argument of (${KEYWORDS.SET_IMMUTABLE_ARRAY}) must be an (${
|
1095
|
+
KEYWORDS.ARRAY_TYPE
|
1096
|
+
}) but got (${array}) (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1097
|
+
args
|
1098
|
+
)})`
|
1099
|
+
)
|
1100
|
+
array = [...array]
|
1101
|
+
const index = evaluate(args[1], env)
|
1102
|
+
if (!Number.isInteger(index))
|
1103
|
+
throw new TypeError(
|
1104
|
+
`Second argument of (${KEYWORDS.SET_IMMUTABLE_ARRAY}) must be an (${
|
1105
|
+
KEYWORDS.NUMBER_TYPE
|
1106
|
+
} integer) (${index}) (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1107
|
+
args
|
1108
|
+
)})`
|
1109
|
+
)
|
1110
|
+
if (index > array.length)
|
1111
|
+
throw new RangeError(
|
1112
|
+
`Second argument of (${
|
1113
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1114
|
+
}) is outside of the (${
|
1115
|
+
KEYWORDS.ARRAY_TYPE
|
1116
|
+
}) bounds (index ${index} bounds ${array.length}) (${
|
1117
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1118
|
+
} ${stringifyArgs(args)})`
|
1119
|
+
)
|
1120
|
+
if (index < 0) {
|
1121
|
+
if (args.length !== 2)
|
1122
|
+
throw new RangeError(
|
1123
|
+
`Invalid number of arguments for (${
|
1124
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1125
|
+
}) (if (< index 0) then 2 required) (${
|
1126
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1127
|
+
} ${stringifyArgs(args)})`
|
1128
|
+
)
|
1129
|
+
if (index * -1 > array.length)
|
1130
|
+
throw new RangeError(
|
1131
|
+
`Second argument of (${
|
1132
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1133
|
+
}) is outside of the (${
|
1134
|
+
KEYWORDS.ARRAY_TYPE
|
1135
|
+
}) bounds (index ${index} bounds ${array.length}) (${
|
1136
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1137
|
+
} ${stringifyArgs(args)})`
|
1138
|
+
)
|
1139
|
+
const target = array.length + index
|
1140
|
+
while (array.length !== target) array.pop()
|
1141
|
+
} else {
|
1142
|
+
if (args.length !== 3)
|
1143
|
+
throw new RangeError(
|
1144
|
+
`Invalid number of arguments for (${
|
1145
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1146
|
+
}) (if (>= index 0) then 3 required) (${
|
1147
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1148
|
+
} ${stringifyArgs(args)})`
|
1149
|
+
)
|
1150
|
+
const value = evaluate(args[2], env)
|
1151
|
+
if (value == undefined)
|
1152
|
+
throw new RangeError(
|
1153
|
+
`Trying to set a null value in (${KEYWORDS.ARRAY_TYPE}) at (${
|
1154
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1155
|
+
}). (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(args)})`
|
1156
|
+
)
|
1157
|
+
array[index] = value
|
1158
|
+
}
|
1159
|
+
return array
|
1160
|
+
},
|
1083
1161
|
}
|
1084
1162
|
keywords[KEYWORDS.NOT_COMPILED_BLOCK] = keywords[KEYWORDS.BLOCK]
|
1085
1163
|
export { keywords }
|