fez-lisp 1.2.33 → 1.2.35
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 +4 -7
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/compiler.js +8 -7
- package/src/interpreter.js +84 -11
- package/src/keywords.js +3 -1
- package/src/utils.js +1 -1
package/package.json
CHANGED
package/src/compiler.js
CHANGED
@@ -109,7 +109,8 @@ const Helpers = {
|
|
109
109
|
__tco: `__tco=fn=>(...args)=>{let result=fn(...args);while(typeof result==='function')result=result();return result}`,
|
110
110
|
atom_predicate: `atom_predicate=(number)=>+(typeof number==='number')`,
|
111
111
|
lambda_predicate: `lambda_predicate=(fm)=>+(typeof fn==='function')`,
|
112
|
-
set_effect: `set_effect=(array,index,value)=>{if(index<0){const target=array.length+index;while(array.length!==target)array.pop()}else array[index] = value;return array}
|
112
|
+
set_effect: `set_effect=(array,index,value)=>{if(index<0){const target=array.length+index;while(array.length!==target)array.pop()}else array[index] = value;return array}`,
|
113
|
+
__error: `__error=(error)=>{throw new Error(error.map((x)=>String.fromCharCode(x)).join(''))}`
|
113
114
|
}
|
114
115
|
const semiColumnEdgeCases = new Set([
|
115
116
|
';)',
|
@@ -141,6 +142,8 @@ const compile = (tree, Drill) => {
|
|
141
142
|
const token = first[VALUE]
|
142
143
|
if (first[TYPE] === APPLY) {
|
143
144
|
switch (token) {
|
145
|
+
case KEYWORDS.ASSERT:
|
146
|
+
return '0'
|
144
147
|
case KEYWORDS.BLOCK: {
|
145
148
|
if (Arguments.length > 1) {
|
146
149
|
return `(${Arguments.map((x) =>
|
@@ -292,12 +295,10 @@ const compile = (tree, Drill) => {
|
|
292
295
|
out += '0);'
|
293
296
|
return out
|
294
297
|
}
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
// return compile(inp, Drill)
|
300
|
-
// }
|
298
|
+
case KEYWORDS.THROW: {
|
299
|
+
Drill.Helpers.add('__error')
|
300
|
+
return `__error(${compile(Arguments[0], Drill)})`
|
301
|
+
}
|
301
302
|
default: {
|
302
303
|
const camelCased = lispToJavaScriptVariableName(token)
|
303
304
|
if (camelCased in Helpers) Drill.Helpers.add(camelCased)
|
package/src/interpreter.js
CHANGED
@@ -3,14 +3,12 @@ import {
|
|
3
3
|
VALUE,
|
4
4
|
WORD,
|
5
5
|
KEYWORDS,
|
6
|
-
APPLY,
|
7
|
-
ATOM,
|
8
6
|
FALSE,
|
9
7
|
TRUE,
|
10
|
-
TYPES
|
8
|
+
TYPES,
|
9
|
+
APPLY
|
11
10
|
} from './keywords.js'
|
12
11
|
import { evaluate } from './evaluator.js'
|
13
|
-
import { isLeaf } from './parser.js'
|
14
12
|
import { isForbiddenVariableName, stringifyArgs } from './utils.js'
|
15
13
|
const keywords = {
|
16
14
|
[KEYWORDS.REMAINDER_OF_DIVISION]: (args, env) => {
|
@@ -172,7 +170,9 @@ const keywords = {
|
|
172
170
|
const condition = evaluate(args[0], env)
|
173
171
|
if (condition !== FALSE && condition !== TRUE)
|
174
172
|
throw new TypeError(
|
175
|
-
`Condition of (${KEYWORDS.IF}) must be ${TRUE} or ${FALSE} but got ${
|
173
|
+
`Condition of (${KEYWORDS.IF}) must be ${TRUE} or ${FALSE} but got (${
|
174
|
+
KEYWORDS.IF
|
175
|
+
} ${stringifyArgs(args)})`
|
176
176
|
)
|
177
177
|
return condition
|
178
178
|
? evaluate(args[1], env)
|
@@ -201,7 +201,11 @@ const keywords = {
|
|
201
201
|
const condition = evaluate(args[i], env)
|
202
202
|
if (condition !== FALSE && condition !== TRUE)
|
203
203
|
throw new TypeError(
|
204
|
-
`Condition of (${
|
204
|
+
`Condition of (${
|
205
|
+
KEYWORDS.CONDITION
|
206
|
+
}) must be ${TRUE} or ${FALSE} but got (${
|
207
|
+
KEYWORDS.CONDITION
|
208
|
+
} ${stringifyArgs(args)})`
|
205
209
|
)
|
206
210
|
if (condition) return evaluate(args[i + 1], env)
|
207
211
|
}
|
@@ -437,7 +441,11 @@ const keywords = {
|
|
437
441
|
circuit = evaluate(args[i], env)
|
438
442
|
if (circuit !== FALSE && circuit !== TRUE)
|
439
443
|
throw new TypeError(
|
440
|
-
`Condition of (${
|
444
|
+
`Condition of (${
|
445
|
+
KEYWORDS.AND
|
446
|
+
}) must be ${TRUE} or ${FALSE} but got (${
|
447
|
+
KEYWORDS.AND
|
448
|
+
} ${stringifyArgs(args)})`
|
441
449
|
)
|
442
450
|
if (circuit) continue
|
443
451
|
else return 0
|
@@ -445,7 +453,9 @@ const keywords = {
|
|
445
453
|
const end = evaluate(args.at(-1), env)
|
446
454
|
if (end !== FALSE && end !== TRUE)
|
447
455
|
throw new TypeError(
|
448
|
-
`Condition of (${KEYWORDS.AND}) must be ${TRUE} or ${FALSE} but got ${
|
456
|
+
`Condition of (${KEYWORDS.AND}) must be ${TRUE} or ${FALSE} but got (${
|
457
|
+
KEYWORDS.AND
|
458
|
+
} ${stringifyArgs(args)})`
|
449
459
|
)
|
450
460
|
return end
|
451
461
|
},
|
@@ -461,7 +471,9 @@ const keywords = {
|
|
461
471
|
circuit = evaluate(args[i], env)
|
462
472
|
if (circuit !== FALSE && circuit !== TRUE)
|
463
473
|
throw new TypeError(
|
464
|
-
`Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got ${
|
474
|
+
`Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got (${
|
475
|
+
KEYWORDS.OR
|
476
|
+
} ${stringifyArgs(args)})`
|
465
477
|
)
|
466
478
|
if (circuit) return 1
|
467
479
|
else continue
|
@@ -469,7 +481,9 @@ const keywords = {
|
|
469
481
|
const end = evaluate(args.at(-1), env)
|
470
482
|
if (end !== FALSE && end !== TRUE)
|
471
483
|
throw new TypeError(
|
472
|
-
`Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got ${
|
484
|
+
`Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got (${
|
485
|
+
KEYWORDS.OR
|
486
|
+
} ${stringifyArgs(args)})`
|
473
487
|
)
|
474
488
|
return end
|
475
489
|
},
|
@@ -795,8 +809,67 @@ const keywords = {
|
|
795
809
|
)
|
796
810
|
console.clear()
|
797
811
|
return 0
|
812
|
+
},
|
813
|
+
|
814
|
+
// Not sure about these
|
815
|
+
[KEYWORDS.THROW]: (args, env) => {
|
816
|
+
if (args.length !== 1)
|
817
|
+
throw new RangeError(
|
818
|
+
`Invalid number of arguments to (${KEYWORDS.THROW}) (= 1 required) (${
|
819
|
+
KEYWORDS.THROW
|
820
|
+
} ${stringifyArgs(args)})`
|
821
|
+
)
|
822
|
+
const expression = evaluate(args[0], env)
|
823
|
+
if (!Array.isArray(expression))
|
824
|
+
throw new TypeError(
|
825
|
+
`Argument of (${KEYWORDS.THROW}) must be an (${
|
826
|
+
KEYWORDS.ARRAY_TYPE
|
827
|
+
}) but got (${expression}) (${KEYWORDS.THROW} ${stringifyArgs(args)})`
|
828
|
+
)
|
829
|
+
throw new Error(expression.map((x) => String.fromCharCode(x)).join(''))
|
830
|
+
},
|
831
|
+
|
832
|
+
[KEYWORDS.ASSERT]: (args, env) => {
|
833
|
+
if (args.length < 2)
|
834
|
+
throw new RangeError(
|
835
|
+
`Invalid number of arguments for (${
|
836
|
+
KEYWORDS.ASSERT
|
837
|
+
}), expected (> 2 required) but got ${args.length} (${
|
838
|
+
KEYWORDS.ASSERT
|
839
|
+
} ${stringifyArgs(args)})`
|
840
|
+
)
|
841
|
+
if (args.length % 2 !== 0)
|
842
|
+
throw new RangeError(
|
843
|
+
`Invalid number of arguments for (${
|
844
|
+
KEYWORDS.ASSERT
|
845
|
+
}), expected even number of arguments but got ${args.length} (${
|
846
|
+
KEYWORDS.ASSERT
|
847
|
+
} ${stringifyArgs(args)})`
|
848
|
+
)
|
849
|
+
for (let i = 0; i < args.length; i += 2) {
|
850
|
+
const condition = evaluate(args[i], env)
|
851
|
+
if (condition !== FALSE && condition !== TRUE)
|
852
|
+
throw new TypeError(
|
853
|
+
`Condition of (${
|
854
|
+
KEYWORDS.ASSERT
|
855
|
+
}) must be ${TRUE} or ${FALSE} but got (${
|
856
|
+
KEYWORDS.ASSERT
|
857
|
+
} ${stringifyArgs(args)})`
|
858
|
+
)
|
859
|
+
if (condition) {
|
860
|
+
const error = args[i + 1]
|
861
|
+
if (error[0][TYPE] === APPLY && error[0][VALUE] === KEYWORDS.THROW)
|
862
|
+
return evaluate(error, env)
|
863
|
+
else
|
864
|
+
throw new TypeError(
|
865
|
+
`Concequence of (${KEYWORDS.ASSERT}) must be (${
|
866
|
+
KEYWORDS.THROW
|
867
|
+
}) but got (${KEYWORDS.ASSERT} ${stringifyArgs(args)})`
|
868
|
+
)
|
869
|
+
}
|
870
|
+
}
|
871
|
+
return 0
|
798
872
|
}
|
799
873
|
}
|
800
|
-
keywords[KEYWORDS.NOT_COMPILED_BLOCK] = keywords[KEYWORDS.BLOCK]
|
801
874
|
|
802
875
|
export { keywords }
|
package/src/keywords.js
CHANGED
@@ -44,12 +44,14 @@ export const KEYWORDS = {
|
|
44
44
|
|
45
45
|
SET_ARRAY: 'set!',
|
46
46
|
|
47
|
-
NOT_COMPILED_BLOCK: 'void',
|
48
47
|
LOG: 'log!',
|
49
48
|
LOG_STRING: 'log-string!',
|
50
49
|
LOG_CHAR: 'log-char!',
|
51
50
|
CLEAR_CONSOLE: 'clear!',
|
52
51
|
|
52
|
+
THROW: 'throw',
|
53
|
+
ASSERT: 'assert',
|
54
|
+
|
53
55
|
// Syntactic suggars
|
54
56
|
PIPE: '|>',
|
55
57
|
NOT_EQUAL_1: '!=',
|
package/src/utils.js
CHANGED
@@ -70,7 +70,7 @@ export const stringifyArrayTypes = (type) =>
|
|
70
70
|
: 'number'
|
71
71
|
export const stringifyType = (type) => {
|
72
72
|
if (!isLeaf(type)) {
|
73
|
-
const [car
|
73
|
+
const [car] = type
|
74
74
|
if (car == undefined) return '(array)'
|
75
75
|
else if (car[TYPE] === APPLY && car[VALUE] === KEYWORDS.ARRAY_TYPE)
|
76
76
|
return `(array ${type
|