fez-lisp 1.5.108 → 1.5.110
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/check.js +135 -119
- package/src/compiler.js +5 -0
- package/src/enchance.js +2 -2
- package/src/keywords.js +31 -0
- package/src/macros.js +16 -8
- package/src/types.js +73 -62
- package/src/utils.js +1 -0
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -3,6 +3,9 @@ import {
|
|
3
3
|
ATOM,
|
4
4
|
FALSE,
|
5
5
|
KEYWORDS,
|
6
|
+
MULTI_DIMENTIONAL_SETTERS,
|
7
|
+
MUTATION_SUFFIX,
|
8
|
+
MUTATORS_SET,
|
6
9
|
PLACEHOLDER,
|
7
10
|
PREDICATE_SUFFIX,
|
8
11
|
PREDICATES_INPUT_SET,
|
@@ -35,7 +38,10 @@ import {
|
|
35
38
|
formatType,
|
36
39
|
ANONYMOUS_FUNCTION_TYPE_PREFIX,
|
37
40
|
validateLambda,
|
38
|
-
NIL
|
41
|
+
NIL,
|
42
|
+
TRUE_WORD,
|
43
|
+
FALSE_WORD,
|
44
|
+
BOOLEAN_SUBTYPE
|
39
45
|
} from './types.js'
|
40
46
|
import {
|
41
47
|
Brr,
|
@@ -90,6 +96,15 @@ export const setPropToAtom = (stats, prop) => {
|
|
90
96
|
(stats[prop][0] = ATOM)
|
91
97
|
)
|
92
98
|
}
|
99
|
+
export const setPropToPredicate = (stats, prop) => {
|
100
|
+
return (stats[prop][1] = BOOLEAN_SUBTYPE())
|
101
|
+
}
|
102
|
+
export const setReturnToPredicate = (stats) => {
|
103
|
+
return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
|
104
|
+
}
|
105
|
+
export const setTypeToPredicate = (stats) => {
|
106
|
+
return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
|
107
|
+
}
|
93
108
|
export const setPropToAbstraction = (stats, prop) => {
|
94
109
|
return (
|
95
110
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
@@ -100,14 +115,16 @@ export const setProp = (stats, prop, value) => {
|
|
100
115
|
return (
|
101
116
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
102
117
|
value[prop][0] !== UNKNOWN &&
|
103
|
-
(stats[prop][0] = value[prop][0])
|
118
|
+
((stats[prop][0] = value[prop][0]),
|
119
|
+
value[prop][1] && (stats[prop][1] = value[prop][1]))
|
104
120
|
)
|
105
121
|
}
|
106
122
|
export const setPropToReturn = (stats, prop, value) => {
|
107
123
|
return (
|
108
124
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
109
125
|
value[RETURNS][0] !== UNKNOWN &&
|
110
|
-
(stats[prop][0] = value[RETURNS][0])
|
126
|
+
((stats[prop][0] = value[RETURNS][0]),
|
127
|
+
value[RETURNS][1] && (stats[prop][1] = value[RETURNS][1]))
|
111
128
|
)
|
112
129
|
}
|
113
130
|
export const setPropToReturnRef = (stats, prop, value) => {
|
@@ -120,7 +137,8 @@ export const setPropToReturnRef = (stats, prop, value) => {
|
|
120
137
|
export const setPropToType = (stats, prop, value) => {
|
121
138
|
return (
|
122
139
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
123
|
-
(stats[prop][0] = value[TYPE_PROP][0])
|
140
|
+
((stats[prop][0] = value[TYPE_PROP][0]),
|
141
|
+
value[TYPE_PROP][1] && (stats[prop][1] = value[TYPE_PROP][1]))
|
124
142
|
)
|
125
143
|
}
|
126
144
|
export const setPropToTypeRef = (stats, prop, value) => {
|
@@ -169,27 +187,33 @@ export const setReturn = (stats, value) => {
|
|
169
187
|
return (
|
170
188
|
isUnknownReturn(stats) &&
|
171
189
|
!isUnknownReturn(value) &&
|
172
|
-
(stats[RETURNS][0] = value[RETURNS][0])
|
190
|
+
((stats[RETURNS][0] = value[RETURNS][0]),
|
191
|
+
value[RETURNS][1] && (stats[RETURNS][1] = value[RETURNS][1]))
|
173
192
|
)
|
174
193
|
}
|
175
194
|
export const setType = (stats, value) =>
|
176
195
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
177
196
|
!isUnknownType(value) &&
|
178
|
-
(stats[TYPE_PROP][0] = value[TYPE_PROP][0])
|
197
|
+
((stats[TYPE_PROP][0] = value[TYPE_PROP][0]),
|
198
|
+
value[TYPE_PROP][1] && (stats[TYPE_PROP][1] = value[TYPE_PROP][1]))
|
179
199
|
export const setTypeToReturn = (stats, value) =>
|
180
200
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
181
201
|
!isUnknownReturn(value) &&
|
182
|
-
(stats[TYPE_PROP][0] = value[RETURNS][0])
|
202
|
+
((stats[TYPE_PROP][0] = value[RETURNS][0]),
|
203
|
+
value[RETURNS][1] && (stats[TYPE_PROP][1] = value[RETURNS][1]))
|
183
204
|
export const setReturnToType = (stats, value) =>
|
184
205
|
(isUnknownReturn(stats) || isAnyReturn(stats)) &&
|
185
206
|
!isUnknownType(value) &&
|
186
|
-
(stats[RETURNS][0] = value[TYPE_PROP][0])
|
207
|
+
((stats[RETURNS][0] = value[TYPE_PROP][0]),
|
208
|
+
value[TYPE_PROP][1] && (stats[RETURNS][1] = value[TYPE_PROP][1]))
|
187
209
|
export const isAnyReturn = (stats) => stats && stats[RETURNS][0] === ANY
|
188
210
|
export const isAnyType = (stats) => stats && stats[TYPE_PROP][0] === ANY
|
189
211
|
export const isUnknownType = (stats) => stats && stats[TYPE_PROP][0] === UNKNOWN
|
190
212
|
export const isUnknownReturn = (stats) => stats[RETURNS][0] === UNKNOWN
|
191
213
|
export const getType = (stats) => stats && stats[TYPE_PROP][0]
|
214
|
+
export const getTypes = (stats) => stats && stats[TYPE_PROP]
|
192
215
|
export const getReturn = (stats) => stats && stats[RETURNS][0]
|
216
|
+
export const getReturns = (stats) => stats && stats[RETURNS]
|
193
217
|
export const isAtomType = (stats) =>
|
194
218
|
isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
|
195
219
|
export const isAtomReturn = (stats) =>
|
@@ -200,59 +224,56 @@ export const compareReturns = (a, b) =>
|
|
200
224
|
isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
|
201
225
|
export const compareTypeWithReturn = (a, b) =>
|
202
226
|
isAnyType(a) || isAnyReturn(b) || a[TYPE_PROP][0] === b[RETURNS][0]
|
227
|
+
const IsPredicate = (leaf) =>
|
228
|
+
(leaf[TYPE] === ATOM && (leaf[VALUE] === TRUE || leaf[VALUE] === FALSE)) ||
|
229
|
+
(leaf[TYPE] === WORD &&
|
230
|
+
(leaf[VALUE] === TRUE_WORD ||
|
231
|
+
leaf[VALUE] === FALSE_WORD ||
|
232
|
+
leaf[VALUE] === NIL ||
|
233
|
+
getSuffix(leaf[VALUE]) === PREDICATE_SUFFIX)) ||
|
234
|
+
(leaf[TYPE] === APPLY &&
|
235
|
+
(PREDICATES_OUTPUT_SET.has(leaf[VALUE]) ||
|
236
|
+
getSuffix(leaf[VALUE]) === PREDICATE_SUFFIX))
|
203
237
|
const checkPredicateName = (exp, rest) => {
|
204
238
|
if (getSuffix(rest[0][VALUE]) === PREDICATE_SUFFIX) {
|
205
239
|
const last = rest.at(-1)
|
206
|
-
if (isLeaf(last)) {
|
207
|
-
if (last
|
240
|
+
if (last[TYPE] !== APPLY && isLeaf(last) && !IsPredicate(last)) {
|
241
|
+
if (!IsPredicate(last))
|
208
242
|
throw new TypeError(
|
209
|
-
`Assigning predicate (ending in ?) variable
|
243
|
+
`Assigning predicate (ending in ?) variable (${
|
210
244
|
rest[0][VALUE]
|
211
245
|
}) to an (${
|
212
246
|
STATIC_TYPES.ATOM
|
213
|
-
}) that is not (or ${TRUE} ${FALSE}) (${stringifyArgs(
|
214
|
-
)
|
215
|
-
else if (
|
216
|
-
last[TYPE] === WORD &&
|
217
|
-
getSuffix(last[VALUE]) !== PREDICATE_SUFFIX &&
|
218
|
-
!PREDICATES_OUTPUT_SET.has(last[VALUE])
|
219
|
-
)
|
220
|
-
throw new TypeError(
|
221
|
-
`Assigning predicate (ending in ?) variable (${
|
222
|
-
rest[0][VALUE]
|
223
|
-
}) to another variable which is not a predicate (also ending in ?) (${stringifyArgs(
|
247
|
+
}) that is not (or ${TRUE} ${FALSE}) or to another variable which is not a predicate (also ending in ?) or to a variable that is not (or true false nil) (${stringifyArgs(
|
224
248
|
exp
|
225
|
-
)})`
|
249
|
+
)}) (check #100)`
|
226
250
|
)
|
227
251
|
} else if (last[0][0] === APPLY) {
|
228
252
|
const application = last[0]
|
229
|
-
if (
|
230
|
-
application[VALUE] !== KEYWORDS.IF &&
|
231
|
-
getSuffix(application[VALUE]) !== PREDICATE_SUFFIX &&
|
232
|
-
!PREDICATES_OUTPUT_SET.has(application[VALUE])
|
233
|
-
)
|
253
|
+
if (application[VALUE] !== KEYWORDS.IF && !IsPredicate(application))
|
234
254
|
throw new TypeError(
|
235
255
|
`Assigning predicate (ending in ?) variable (${
|
236
256
|
application[VALUE]
|
237
|
-
})
|
257
|
+
}) to another variable which is not a predicate (also ending in ?) or to a variable that is not (or true false nil) (${stringifyArgs(
|
238
258
|
exp
|
239
|
-
)})`
|
259
|
+
)}) (check #101)`
|
240
260
|
)
|
241
261
|
}
|
262
|
+
return true
|
242
263
|
}
|
264
|
+
return false
|
243
265
|
}
|
244
266
|
const checkPredicateNameDeep = (name, exp, rest, returns) => {
|
245
267
|
if (returns[VALUE] === KEYWORDS.CALL_FUNCTION) {
|
246
268
|
const fn = rest.at(-1).at(-1).at(-1)
|
247
|
-
checkPredicateName(exp, [
|
269
|
+
return checkPredicateName(exp, [
|
248
270
|
[WORD, name],
|
249
271
|
isLeaf(fn)
|
250
272
|
? fn // when apply is a word (let x? (lambda (apply [] array:empty!)))
|
251
273
|
: drillReturnType(fn, (r) => r[VALUE] === KEYWORDS.CALL_FUNCTION) // when apply is an annonymous lambda // (let fn? (lambda x (apply x (lambda x (array:empty! [])))))
|
252
274
|
])
|
253
|
-
} else {
|
254
|
-
checkPredicateName(exp, [[WORD, name], returns])
|
255
275
|
}
|
276
|
+
return checkPredicateName(exp, [[WORD, name], returns])
|
256
277
|
}
|
257
278
|
const fillUknownArgs = (n) =>
|
258
279
|
Array.from({ length: n })
|
@@ -408,31 +429,33 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
|
408
429
|
if (returns[TYPE] === ATOM) {
|
409
430
|
// ATOM ASSIGMENT
|
410
431
|
setPropToAtom(env[name][STATS], prop)
|
411
|
-
checkPredicateName(exp, [[WORD, name], returns])
|
412
432
|
} else {
|
413
433
|
switch (returns[VALUE]) {
|
414
434
|
case KEYWORDS.IF:
|
415
435
|
resolveCondition({ rem, name, env, exp, prop })
|
416
436
|
break
|
417
437
|
default:
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
if (returns[
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
438
|
+
{
|
439
|
+
checkPredicateNameDeep(name, exp, exp.slice(1), returns)
|
440
|
+
if (!env[returns[VALUE]]) return false
|
441
|
+
else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
|
442
|
+
if (returns[TYPE] === WORD)
|
443
|
+
setReturnToAbbstraction(env[name][STATS])
|
444
|
+
else {
|
445
|
+
// ALWAYS APPLY
|
446
|
+
// rest.at(-1)[0][TYPE] === APPLY
|
447
|
+
// Here is upon application to store the result in the variable
|
448
|
+
if (isUnknownType(env[name][STATS]))
|
449
|
+
stack.prepend(() => {
|
450
|
+
setTypeToReturn(env[name][STATS], env[returns[VALUE]][STATS])
|
451
|
+
// env[name][STATS][TYPE_PROP][0] =
|
452
|
+
// env[returns[VALUE]][STATS][RETURNS][0]
|
453
|
+
// this seems to be able to be deleted
|
454
|
+
// env[name][STATS][TYPE_PROP][1] =
|
455
|
+
// env[returns[VALUE]][STATS][RETURNS][1]
|
456
|
+
})
|
457
|
+
else setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
|
458
|
+
}
|
436
459
|
}
|
437
460
|
}
|
438
461
|
break
|
@@ -570,16 +593,18 @@ export const typeCheck = (ast, error = true) => {
|
|
570
593
|
retried: 0,
|
571
594
|
counter: 0,
|
572
595
|
[SIGNATURE]: name,
|
573
|
-
[TYPE_PROP]: [
|
574
|
-
isLeafNode
|
575
|
-
? right[TYPE]
|
576
|
-
: env[right[VALUE]] == undefined
|
577
|
-
? UNKNOWN
|
578
|
-
: env[right[VALUE]][STATS][RETURNS][0]
|
579
|
-
],
|
596
|
+
[TYPE_PROP]: [UNKNOWN],
|
580
597
|
[RETURNS]: [UNKNOWN]
|
581
598
|
}
|
582
599
|
}
|
600
|
+
const type = isLeafNode
|
601
|
+
? right[TYPE]
|
602
|
+
: env[right[VALUE]] == undefined
|
603
|
+
? UNKNOWN
|
604
|
+
: env[right[VALUE]][STATS][RETURNS][0]
|
605
|
+
if (type !== UNKNOWN)
|
606
|
+
setTypeToReturn(env[name][STATS], env[right[VALUE]][STATS])
|
607
|
+
|
583
608
|
const body = rightHand
|
584
609
|
const rem = hasBlock(body) ? body.at(-1) : body
|
585
610
|
const returns = isLeaf(rem) ? rem : rem[0]
|
@@ -628,10 +653,15 @@ export const typeCheck = (ast, error = true) => {
|
|
628
653
|
const ref = env[copy[SCOPE_NAME]]
|
629
654
|
if (!ref) continue
|
630
655
|
ref[STATS][ARGUMENTS][i] = copy[param[VALUE]]
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
656
|
+
|
657
|
+
// TODO overwrite return type check here
|
658
|
+
}
|
659
|
+
const returns = deepLambdaReturn(
|
660
|
+
hasBlock(exp) ? exp.at(-1) : exp,
|
661
|
+
(result) => result[VALUE] !== KEYWORDS.IF
|
662
|
+
)
|
663
|
+
const ref = env[copy[SCOPE_NAME]]
|
664
|
+
if (ref)
|
635
665
|
if (isLeaf(returns))
|
636
666
|
// TODO figure out what we do here
|
637
667
|
// this here is a variable WORD
|
@@ -667,8 +697,6 @@ export const typeCheck = (ast, error = true) => {
|
|
667
697
|
}
|
668
698
|
})
|
669
699
|
}
|
670
|
-
// TODO overwrite return type check here
|
671
|
-
}
|
672
700
|
check(rest.at(-1), copy, copy)
|
673
701
|
break
|
674
702
|
case STATIC_TYPES.ABSTRACTION:
|
@@ -768,60 +796,6 @@ export const typeCheck = (ast, error = true) => {
|
|
768
796
|
const MAIN_TYPE = getType(args[i][STATS])
|
769
797
|
if (MAIN_TYPE === ANY) continue
|
770
798
|
if (first[TYPE] === APPLY && isSpecial) {
|
771
|
-
if (
|
772
|
-
MAIN_TYPE === ATOM &&
|
773
|
-
PREDICATES_INPUT_SET.has(first[VALUE])
|
774
|
-
) {
|
775
|
-
if (
|
776
|
-
!isRestILeaf &&
|
777
|
-
rest[i][0][TYPE] === APPLY &&
|
778
|
-
rest[i][0][VALUE] === KEYWORDS.CALL_FUNCTION
|
779
|
-
) {
|
780
|
-
if (isLeaf(rest[i].at(-1))) {
|
781
|
-
const fnName = rest[i].at(-1)[VALUE]
|
782
|
-
const fn = env[fnName]
|
783
|
-
if (fn && getReturn(fn[STATS]) !== ATOM)
|
784
|
-
throw new TypeError(
|
785
|
-
`Incorrect type of argument (${i}) for (${
|
786
|
-
first[VALUE]
|
787
|
-
}). Expected (${toTypeNames(
|
788
|
-
ATOM
|
789
|
-
)}) but got an (${toTypeNames(
|
790
|
-
getReturn(fn[STATS])
|
791
|
-
)}) (${stringifyArgs(exp)}) (check #26)`
|
792
|
-
)
|
793
|
-
} else {
|
794
|
-
const body = rest[i].at(-1).at(-1)
|
795
|
-
const rem = hasBlock(body) ? body.at(-1) : body
|
796
|
-
const returns = isLeaf(rem) ? rem : rem[0]
|
797
|
-
if (returns[TYPE] === ATOM) {
|
798
|
-
if (MAIN_TYPE !== ATOM)
|
799
|
-
throw new TypeError(
|
800
|
-
`Incorrect type of argument ${i} for (${
|
801
|
-
first[VALUE]
|
802
|
-
}). Expected (${toTypeNames(
|
803
|
-
MAIN_TYPE
|
804
|
-
)}) but got an (${toTypeNames(
|
805
|
-
ATOM
|
806
|
-
)}) (${stringifyArgs(exp)}) (check #27)`
|
807
|
-
)
|
808
|
-
} else if (
|
809
|
-
env[returns[VALUE]] &&
|
810
|
-
!isUnknownReturn(env[returns[VALUE]][STATS]) &&
|
811
|
-
getReturn(env[returns[VALUE]][STATS]) !== ATOM
|
812
|
-
)
|
813
|
-
throw new TypeError(
|
814
|
-
`Incorrect type of argument ${i} for (${
|
815
|
-
first[VALUE]
|
816
|
-
}). Expected (${toTypeNames(
|
817
|
-
ATOM
|
818
|
-
)}) but got (${toTypeNames(
|
819
|
-
getReturn(env[returns[VALUE]][STATS])
|
820
|
-
)}) (${stringifyArgs(exp)}) (check #29)`
|
821
|
-
)
|
822
|
-
}
|
823
|
-
}
|
824
|
-
}
|
825
799
|
const expectedArgs = env[first[VALUE]][STATS][ARGUMENTS]
|
826
800
|
if (!isRestILeaf) {
|
827
801
|
const name = rest[i][0][VALUE]
|
@@ -1207,6 +1181,48 @@ export const typeCheck = (ast, error = true) => {
|
|
1207
1181
|
}
|
1208
1182
|
match()
|
1209
1183
|
}
|
1184
|
+
|
1185
|
+
// handly typehints for arrays
|
1186
|
+
if (
|
1187
|
+
first[TYPE] === APPLY &&
|
1188
|
+
MUTATORS_SET.has(first[VALUE]) &&
|
1189
|
+
env[first[VALUE]]
|
1190
|
+
) {
|
1191
|
+
const current = env[rest[i][VALUE]]
|
1192
|
+
if (current) {
|
1193
|
+
if (rest[i][TYPE] === WORD) {
|
1194
|
+
if (!current[STATS][TYPE_PROP][1]) {
|
1195
|
+
current[STATS][TYPE_PROP][1] = new Set()
|
1196
|
+
}
|
1197
|
+
if (MULTI_DIMENTIONAL_SETTERS.has(first[VALUE])) {
|
1198
|
+
current[STATS][TYPE_PROP][1].add(COLLECTION)
|
1199
|
+
} else {
|
1200
|
+
const right = isLeaf(rest.at(-1))
|
1201
|
+
? rest.at(-1)
|
1202
|
+
: rest.at(-1)[0]
|
1203
|
+
switch (right[TYPE]) {
|
1204
|
+
case ATOM:
|
1205
|
+
current[STATS][TYPE_PROP][1].add(ATOM)
|
1206
|
+
break
|
1207
|
+
case WORD:
|
1208
|
+
if (env[right[VALUE]]) {
|
1209
|
+
current[STATS][TYPE_PROP][1].add(
|
1210
|
+
...env[right[VALUE]][STATS][TYPE_PROP]
|
1211
|
+
)
|
1212
|
+
}
|
1213
|
+
break
|
1214
|
+
case APPLY:
|
1215
|
+
if (env[right[VALUE]])
|
1216
|
+
current[STATS][TYPE_PROP][1].add(
|
1217
|
+
...env[right[VALUE]][STATS][RETURNS]
|
1218
|
+
)
|
1219
|
+
break
|
1220
|
+
}
|
1221
|
+
}
|
1222
|
+
}
|
1223
|
+
}
|
1224
|
+
}
|
1225
|
+
// handly typehints for arrays
|
1210
1226
|
}
|
1211
1227
|
}
|
1212
1228
|
})
|
package/src/compiler.js
CHANGED
@@ -9,6 +9,7 @@ import {
|
|
9
9
|
STATIC_TYPES
|
10
10
|
} from './keywords.js'
|
11
11
|
import { leaf, isLeaf, AST } from './parser.js'
|
12
|
+
import { FALSE_WORD, TRUE_WORD } from './types.js'
|
12
13
|
const deepRename = (name, newName, tree) => {
|
13
14
|
if (!isLeaf(tree))
|
14
15
|
for (const leaf of tree) {
|
@@ -40,6 +41,10 @@ const toCamelCase = (name) => {
|
|
40
41
|
const dashToLodashes = (name) => name.replace(new RegExp(/-/g), '_')
|
41
42
|
const keywordToHelper = (name) => {
|
42
43
|
switch (name) {
|
44
|
+
case TRUE_WORD:
|
45
|
+
return '__true'
|
46
|
+
case FALSE_WORD:
|
47
|
+
return '__false'
|
43
48
|
case KEYWORDS.ADDITION:
|
44
49
|
return '__add'
|
45
50
|
case KEYWORDS.MULTIPLICATION:
|
package/src/enchance.js
CHANGED
@@ -8,7 +8,7 @@ import {
|
|
8
8
|
VALUE,
|
9
9
|
WORD
|
10
10
|
} from './keywords.js'
|
11
|
-
import { getSuffix, shake, wrapInBlock } from './utils.js'
|
11
|
+
import { getPrefix, getSuffix, shake, wrapInBlock } from './utils.js'
|
12
12
|
import std from '../lib/baked/std.js'
|
13
13
|
export const OPTIMIZATIONS = {
|
14
14
|
RECURSION: 'recursive',
|
@@ -47,7 +47,7 @@ export const enhance = (ast) => {
|
|
47
47
|
last[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
|
48
48
|
) {
|
49
49
|
const name = exp[1][VALUE]
|
50
|
-
const prefix = name
|
50
|
+
const prefix = getPrefix(name)
|
51
51
|
if (prefix === OPTIMIZATIONS.RECURSION) {
|
52
52
|
const args = last.slice(1, -1)
|
53
53
|
const newName = `${OPTIMIZED_PREFIX}${name}::*${performance
|
package/src/keywords.js
CHANGED
@@ -97,3 +97,34 @@ export const PREDICATES_OUTPUT_SET = new Set([
|
|
97
97
|
KEYWORDS.IS_ATOM,
|
98
98
|
KEYWORDS.IS_LAMBDA
|
99
99
|
])
|
100
|
+
export const MUTATORS_SET = new Set([
|
101
|
+
KEYWORDS.SET_ARRAY,
|
102
|
+
'set:with!',
|
103
|
+
'map:with!',
|
104
|
+
'matrix:set!',
|
105
|
+
'matrix:set-and-get!',
|
106
|
+
'array:set-and-get!',
|
107
|
+
'var:set-and-get!',
|
108
|
+
'map:set-and-get!',
|
109
|
+
'set:add-and-get!',
|
110
|
+
'set:add!',
|
111
|
+
'map:set!',
|
112
|
+
'array:set!',
|
113
|
+
'array:append!',
|
114
|
+
'array:push!',
|
115
|
+
'var:set!',
|
116
|
+
'array:merge!',
|
117
|
+
'list:merge!',
|
118
|
+
'list:concat!'
|
119
|
+
])
|
120
|
+
export const MULTI_DIMENTIONAL_SETTERS = new Set([
|
121
|
+
'set:with!',
|
122
|
+
'map:with!',
|
123
|
+
'matrix:set!',
|
124
|
+
'matrix:set-and-get!',
|
125
|
+
'array:set-and-get!',
|
126
|
+
'set:add!',
|
127
|
+
'map:set!',
|
128
|
+
'list:merge!',
|
129
|
+
'list:concat!'
|
130
|
+
])
|
package/src/macros.js
CHANGED
@@ -10,6 +10,7 @@ import {
|
|
10
10
|
FALSE,
|
11
11
|
KEYWORDS,
|
12
12
|
PLACEHOLDER,
|
13
|
+
STATIC_TYPES,
|
13
14
|
TRUE,
|
14
15
|
TYPE,
|
15
16
|
VALUE,
|
@@ -77,6 +78,14 @@ export const deSuggarAst = (ast, scope) => {
|
|
77
78
|
// break
|
78
79
|
case KEYWORDS.BLOCK:
|
79
80
|
{
|
81
|
+
if (rest.length === 0)
|
82
|
+
throw new RangeError(
|
83
|
+
`Invalid number of arguments for (${
|
84
|
+
KEYWORDS.BLOCK
|
85
|
+
}), expected (>= 1) but got (0) (${
|
86
|
+
KEYWORDS.BLOCK
|
87
|
+
} ${stringifyArgs(rest)})`
|
88
|
+
)
|
80
89
|
if (
|
81
90
|
prev &&
|
82
91
|
prev[TYPE] === APPLY &&
|
@@ -151,12 +160,10 @@ export const deSuggarAst = (ast, scope) => {
|
|
151
160
|
let temp = exp
|
152
161
|
for (let i = 0; i < rest.length; i += 2) {
|
153
162
|
if (i === rest.length - 2) {
|
154
|
-
temp.push(
|
155
|
-
[APPLY,
|
156
|
-
|
157
|
-
|
158
|
-
rest.at(-1)
|
159
|
-
)
|
163
|
+
temp.push([APPLY, KEYWORDS.IF], rest[i], rest.at(-1), [
|
164
|
+
[APPLY, STATIC_TYPES.ANY],
|
165
|
+
[WORD, NIL]
|
166
|
+
])
|
160
167
|
} else {
|
161
168
|
temp.push([APPLY, KEYWORDS.IF], rest[i], rest[i + 1], [])
|
162
169
|
temp = temp.at(-1)
|
@@ -239,8 +246,9 @@ export const deSuggarAst = (ast, scope) => {
|
|
239
246
|
break
|
240
247
|
case KEYWORDS.MULTIPLICATION:
|
241
248
|
if (!rest.length) {
|
242
|
-
exp[0][TYPE] = ATOM
|
243
|
-
exp[0][VALUE] =
|
249
|
+
// exp[0][TYPE] = ATOM
|
250
|
+
exp[0][VALUE] = KEYWORDS.NOT
|
251
|
+
exp[1] = [ATOM, FALSE]
|
244
252
|
} else if (rest.length > 2) {
|
245
253
|
exp.length = 0
|
246
254
|
let temp = exp
|