fez-lisp 1.2.49 → 1.2.50
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/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/compiler.js +6 -5
- package/src/interpreter.js +0 -23
- package/src/keywords.js +14 -11
- package/src/utils.js +66 -14
package/package.json
CHANGED
package/src/compiler.js
CHANGED
@@ -5,7 +5,8 @@ import {
|
|
5
5
|
KEYWORDS,
|
6
6
|
TYPE,
|
7
7
|
VALUE,
|
8
|
-
WORD
|
8
|
+
WORD,
|
9
|
+
SUGGAR
|
9
10
|
} from './keywords.js'
|
10
11
|
import { leaf, isLeaf } from './parser.js'
|
11
12
|
const deepRenameTco = (name, newName, tree) => {
|
@@ -176,9 +177,9 @@ const compile = (tree, Drill) => {
|
|
176
177
|
case KEYWORDS.DEFINE_VARIABLE: {
|
177
178
|
const n = Arguments[0][VALUE]
|
178
179
|
const prefix = n.split(':')[0]
|
179
|
-
if (prefix ===
|
180
|
+
if (prefix === SUGGAR.RECURSION) {
|
180
181
|
const name = lispToJavaScriptVariableName(n)
|
181
|
-
const newName =
|
182
|
+
const newName = `${SUGGAR.RECURSION}_${performance
|
182
183
|
.now()
|
183
184
|
.toString()
|
184
185
|
.replace('.', 7)}`
|
@@ -199,10 +200,10 @@ const compile = (tree, Drill) => {
|
|
199
200
|
)})=>{${vars}return ${evaluatedBody
|
200
201
|
.toString()
|
201
202
|
.trim()}}, ${newName})));`
|
202
|
-
} else if (prefix ===
|
203
|
+
} else if (prefix === SUGGAR.CACHE) {
|
203
204
|
// memoization here
|
204
205
|
const name = lispToJavaScriptVariableName(n)
|
205
|
-
const newName = name.substring(
|
206
|
+
const newName = name.substring(SUGGAR.CACHE.length + 1)
|
206
207
|
Drill.Variables.add(name)
|
207
208
|
const functionArgs = Arguments.at(-1).slice(1)
|
208
209
|
const body = functionArgs.pop()
|
package/src/interpreter.js
CHANGED
@@ -651,29 +651,6 @@ export const keywords = {
|
|
651
651
|
)
|
652
652
|
return operands.reduce((acc, x) => acc >>> x)
|
653
653
|
},
|
654
|
-
// [KEYWORDS.PIPE]: (args, env) => {
|
655
|
-
// if (args.length < 1)
|
656
|
-
// throw new RangeError(
|
657
|
-
// `Invalid number of arguments to (${KEYWORDS.PIPE}) (>= 1 required). (${
|
658
|
-
// KEYWORDS.PIPE
|
659
|
-
// } ${stringifyArgs(args)})`
|
660
|
-
// )
|
661
|
-
// let inp = args[0]
|
662
|
-
// for (let i = 1; i < args.length; ++i) {
|
663
|
-
// if (!args[i].length || args[i][0][TYPE] !== APPLY)
|
664
|
-
// throw new TypeError(
|
665
|
-
// `Argument at position (${i}) of (${
|
666
|
-
// KEYWORDS.PIPE
|
667
|
-
// }) is not an invoked (${KEYWORDS.ANONYMOUS_FUNCTION}). (${
|
668
|
-
// KEYWORDS.PIPE
|
669
|
-
// } ${stringifyArgs(args)})`
|
670
|
-
// )
|
671
|
-
// const [first, ...rest] = args[i]
|
672
|
-
// const arr = [first, inp, ...rest]
|
673
|
-
// inp = arr
|
674
|
-
// }
|
675
|
-
// return evaluate(inp, env)
|
676
|
-
// },
|
677
654
|
[KEYWORDS.SET_ARRAY]: (args, env) => {
|
678
655
|
if (args.length !== 1 && args.length !== 3)
|
679
656
|
throw new RangeError(
|
package/src/keywords.js
CHANGED
@@ -6,6 +6,19 @@ export const ATOM = 2
|
|
6
6
|
export const TRUE = 1
|
7
7
|
export const FALSE = 0
|
8
8
|
export const PLACEHOLDER = '.'
|
9
|
+
export const SUGGAR = {
|
10
|
+
// Syntactic suggars
|
11
|
+
PIPE: '|>',
|
12
|
+
NOT_EQUAL_1: '!=',
|
13
|
+
NOT_EQUAL_2: '<>',
|
14
|
+
UNLESS: 'unless',
|
15
|
+
LIST_TYPE: 'list',
|
16
|
+
POWER: '**',
|
17
|
+
INTEGER_DEVISION: '//',
|
18
|
+
|
19
|
+
RECURSION: 'recursive',
|
20
|
+
CACHE: 'memoized'
|
21
|
+
}
|
9
22
|
export const KEYWORDS = {
|
10
23
|
NUMBER_TYPE: 'number',
|
11
24
|
ARRAY_TYPE: 'array',
|
@@ -49,17 +62,7 @@ export const KEYWORDS = {
|
|
49
62
|
LOG_CHAR: 'log-char!',
|
50
63
|
CLEAR_CONSOLE: 'clear!',
|
51
64
|
|
52
|
-
THROW: 'throw'
|
53
|
-
|
54
|
-
// Syntactic suggars
|
55
|
-
PIPE: '|>',
|
56
|
-
NOT_EQUAL_1: '!=',
|
57
|
-
NOT_EQUAL_2: '<>',
|
58
|
-
UNLESS: 'unless',
|
59
|
-
LIST_TYPE: 'list',
|
60
|
-
|
61
|
-
RECURSION: 'recursive',
|
62
|
-
CACHE: 'memoized'
|
65
|
+
THROW: 'throw'
|
63
66
|
}
|
64
67
|
|
65
68
|
export const TYPES = {
|
package/src/utils.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import std from '../lib/baked/std.js'
|
2
2
|
import { comp } from './compiler.js'
|
3
|
-
import { APPLY, ATOM, KEYWORDS, TYPE, VALUE, WORD } from './keywords.js'
|
3
|
+
import { APPLY, ATOM, KEYWORDS, SUGGAR, TYPE, VALUE, WORD } from './keywords.js'
|
4
4
|
import { evaluate, run } from './evaluator.js'
|
5
5
|
import { AST, isLeaf, LISP } from './parser.js'
|
6
6
|
export const logError = (error) =>
|
@@ -102,8 +102,8 @@ export const isForbiddenVariableName = (name) => {
|
|
102
102
|
switch (name) {
|
103
103
|
case '_':
|
104
104
|
case KEYWORDS.DEFINE_VARIABLE:
|
105
|
-
case
|
106
|
-
case
|
105
|
+
case SUGGAR.RECURSION:
|
106
|
+
case SUGGAR.CACHE:
|
107
107
|
return true
|
108
108
|
default:
|
109
109
|
return !isNaN(name[0])
|
@@ -410,13 +410,13 @@ export const deSuggar = (ast) => {
|
|
410
410
|
// }
|
411
411
|
// }
|
412
412
|
// break
|
413
|
-
case
|
413
|
+
case SUGGAR.PIPE:
|
414
414
|
{
|
415
415
|
if (rest.length < 1)
|
416
416
|
throw new RangeError(
|
417
417
|
`Invalid number of arguments to (${
|
418
|
-
|
419
|
-
}) (>= 1 required). (${
|
418
|
+
SUGGAR.PIPE
|
419
|
+
}) (>= 1 required). (${SUGGAR.PIPE} ${stringifyArgs(
|
420
420
|
rest
|
421
421
|
)})`
|
422
422
|
)
|
@@ -426,10 +426,10 @@ export const deSuggar = (ast) => {
|
|
426
426
|
if (!rest[i].length || rest[i][0][TYPE] !== APPLY)
|
427
427
|
throw new TypeError(
|
428
428
|
`Argument at position (${i}) of (${
|
429
|
-
|
429
|
+
SUGGAR.PIPE
|
430
430
|
}) is not an invoked (${
|
431
431
|
KEYWORDS.ANONYMOUS_FUNCTION
|
432
|
-
}). (${
|
432
|
+
}). (${SUGGAR.PIPE} ${stringifyArgs(rest)})`
|
433
433
|
)
|
434
434
|
inp = [rest[i].shift(), inp, ...rest[i]]
|
435
435
|
}
|
@@ -437,7 +437,7 @@ export const deSuggar = (ast) => {
|
|
437
437
|
deSuggar(exp)
|
438
438
|
}
|
439
439
|
break
|
440
|
-
case
|
440
|
+
case SUGGAR.LIST_TYPE:
|
441
441
|
{
|
442
442
|
exp.length = 0
|
443
443
|
let temp = exp
|
@@ -449,6 +449,58 @@ export const deSuggar = (ast) => {
|
|
449
449
|
deSuggar(exp)
|
450
450
|
}
|
451
451
|
break
|
452
|
+
case SUGGAR.INTEGER_DEVISION:
|
453
|
+
{
|
454
|
+
if (rest.some((x) => x[TYPE] === APPLY))
|
455
|
+
throw new TypeError(
|
456
|
+
`Arguments of (${
|
457
|
+
SUGGAR.INTEGER_DEVISION
|
458
|
+
}), must be (or atom word) (hint use (math:floor (${
|
459
|
+
KEYWORDS.DIVISION
|
460
|
+
} a b)) instead) (${
|
461
|
+
SUGGAR.INTEGER_DEVISION
|
462
|
+
} ${stringifyArgs(rest)})`
|
463
|
+
)
|
464
|
+
else {
|
465
|
+
exp.length = 1
|
466
|
+
exp[0] = [APPLY, KEYWORDS.BITWISE_OR]
|
467
|
+
exp.push([[APPLY, KEYWORDS.DIVISION], ...rest])
|
468
|
+
exp.push([ATOM, 0])
|
469
|
+
}
|
470
|
+
}
|
471
|
+
break
|
472
|
+
case SUGGAR.POWER:
|
473
|
+
{
|
474
|
+
if (rest.length !== 2)
|
475
|
+
throw new RangeError(
|
476
|
+
`Invalid number of arguments for (${
|
477
|
+
SUGGAR.POWER
|
478
|
+
}), expected (= 2) but got ${rest.length} (${
|
479
|
+
SUGGAR.POWER
|
480
|
+
} ${stringifyArgs(rest)})`
|
481
|
+
)
|
482
|
+
if (
|
483
|
+
(exp[2][TYPE] === ATOM || exp[2][TYPE] === WORD) &&
|
484
|
+
(exp[1][TYPE] === WORD || exp[1][TYPE] === ATOM)
|
485
|
+
) {
|
486
|
+
exp[0][VALUE] = KEYWORDS.MULTIPLICATION
|
487
|
+
const exponent = exp[1]
|
488
|
+
const power = exp[2][VALUE]
|
489
|
+
exp.length = 1
|
490
|
+
const right = Array.from({ length: power })
|
491
|
+
.fill(0)
|
492
|
+
.map(() => [exponent[TYPE], exponent[VALUE]])
|
493
|
+
exp.push(...right)
|
494
|
+
} else
|
495
|
+
throw new TypeError(
|
496
|
+
`ArgumentS of (${
|
497
|
+
SUGGAR.POWER
|
498
|
+
}), must be (or atom word) (hint use math:power instead) (${
|
499
|
+
SUGGAR.POWER
|
500
|
+
} ${stringifyArgs(rest)})`
|
501
|
+
)
|
502
|
+
}
|
503
|
+
break
|
452
504
|
case KEYWORDS.MULTIPLICATION:
|
453
505
|
if (!rest.length) {
|
454
506
|
exp[0][0] = 2
|
@@ -462,14 +514,14 @@ export const deSuggar = (ast) => {
|
|
462
514
|
exp[0][1] = 0
|
463
515
|
}
|
464
516
|
break
|
465
|
-
case
|
517
|
+
case SUGGAR.UNLESS:
|
466
518
|
{
|
467
519
|
if (rest.length > 3 || rest.length < 2)
|
468
520
|
throw new RangeError(
|
469
521
|
`Invalid number of arguments for (${
|
470
|
-
|
522
|
+
SUGGAR.UNLESS
|
471
523
|
}), expected (or (= 3) (= 2)) but got ${rest.length} (${
|
472
|
-
|
524
|
+
SUGGAR.UNLESS
|
473
525
|
} ${stringifyArgs(rest)})`
|
474
526
|
)
|
475
527
|
exp[0][1] = KEYWORDS.IF
|
@@ -480,8 +532,8 @@ export const deSuggar = (ast) => {
|
|
480
532
|
deSuggar(exp)
|
481
533
|
break
|
482
534
|
|
483
|
-
case
|
484
|
-
case
|
535
|
+
case SUGGAR.NOT_EQUAL_1:
|
536
|
+
case SUGGAR.NOT_EQUAL_2:
|
485
537
|
{
|
486
538
|
if (rest.length > 3 || rest.length < 2)
|
487
539
|
throw new RangeError(
|