fez-lisp 1.0.6 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +18 -18
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/compiler.js +14 -0
- package/src/enums.js +2 -0
- package/src/interpreter.js +3 -3
- package/src/parser.js +2 -1
- package/src/tokeniser.js +206 -117
- package/src/utils.js +9 -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(
|
@@ -445,6 +432,17 @@ const keywords = {
|
|
445
432
|
)
|
446
433
|
return +!evaluate(args[0], env)
|
447
434
|
},
|
435
|
+
[KEYWORDS.EQUALITY]: (args, env) => {
|
436
|
+
if (args.length !== 2)
|
437
|
+
throw new RangeError(
|
438
|
+
`Invalid number of arguments for (${KEYWORDS.EQUAL}) (2 required) (${
|
439
|
+
KEYWORDS.EQUAL
|
440
|
+
} ${stringifyArgs(args)})`
|
441
|
+
)
|
442
|
+
const a = evaluate(args[0], env)
|
443
|
+
const b = evaluate(args[1], env)
|
444
|
+
return +(a === b)
|
445
|
+
},
|
448
446
|
[KEYWORDS.EQUAL]: (args, env) => {
|
449
447
|
if (args.length !== 2)
|
450
448
|
throw new RangeError(
|
@@ -454,15 +452,16 @@ const keywords = {
|
|
454
452
|
)
|
455
453
|
const a = evaluate(args[0], env)
|
456
454
|
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
|
-
)
|
455
|
+
if (typeof a !== 'number')
|
463
456
|
throw new TypeError(
|
464
|
-
`Invalid use of (${KEYWORDS.EQUAL}),
|
465
|
-
KEYWORDS.
|
457
|
+
`Invalid use of (${KEYWORDS.EQUAL}), first arguments are not an ${
|
458
|
+
KEYWORDS.NUMBER_TYPE
|
459
|
+
} (${KEYWORDS.EQUAL} ${stringifyArgs(args)})`
|
460
|
+
)
|
461
|
+
if (typeof b !== 'number')
|
462
|
+
throw new TypeError(
|
463
|
+
`Invalid use of (${KEYWORDS.EQUAL}), second argument are not an ${
|
464
|
+
KEYWORDS.NUMBER_TYPE
|
466
465
|
} (${KEYWORDS.EQUAL} ${stringifyArgs(args)})`
|
467
466
|
)
|
468
467
|
return +(a === b)
|
@@ -476,15 +475,16 @@ const keywords = {
|
|
476
475
|
)
|
477
476
|
const a = evaluate(args[0], env)
|
478
477
|
const b = evaluate(args[1], env)
|
479
|
-
if (
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
478
|
+
if (typeof a !== 'number')
|
479
|
+
throw new TypeError(
|
480
|
+
`Invalid use of (${KEYWORDS.LESS_THAN}), first arguments are not an ${
|
481
|
+
KEYWORDS.NUMBER_TYPE
|
482
|
+
} (${KEYWORDS.LESS_THAN} ${stringifyArgs(args)})`
|
483
|
+
)
|
484
|
+
if (typeof b !== 'number')
|
485
485
|
throw new TypeError(
|
486
|
-
`Invalid use of (${KEYWORDS.LESS_THAN}),
|
487
|
-
KEYWORDS.
|
486
|
+
`Invalid use of (${KEYWORDS.LESS_THAN}), second argument are not an ${
|
487
|
+
KEYWORDS.NUMBER_TYPE
|
488
488
|
} (${KEYWORDS.LESS_THAN} ${stringifyArgs(args)})`
|
489
489
|
)
|
490
490
|
return +(a < b)
|
@@ -498,16 +498,19 @@ const keywords = {
|
|
498
498
|
)
|
499
499
|
const a = evaluate(args[0], env)
|
500
500
|
const b = evaluate(args[1], env)
|
501
|
-
if (
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
501
|
+
if (typeof a !== 'number')
|
502
|
+
throw new TypeError(
|
503
|
+
`Invalid use of (${
|
504
|
+
KEYWORDS.GREATHER_THAN
|
505
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
506
|
+
KEYWORDS.GREATHER_THAN
|
507
|
+
} ${stringifyArgs(args)})`
|
508
|
+
)
|
509
|
+
if (typeof b !== 'number')
|
507
510
|
throw new TypeError(
|
508
511
|
`Invalid use of (${
|
509
512
|
KEYWORDS.GREATHER_THAN
|
510
|
-
}),
|
513
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
511
514
|
KEYWORDS.GREATHER_THAN
|
512
515
|
} ${stringifyArgs(args)})`
|
513
516
|
)
|
@@ -524,16 +527,19 @@ const keywords = {
|
|
524
527
|
)
|
525
528
|
const a = evaluate(args[0], env)
|
526
529
|
const b = evaluate(args[1], env)
|
527
|
-
if (
|
528
|
-
Array.isArray(a) ||
|
529
|
-
Array.isArray(b) ||
|
530
|
-
typeof a === 'function' ||
|
531
|
-
typeof b === 'function'
|
532
|
-
)
|
530
|
+
if (typeof a !== 'number')
|
533
531
|
throw new TypeError(
|
534
532
|
`Invalid use of (${
|
535
533
|
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
536
|
-
}),
|
534
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
535
|
+
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
536
|
+
} ${stringifyArgs(args)})`
|
537
|
+
)
|
538
|
+
if (typeof b !== 'number')
|
539
|
+
throw new TypeError(
|
540
|
+
`Invalid use of (${
|
541
|
+
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
542
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
537
543
|
KEYWORDS.GREATHER_THAN_OR_EQUAL
|
538
544
|
} ${stringifyArgs(args)})`
|
539
545
|
)
|
@@ -548,16 +554,19 @@ const keywords = {
|
|
548
554
|
)
|
549
555
|
const a = evaluate(args[0], env)
|
550
556
|
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
|
-
)
|
557
|
+
if (typeof a !== 'number')
|
557
558
|
throw new TypeError(
|
558
559
|
`Invalid use of (${
|
559
560
|
KEYWORDS.LESS_THAN_OR_EQUAL
|
560
|
-
}),
|
561
|
+
}), first arguments are not an ${KEYWORDS.NUMBER_TYPE} (${
|
562
|
+
KEYWORDS.LESS_THAN_OR_EQUAL
|
563
|
+
} ${stringifyArgs(args)})`
|
564
|
+
)
|
565
|
+
if (typeof b !== 'number')
|
566
|
+
throw new TypeError(
|
567
|
+
`Invalid use of (${
|
568
|
+
KEYWORDS.LESS_THAN_OR_EQUAL
|
569
|
+
}), second argument are not an ${KEYWORDS.NUMBER_TYPE} (${
|
561
570
|
KEYWORDS.LESS_THAN_OR_EQUAL
|
562
571
|
} ${stringifyArgs(args)})`
|
563
572
|
)
|
@@ -671,7 +680,7 @@ const keywords = {
|
|
671
680
|
KEYWORDS.NUMBER_TYPE
|
672
681
|
} ("${value}") to a ${KEYWORDS.NUMBER_TYPE} at (${
|
673
682
|
KEYWORDS.CAST_TYPE
|
674
|
-
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})
|
683
|
+
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})`
|
675
684
|
)
|
676
685
|
return num
|
677
686
|
}
|
@@ -681,12 +690,12 @@ const keywords = {
|
|
681
690
|
return +!!value
|
682
691
|
case KEYWORDS.ARRAY_TYPE: {
|
683
692
|
if (typeof value === 'number')
|
684
|
-
return
|
693
|
+
return [...Number(value).toString()].map(Number)
|
685
694
|
else if (typeof value[Symbol.iterator] !== 'function')
|
686
695
|
throw new TypeError(
|
687
696
|
`Arguments are not iterable for ${KEYWORDS.ARRAY_TYPE} at (${
|
688
697
|
KEYWORDS.CAST_TYPE
|
689
|
-
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})
|
698
|
+
}) (${KEYWORDS.CAST_TYPE} ${stringifyArgs(args)})`
|
690
699
|
)
|
691
700
|
return [...value]
|
692
701
|
}
|
@@ -698,7 +707,7 @@ const keywords = {
|
|
698
707
|
KEYWORDS.CHAR_TYPE
|
699
708
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
700
709
|
KEYWORDS.CAST_TYPE
|
701
|
-
} ${stringifyArgs(args)})
|
710
|
+
} ${stringifyArgs(args)})`
|
702
711
|
)
|
703
712
|
return String.fromCharCode(index)
|
704
713
|
}
|
@@ -710,7 +719,7 @@ const keywords = {
|
|
710
719
|
KEYWORDS.CHAR_CODE_TYPE
|
711
720
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
712
721
|
KEYWORDS.CAST_TYPE
|
713
|
-
} ${stringifyArgs(args)})
|
722
|
+
} ${stringifyArgs(args)})`
|
714
723
|
)
|
715
724
|
if (string.length !== 1)
|
716
725
|
throw new RangeError(
|
@@ -718,7 +727,7 @@ const keywords = {
|
|
718
727
|
KEYWORDS.CHAR_CODE_TYPE
|
719
728
|
} at (${KEYWORDS.CAST_TYPE}) (${
|
720
729
|
KEYWORDS.CAST_TYPE
|
721
|
-
} ${stringifyArgs(args)})
|
730
|
+
} ${stringifyArgs(args)})`
|
722
731
|
)
|
723
732
|
return string.charCodeAt(0)
|
724
733
|
}
|
@@ -730,7 +739,7 @@ const keywords = {
|
|
730
739
|
KEYWORDS.CHAR_TYPE
|
731
740
|
} ${KEYWORDS.CHAR_CODE_TYPE}) at (${KEYWORDS.CAST_TYPE}) (${
|
732
741
|
KEYWORDS.CAST_TYPE
|
733
|
-
} ${stringifyArgs(args)})
|
742
|
+
} ${stringifyArgs(args)})`
|
734
743
|
)
|
735
744
|
}
|
736
745
|
}
|
@@ -747,7 +756,7 @@ const keywords = {
|
|
747
756
|
throw new TypeError(
|
748
757
|
`Not all arguments of (${KEYWORDS.BITWISE_AND}) are ${
|
749
758
|
KEYWORDS.NUMBER_TYPE
|
750
|
-
} (${KEYWORDS.BITWISE_AND} ${stringifyArgs(args)})
|
759
|
+
} (${KEYWORDS.BITWISE_AND} ${stringifyArgs(args)})`
|
751
760
|
)
|
752
761
|
return operands.reduce((acc, x) => acc & x)
|
753
762
|
},
|
@@ -763,7 +772,7 @@ const keywords = {
|
|
763
772
|
throw new TypeError(
|
764
773
|
`Argument of (${KEYWORDS.BITWISE_NOT}) is not a (${
|
765
774
|
KEYWORDS.NUMBER_TYPE
|
766
|
-
}) (${KEYWORDS.BITWISE_NOT} ${stringifyArgs(args)})
|
775
|
+
}) (${KEYWORDS.BITWISE_NOT} ${stringifyArgs(args)})`
|
767
776
|
)
|
768
777
|
return ~operand
|
769
778
|
},
|
@@ -779,7 +788,7 @@ const keywords = {
|
|
779
788
|
throw new TypeError(
|
780
789
|
`Not all arguments of (${KEYWORDS.BITWISE_OR}) are (${
|
781
790
|
KEYWORDS.NUMBER_TYPE
|
782
|
-
}) (${KEYWORDS.BITWISE_OR} ${stringifyArgs(args)})
|
791
|
+
}) (${KEYWORDS.BITWISE_OR} ${stringifyArgs(args)})`
|
783
792
|
)
|
784
793
|
return operands.reduce((acc, x) => acc | x)
|
785
794
|
},
|
@@ -788,14 +797,14 @@ const keywords = {
|
|
788
797
|
throw new RangeError(
|
789
798
|
`Invalid number of arguments to (${
|
790
799
|
KEYWORDS.BITWISE_XOR
|
791
|
-
}) (>= 2 required). (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})
|
800
|
+
}) (>= 2 required). (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})`
|
792
801
|
)
|
793
802
|
const operands = args.map((a) => evaluate(a, env))
|
794
803
|
if (operands.some((x) => typeof x !== 'number'))
|
795
804
|
throw new TypeError(
|
796
805
|
`Not all arguments of (${KEYWORDS.BITWISE_XOR}) are (${
|
797
806
|
KEYWORDS.NUMBER_TYPE
|
798
|
-
}) (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})
|
807
|
+
}) (${KEYWORDS.BITWISE_XOR} ${stringifyArgs(args)})`
|
799
808
|
)
|
800
809
|
return operands.reduce((acc, x) => acc ^ x)
|
801
810
|
},
|
@@ -806,14 +815,14 @@ const keywords = {
|
|
806
815
|
KEYWORDS.BITWISE_LEFT_SHIFT
|
807
816
|
}) (>= 2 required). (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(
|
808
817
|
args
|
809
|
-
)})
|
818
|
+
)})`
|
810
819
|
)
|
811
820
|
const operands = args.map((a) => evaluate(a, env))
|
812
821
|
if (operands.some((x) => typeof x !== 'number'))
|
813
822
|
throw new TypeError(
|
814
823
|
`Not all arguments of (${KEYWORDS.BITWISE_LEFT_SHIFT}) are (${
|
815
824
|
KEYWORDS.NUMBER_TYPE
|
816
|
-
}) (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(args)})
|
825
|
+
}) (${KEYWORDS.BITWISE_LEFT_SHIFT} ${stringifyArgs(args)})`
|
817
826
|
)
|
818
827
|
return operands.reduce((acc, x) => acc << x)
|
819
828
|
},
|
@@ -824,14 +833,14 @@ const keywords = {
|
|
824
833
|
KEYWORDS.BITWISE_RIGHT_SHIFT
|
825
834
|
}) (>= 2 required). (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(
|
826
835
|
args
|
827
|
-
)})
|
836
|
+
)})`
|
828
837
|
)
|
829
838
|
const operands = args.map((a) => evaluate(a, env))
|
830
839
|
if (operands.some((x) => typeof x !== 'number'))
|
831
840
|
throw new TypeError(
|
832
841
|
`Not all arguments of (${KEYWORDS.BITWISE_RIGHT_SHIFT}) are (${
|
833
842
|
KEYWORDS.NUMBER_TYPE
|
834
|
-
}) (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(args)})
|
843
|
+
}) (${KEYWORDS.BITWISE_RIGHT_SHIFT} ${stringifyArgs(args)})`
|
835
844
|
)
|
836
845
|
return operands.reduce((acc, x) => acc >> x)
|
837
846
|
},
|
@@ -842,14 +851,14 @@ const keywords = {
|
|
842
851
|
KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT
|
843
852
|
}) (>= 2 required). (${
|
844
853
|
KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT
|
845
|
-
} ${stringifyArgs(args)})
|
854
|
+
} ${stringifyArgs(args)})`
|
846
855
|
)
|
847
856
|
const operands = args.map((a) => evaluate(a, env))
|
848
857
|
if (operands.some((x) => typeof x !== 'number'))
|
849
858
|
throw new TypeError(
|
850
859
|
`Not all arguments of (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT}) are (${
|
851
860
|
KEYWORDS.NUMBER_TYPE
|
852
|
-
}) (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT} ${stringifyArgs(args)})
|
861
|
+
}) (${KEYWORDS.BITWISE_UNSIGNED_RIGHT_SHIFT} ${stringifyArgs(args)})`
|
853
862
|
)
|
854
863
|
return operands.reduce((acc, x) => acc >>> x)
|
855
864
|
},
|
@@ -879,14 +888,14 @@ const keywords = {
|
|
879
888
|
throw new RangeError(
|
880
889
|
`Invalid number of arguments to (${
|
881
890
|
KEYWORDS.THROW_ERROR
|
882
|
-
}) (1 required). (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})
|
891
|
+
}) (1 required). (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})`
|
883
892
|
)
|
884
893
|
const string = evaluate(args[0], env)
|
885
894
|
if (typeof string !== 'string')
|
886
895
|
throw new TypeError(
|
887
896
|
`First argument of (${KEYWORDS.THROW_ERROR}) must be an (${
|
888
897
|
KEYWORDS.STRING_TYPE
|
889
|
-
}) (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})
|
898
|
+
}) (${KEYWORDS.THROW_ERROR} ${stringifyArgs(args)})`
|
890
899
|
)
|
891
900
|
throw new Error(string)
|
892
901
|
},
|
@@ -895,14 +904,14 @@ const keywords = {
|
|
895
904
|
throw new RangeError(
|
896
905
|
`Invalid number of arguments to (${KEYWORDS.MERGE}) (>= 2 required). (${
|
897
906
|
KEYWORDS.MERGE
|
898
|
-
} ${stringifyArgs(args)})
|
907
|
+
} ${stringifyArgs(args)})`
|
899
908
|
)
|
900
909
|
const arrays = args.map((arg) => evaluate(arg, env))
|
901
910
|
if (arrays.some((maybe) => !Array.isArray(maybe)))
|
902
911
|
throw new TypeError(
|
903
912
|
`Arguments of (${KEYWORDS.MERGE}) must be (${KEYWORDS.ARRAY_TYPE}) (${
|
904
913
|
KEYWORDS.MERGE
|
905
|
-
} ${stringifyArgs(args)})
|
914
|
+
} ${stringifyArgs(args)})`
|
906
915
|
)
|
907
916
|
return arrays.reduce((a, b) => a.concat(b), [])
|
908
917
|
},
|
@@ -913,7 +922,7 @@ const keywords = {
|
|
913
922
|
KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION
|
914
923
|
}) (>= 2 required). (${
|
915
924
|
KEYWORDS.TAIL_CALLS_OPTIMISED_RECURSIVE_FUNCTION
|
916
|
-
} ${stringifyArgs(args)})
|
925
|
+
} ${stringifyArgs(args)})`
|
917
926
|
)
|
918
927
|
// TODO: Add validation for TCO recursion
|
919
928
|
return keywords[KEYWORDS.DEFINE_VARIABLE](args, env)
|
@@ -925,7 +934,7 @@ const keywords = {
|
|
925
934
|
KEYWORDS.IMMUTABLE_FUNCTION
|
926
935
|
}) (>= 2 required). (${KEYWORDS.IMMUTABLE_FUNCTION} ${stringifyArgs(
|
927
936
|
args
|
928
|
-
)})
|
937
|
+
)})`
|
929
938
|
)
|
930
939
|
const [definition, ...functionArgs] = args
|
931
940
|
const token = definition[VALUE]
|
@@ -1024,14 +1033,14 @@ const keywords = {
|
|
1024
1033
|
throw new TypeError(
|
1025
1034
|
`First argument of (${KEYWORDS.SET_ARRAY}) must be an (${
|
1026
1035
|
KEYWORDS.ARRAY_TYPE
|
1027
|
-
}) but got (${array}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})
|
1036
|
+
}) but got (${array}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})`
|
1028
1037
|
)
|
1029
1038
|
const index = evaluate(args[1], env)
|
1030
1039
|
if (!Number.isInteger(index))
|
1031
1040
|
throw new TypeError(
|
1032
1041
|
`Second argument of (${KEYWORDS.SET_ARRAY}) must be an (${
|
1033
1042
|
KEYWORDS.NUMBER_TYPE
|
1034
|
-
} integer) (${index}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})
|
1043
|
+
} integer) (${index}) (${KEYWORDS.SET_ARRAY} ${stringifyArgs(args)})`
|
1035
1044
|
)
|
1036
1045
|
if (index > array.length)
|
1037
1046
|
throw new RangeError(
|
@@ -1039,7 +1048,7 @@ const keywords = {
|
|
1039
1048
|
KEYWORDS.ARRAY_TYPE
|
1040
1049
|
}) bounds (index ${index} bounds ${array.length}) (${
|
1041
1050
|
KEYWORDS.SET_ARRAY
|
1042
|
-
} ${stringifyArgs(args)})
|
1051
|
+
} ${stringifyArgs(args)})`
|
1043
1052
|
)
|
1044
1053
|
if (index < 0) {
|
1045
1054
|
if (args.length !== 2)
|
@@ -1080,6 +1089,86 @@ const keywords = {
|
|
1080
1089
|
}
|
1081
1090
|
return array
|
1082
1091
|
},
|
1092
|
+
|
1093
|
+
[KEYWORDS.SET_IMMUTABLE_ARRAY]: (args, env) => {
|
1094
|
+
if (args.length !== 2 && args.length !== 3)
|
1095
|
+
throw new RangeError(
|
1096
|
+
`Invalid number of arguments for (${
|
1097
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1098
|
+
}) (or 2 3) required (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1099
|
+
args
|
1100
|
+
)})`
|
1101
|
+
)
|
1102
|
+
let array = evaluate(args[0], env)
|
1103
|
+
if (!Array.isArray(array))
|
1104
|
+
throw new TypeError(
|
1105
|
+
`First argument of (${KEYWORDS.SET_IMMUTABLE_ARRAY}) must be an (${
|
1106
|
+
KEYWORDS.ARRAY_TYPE
|
1107
|
+
}) but got (${array}) (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1108
|
+
args
|
1109
|
+
)})`
|
1110
|
+
)
|
1111
|
+
array = [...array]
|
1112
|
+
const index = evaluate(args[1], env)
|
1113
|
+
if (!Number.isInteger(index))
|
1114
|
+
throw new TypeError(
|
1115
|
+
`Second argument of (${KEYWORDS.SET_IMMUTABLE_ARRAY}) must be an (${
|
1116
|
+
KEYWORDS.NUMBER_TYPE
|
1117
|
+
} integer) (${index}) (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(
|
1118
|
+
args
|
1119
|
+
)})`
|
1120
|
+
)
|
1121
|
+
if (index > array.length)
|
1122
|
+
throw new RangeError(
|
1123
|
+
`Second argument of (${
|
1124
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1125
|
+
}) is outside of the (${
|
1126
|
+
KEYWORDS.ARRAY_TYPE
|
1127
|
+
}) bounds (index ${index} bounds ${array.length}) (${
|
1128
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1129
|
+
} ${stringifyArgs(args)})`
|
1130
|
+
)
|
1131
|
+
if (index < 0) {
|
1132
|
+
if (args.length !== 2)
|
1133
|
+
throw new RangeError(
|
1134
|
+
`Invalid number of arguments for (${
|
1135
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1136
|
+
}) (if (< index 0) then 2 required) (${
|
1137
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1138
|
+
} ${stringifyArgs(args)})`
|
1139
|
+
)
|
1140
|
+
if (index * -1 > array.length)
|
1141
|
+
throw new RangeError(
|
1142
|
+
`Second argument of (${
|
1143
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1144
|
+
}) is outside of the (${
|
1145
|
+
KEYWORDS.ARRAY_TYPE
|
1146
|
+
}) bounds (index ${index} bounds ${array.length}) (${
|
1147
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1148
|
+
} ${stringifyArgs(args)})`
|
1149
|
+
)
|
1150
|
+
const target = array.length + index
|
1151
|
+
while (array.length !== target) array.pop()
|
1152
|
+
} else {
|
1153
|
+
if (args.length !== 3)
|
1154
|
+
throw new RangeError(
|
1155
|
+
`Invalid number of arguments for (${
|
1156
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1157
|
+
}) (if (>= index 0) then 3 required) (${
|
1158
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1159
|
+
} ${stringifyArgs(args)})`
|
1160
|
+
)
|
1161
|
+
const value = evaluate(args[2], env)
|
1162
|
+
if (value == undefined)
|
1163
|
+
throw new RangeError(
|
1164
|
+
`Trying to set a null value in (${KEYWORDS.ARRAY_TYPE}) at (${
|
1165
|
+
KEYWORDS.SET_IMMUTABLE_ARRAY
|
1166
|
+
}). (${KEYWORDS.SET_IMMUTABLE_ARRAY} ${stringifyArgs(args)})`
|
1167
|
+
)
|
1168
|
+
array[index] = value
|
1169
|
+
}
|
1170
|
+
return array
|
1171
|
+
},
|
1083
1172
|
}
|
1084
1173
|
keywords[KEYWORDS.NOT_COMPILED_BLOCK] = keywords[KEYWORDS.BLOCK]
|
1085
1174
|
export { keywords }
|