fez-lisp 1.5.125 → 1.5.128
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 +236 -63
- package/src/compiler.js +1 -0
- package/src/interpreter.js +1 -0
- package/src/keywords.js +13 -14
- package/src/types.js +44 -16
- package/src/utils.js +15 -2
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -2,7 +2,10 @@ import {
|
|
2
2
|
APPLY,
|
3
3
|
ATOM,
|
4
4
|
FALSE,
|
5
|
+
GETTERS_SET,
|
5
6
|
KEYWORDS,
|
7
|
+
MUTATION_SUFFIX,
|
8
|
+
MUTATORS_SET,
|
6
9
|
PLACEHOLDER,
|
7
10
|
PREDICATE_SUFFIX,
|
8
11
|
PREDICATES_OUTPUT_SET,
|
@@ -40,13 +43,17 @@ import {
|
|
40
43
|
BOOLEAN_SUBTYPE,
|
41
44
|
formatSubType,
|
42
45
|
PREDICATE,
|
43
|
-
IS_ARGUMENT
|
46
|
+
IS_ARGUMENT,
|
47
|
+
NUMBER,
|
48
|
+
SETTER
|
44
49
|
} from './types.js'
|
45
50
|
import {
|
46
51
|
Brr,
|
47
52
|
getSuffix,
|
48
53
|
hasApplyLambdaBlock,
|
49
54
|
hasBlock,
|
55
|
+
log,
|
56
|
+
logExp,
|
50
57
|
stringifyArgs
|
51
58
|
} from './utils.js'
|
52
59
|
Set.prototype.union = function (B) {
|
@@ -107,10 +114,16 @@ export const isUnknownNotAnyType = (stats) =>
|
|
107
114
|
export const isUnknownNotAnyReturn = (stats) =>
|
108
115
|
stats && !isAnyReturn(stats) && isUnknownReturn(stats)
|
109
116
|
export const castType = (stats, type) => {
|
110
|
-
return (
|
117
|
+
return (
|
118
|
+
(stats[TYPE_PROP][0] = type[RETURNS][0]),
|
119
|
+
(stats[TYPE_PROP][1] = type[RETURNS][1])
|
120
|
+
)
|
111
121
|
}
|
112
122
|
export const castReturn = (stats, type) => {
|
113
|
-
return (
|
123
|
+
return (
|
124
|
+
(stats[RETURNS][0] = type[RETURNS][0]),
|
125
|
+
(stats[RETURNS][1] = type[RETURNS][1])
|
126
|
+
)
|
114
127
|
}
|
115
128
|
export const isTypeAbstraction = (stats) => stats[TYPE_PROP] === APPLY
|
116
129
|
export const setPropToAtom = (stats, prop) => {
|
@@ -123,7 +136,7 @@ export const setPropToPredicate = (stats, prop) => {
|
|
123
136
|
return (stats[prop][1] = BOOLEAN_SUBTYPE())
|
124
137
|
}
|
125
138
|
export const setReturnToPredicate = (stats) => {
|
126
|
-
return (stats[RETURNS][
|
139
|
+
return (stats[RETURNS][0] = BOOLEAN_SUBTYPE())
|
127
140
|
}
|
128
141
|
export const setTypeToPredicate = (stats) => {
|
129
142
|
return (stats[RETURNS][1] = BOOLEAN_SUBTYPE())
|
@@ -152,6 +165,7 @@ export const setPropToReturn = (stats, prop, value) => {
|
|
152
165
|
}
|
153
166
|
export const setPropToReturnRef = (stats, prop, value) => {
|
154
167
|
return (
|
168
|
+
stats[prop] &&
|
155
169
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
156
170
|
value[RETURNS][0] !== UNKNOWN &&
|
157
171
|
(stats[prop] = value[RETURNS])
|
@@ -159,6 +173,7 @@ export const setPropToReturnRef = (stats, prop, value) => {
|
|
159
173
|
}
|
160
174
|
export const setPropToType = (stats, prop, value) => {
|
161
175
|
return (
|
176
|
+
stats[prop] &&
|
162
177
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
163
178
|
((stats[prop][0] = value[TYPE_PROP][0]),
|
164
179
|
value[TYPE_PROP][1] && (stats[prop][1] = value[TYPE_PROP][1]))
|
@@ -166,6 +181,7 @@ export const setPropToType = (stats, prop, value) => {
|
|
166
181
|
}
|
167
182
|
export const setPropToTypeRef = (stats, prop, value) => {
|
168
183
|
return (
|
184
|
+
stats[prop] &&
|
169
185
|
(stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
|
170
186
|
(stats[prop] = value[TYPE_PROP])
|
171
187
|
)
|
@@ -177,12 +193,18 @@ export const setReturnToAtom = (stats) => {
|
|
177
193
|
}
|
178
194
|
export const setTypeToAtom = (stats) =>
|
179
195
|
(isUnknownType(stats) || isAnyType(stats)) && (stats[TYPE_PROP][0] = ATOM)
|
196
|
+
export const setTypeToCollection = (stats) =>
|
197
|
+
(isUnknownType(stats) || isAnyType(stats)) &&
|
198
|
+
(stats[TYPE_PROP][0] = COLLECTION)
|
180
199
|
export const setReturnToAbbstraction = (stats) =>
|
181
200
|
isUnknownReturn(stats) && (stats[RETURNS][0] = APPLY)
|
182
201
|
export const setTypeRef = (stats, value) =>
|
183
202
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
184
203
|
(stats[TYPE_PROP] = value[TYPE_PROP])
|
185
204
|
export const setReturnRef = (stats, value) => {
|
205
|
+
if (SPECIAL_FORMS_SET.has(value[SIGNATURE])) {
|
206
|
+
return setReturn(stats, value)
|
207
|
+
}
|
186
208
|
return isUnknownReturn(stats) && (stats[RETURNS] = value[RETURNS])
|
187
209
|
}
|
188
210
|
export const setReturnToTypeRef = (stats, value) => {
|
@@ -217,6 +239,15 @@ export const setType = (stats, value) =>
|
|
217
239
|
!isUnknownType(value) &&
|
218
240
|
((stats[TYPE_PROP][0] = value[TYPE_PROP][0]),
|
219
241
|
value[TYPE_PROP][1] && (stats[TYPE_PROP][1] = value[TYPE_PROP][1]))
|
242
|
+
export const setSubType = (stats, value) =>
|
243
|
+
// makes no senseto protect this for now
|
244
|
+
hasSubType(value) && (stats[TYPE_PROP][1] = value[TYPE_PROP][1])
|
245
|
+
export const setPropToSubType = (stats, prop, value) =>
|
246
|
+
// makes no senseto protect this for now
|
247
|
+
hasSubType(value) && (stats[prop][1] = value[TYPE_PROP][1])
|
248
|
+
export const setPropToSubReturn = (stats, prop, value) =>
|
249
|
+
// makes no senseto protect this for now
|
250
|
+
hasSubReturn(value) && (stats[prop][1] = value[RETURNS][1])
|
220
251
|
export const setTypeToReturn = (stats, value) =>
|
221
252
|
(isUnknownType(stats) || isAnyType(stats)) &&
|
222
253
|
!isUnknownReturn(value) &&
|
@@ -230,6 +261,10 @@ export const setReturnToType = (stats, value) =>
|
|
230
261
|
export const isAnyReturn = (stats) => stats && stats[RETURNS][0] === ANY
|
231
262
|
export const isAnyType = (stats) => stats && stats[TYPE_PROP][0] === ANY
|
232
263
|
export const isUnknownType = (stats) => stats && stats[TYPE_PROP][0] === UNKNOWN
|
264
|
+
export const isUnknownProp = (stats, prop) => {
|
265
|
+
return stats && stats[prop][0] === UNKNOWN
|
266
|
+
}
|
267
|
+
|
233
268
|
export const isUnknownReturn = (stats) => stats[RETURNS][0] === UNKNOWN
|
234
269
|
export const getType = (stats) => stats && stats[TYPE_PROP][0]
|
235
270
|
export const getTypes = (stats) => stats && stats[TYPE_PROP]
|
@@ -239,12 +274,25 @@ export const getSubType = (stats) => stats && stats[TYPE_PROP][1]
|
|
239
274
|
export const hasSubType = (stats) => stats && stats[TYPE_PROP][1] instanceof Set
|
240
275
|
export const getSubReturn = (stats) => stats && stats[RETURNS][1]
|
241
276
|
export const hasSubReturn = (stats) => stats && stats[RETURNS][1] instanceof Set
|
277
|
+
export const isUknownSubReturn = (stats) =>
|
278
|
+
!hasSubReturn(stats) ||
|
279
|
+
(stats[RETURNS][1].size === 1 && stats[RETURNS][1].has(UNKNOWN))
|
280
|
+
export const isUknownSubType = (stats) =>
|
281
|
+
hasSubType(stats) &&
|
282
|
+
stats[TYPE_PROP][1].size === 1 &&
|
283
|
+
stats[TYPE_PROP][1].has(UNKNOWN)
|
242
284
|
export const isAtomType = (stats) =>
|
243
285
|
isAnyType(stats) || stats[TYPE_PROP][0] === ATOM
|
244
286
|
export const isAtomReturn = (stats) =>
|
245
287
|
isAnyType(stats) || stats[RETURNS][0] === ATOM
|
246
|
-
export const compareTypes = (a, b) =>
|
247
|
-
isAnyType(a) || isAnyType(b)
|
288
|
+
export const compareTypes = (a, b) => {
|
289
|
+
const isAnyAny = isAnyType(a) || isAnyType(b)
|
290
|
+
if (isAnyAny) return true
|
291
|
+
const isSameType = a[TYPE_PROP][0] === b[TYPE_PROP][0]
|
292
|
+
if (!isSameType) return false
|
293
|
+
return true
|
294
|
+
}
|
295
|
+
|
248
296
|
export const compareReturns = (a, b) =>
|
249
297
|
isAnyReturn(a) || isAnyReturn(b) || a[RETURNS][0] === b[RETURNS][0]
|
250
298
|
export const compareTypeWithReturn = (a, b) =>
|
@@ -266,20 +314,28 @@ const notABooleanType = (a, b) => {
|
|
266
314
|
getSubType(a).has(PREDICATE) &&
|
267
315
|
!isUnknownType(b) &&
|
268
316
|
!isAnyType(b) &&
|
269
|
-
(!
|
270
|
-
!hasSubType(b) ||
|
271
|
-
getSubType(a).difference(getSubType(b)).size !== 0)
|
317
|
+
(!hasSubType(b) || getSubType(a).difference(getSubType(b)).size !== 0)
|
272
318
|
)
|
273
319
|
}
|
320
|
+
// const notABooleanReturn = (a, b) => {
|
321
|
+
// return (
|
322
|
+
// hasSubType(a) &&
|
323
|
+
// getSubType(a).has(PREDICATE) &&
|
324
|
+
// !isUnknownReturn(b) &&
|
325
|
+
// !isAnyReturn(b) &&
|
326
|
+
// (
|
327
|
+
// !isAtomReturn(b) ||
|
328
|
+
// !hasSubReturn(b) ||
|
329
|
+
// getSubType(a).difference(getSubReturn(b)).size !== 0)
|
330
|
+
// )
|
331
|
+
// }
|
274
332
|
const notABooleanReturn = (a, b) => {
|
275
333
|
return (
|
276
334
|
hasSubType(a) &&
|
277
335
|
getSubType(a).has(PREDICATE) &&
|
278
336
|
!isUnknownReturn(b) &&
|
279
337
|
!isAnyReturn(b) &&
|
280
|
-
(!
|
281
|
-
!hasSubReturn(b) ||
|
282
|
-
getSubType(a).difference(getSubReturn(b)).size !== 0)
|
338
|
+
(!hasSubReturn(b) || getSubType(a).difference(getSubReturn(b)).size !== 0)
|
283
339
|
)
|
284
340
|
}
|
285
341
|
const isAtomABoolean = (atom) => atom === TRUE || atom === FALSE
|
@@ -482,17 +538,154 @@ const resolveCondition = ({ rem, name, env, exp, prop }) => {
|
|
482
538
|
break
|
483
539
|
}
|
484
540
|
}
|
541
|
+
const resolveSetter = (first, rest, env) => {
|
542
|
+
if (
|
543
|
+
getSuffix(first[VALUE]) === MUTATION_SUFFIX &&
|
544
|
+
MUTATORS_SET.has(first[VALUE]) &&
|
545
|
+
rest[0] &&
|
546
|
+
isLeaf(rest[0]) &&
|
547
|
+
rest[0][TYPE] !== ATOM &&
|
548
|
+
env[rest[0][VALUE]]
|
549
|
+
) {
|
550
|
+
const name = rest[0][VALUE]
|
551
|
+
const current = env[name]
|
552
|
+
const right = isLeaf(rest.at(-1)) ? rest.at(-1) : rest.at(-1)[0]
|
553
|
+
switch (right[TYPE]) {
|
554
|
+
case ATOM:
|
555
|
+
current[STATS][TYPE_PROP][1] = new Set([NUMBER])
|
556
|
+
break
|
557
|
+
case WORD:
|
558
|
+
if (env[right[VALUE]]) {
|
559
|
+
if (hasSubType(env[right[VALUE]][STATS]))
|
560
|
+
current[STATS][TYPE_PROP][1] = new Set(
|
561
|
+
getSubType(env[right[VALUE]][STATS])
|
562
|
+
)
|
563
|
+
else
|
564
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
565
|
+
getType(env[right[VALUE]][STATS])
|
566
|
+
])
|
567
|
+
}
|
568
|
+
break
|
569
|
+
case APPLY:
|
570
|
+
if (env[right[VALUE]]) {
|
571
|
+
if (right[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
572
|
+
current[STATS][TYPE_PROP][1] = (initArrayType({
|
573
|
+
rem: rest.at(-1),
|
574
|
+
env
|
575
|
+
}) ?? { [RETURNS]: [COLLECTION, new Set([])] })[RETURNS][1]
|
576
|
+
break
|
577
|
+
}
|
578
|
+
if (hasSubReturn(env[right[VALUE]][STATS]))
|
579
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
580
|
+
...getSubReturn(env[right[VALUE]][STATS])
|
581
|
+
])
|
582
|
+
else if (!isUnknownReturn(env[right[VALUE]][STATS]))
|
583
|
+
current[STATS][TYPE_PROP][1] = new Set([
|
584
|
+
getReturn(env[right[VALUE]][STATS])
|
585
|
+
])
|
586
|
+
}
|
587
|
+
break
|
588
|
+
}
|
589
|
+
setTypeToCollection(current[STATS])
|
590
|
+
}
|
591
|
+
}
|
592
|
+
const resolveGetter = ({ rem, prop, name, env }) => {
|
593
|
+
const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
|
594
|
+
if (!env[array[VALUE]] || !env[name]) return true
|
595
|
+
switch (array[TYPE]) {
|
596
|
+
case APPLY:
|
597
|
+
if (hasSubType(env[array[VALUE]][STATS])) {
|
598
|
+
const rightSub = getSubReturn(env[array[VALUE]][STATS])
|
599
|
+
const isAtom = rightSub.has(NUMBER) || rightSub.has(PREDICATE)
|
600
|
+
const isCollection = rightSub.has(COLLECTION)
|
601
|
+
if (isAtom && !isCollection) {
|
602
|
+
setPropToAtom(env[name][STATS], prop)
|
603
|
+
setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
|
604
|
+
} else if (!isAtom && isCollection) {
|
605
|
+
setPropToReturn(env[name][STATS], env[array[VALUE]][STATS])
|
606
|
+
}
|
607
|
+
} else return false
|
608
|
+
break
|
609
|
+
case WORD:
|
610
|
+
{
|
611
|
+
if (hasSubType(env[array[VALUE]][STATS])) {
|
612
|
+
const rightSub = getSubType(env[array[VALUE]][STATS])
|
613
|
+
const isAtom =
|
614
|
+
rightSub.has(ATOM) ||
|
615
|
+
rightSub.has(NUMBER) ||
|
616
|
+
rightSub.has(PREDICATE)
|
617
|
+
const isCollection = rightSub.has(COLLECTION)
|
618
|
+
if (isAtom && !isCollection) {
|
619
|
+
setPropToAtom(env[name][STATS], prop)
|
620
|
+
setPropToSubType(env[name][STATS], prop, env[array[VALUE]][STATS])
|
621
|
+
} else if (!isAtom && isCollection) {
|
622
|
+
setPropToType(env[name][STATS], env[array[VALUE]][STATS])
|
623
|
+
}
|
624
|
+
} else return false
|
625
|
+
}
|
626
|
+
break
|
627
|
+
}
|
628
|
+
return true
|
629
|
+
}
|
630
|
+
const initArrayType = ({ rem, env }) => {
|
631
|
+
const ret = rem
|
632
|
+
.slice(1)
|
633
|
+
.map((x) =>
|
634
|
+
isLeaf(x)
|
635
|
+
? x[TYPE] === WORD
|
636
|
+
? env[x[VALUE]]
|
637
|
+
? getTypes(env[x[VALUE]][STATS])
|
638
|
+
: [UNKNOWN]
|
639
|
+
: [x[TYPE]]
|
640
|
+
: env[x[0][VALUE]]
|
641
|
+
? getReturns(env[x[0][VALUE]][STATS])
|
642
|
+
: [UNKNOWN]
|
643
|
+
)
|
644
|
+
const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
|
645
|
+
if (
|
646
|
+
known &&
|
647
|
+
ret.length &&
|
648
|
+
!ret.some((x) => known[0] !== x[0] || known.length !== x.length)
|
649
|
+
) {
|
650
|
+
const [main, sub] = ret[0]
|
651
|
+
return {
|
652
|
+
[TYPE_PROP]: [APPLY],
|
653
|
+
[RETURNS]: [COLLECTION, new Set(sub ? [...sub] : [main])]
|
654
|
+
}
|
655
|
+
}
|
656
|
+
}
|
485
657
|
const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
486
658
|
if (returns[TYPE] === ATOM) {
|
487
659
|
// ATOM ASSIGMENT
|
488
660
|
setPropToAtom(env[name][STATS], prop)
|
489
661
|
} else {
|
490
662
|
switch (returns[VALUE]) {
|
663
|
+
case KEYWORDS.CREATE_ARRAY:
|
664
|
+
{
|
665
|
+
const r = initArrayType({ rem, env })
|
666
|
+
if (r) setPropToSubReturn(env[name][STATS], prop, r)
|
667
|
+
}
|
668
|
+
break
|
491
669
|
case KEYWORDS.IF:
|
492
670
|
resolveCondition({ rem, name, env, exp, prop })
|
493
671
|
break
|
494
672
|
default:
|
495
673
|
{
|
674
|
+
if (
|
675
|
+
GETTERS_SET.has(returns[VALUE]) &&
|
676
|
+
!resolveGetter({ rem, prop, name, env })
|
677
|
+
)
|
678
|
+
return retry(env[name][STATS], stack, () => {
|
679
|
+
resolveRetunType({
|
680
|
+
returns,
|
681
|
+
rem,
|
682
|
+
stack,
|
683
|
+
prop,
|
684
|
+
exp,
|
685
|
+
name,
|
686
|
+
env
|
687
|
+
})
|
688
|
+
})
|
496
689
|
checkPredicateNameDeep(name, exp, exp.slice(1), returns)
|
497
690
|
if (!env[returns[VALUE]]) return false
|
498
691
|
else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
|
@@ -508,11 +701,6 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
|
|
508
701
|
env[name][STATS],
|
509
702
|
env[returns[VALUE]][STATS]
|
510
703
|
)
|
511
|
-
// env[name][STATS][TYPE_PROP][0] =
|
512
|
-
// env[returns[VALUE]][STATS][RETURNS][0]
|
513
|
-
// this seems to be able to be deleted
|
514
|
-
// env[name][STATS][TYPE_PROP][1] =
|
515
|
-
// env[returns[VALUE]][STATS][RETURNS][1]
|
516
704
|
})
|
517
705
|
else setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
|
518
706
|
}
|
@@ -567,6 +755,8 @@ export const typeCheck = (ast) => {
|
|
567
755
|
break
|
568
756
|
case APPLY: {
|
569
757
|
switch (first[VALUE]) {
|
758
|
+
// Var
|
759
|
+
// ---------------
|
570
760
|
case KEYWORDS.DEFINE_VARIABLE:
|
571
761
|
if (rest.length !== 2)
|
572
762
|
throw new TypeError(
|
@@ -765,6 +955,7 @@ export const typeCheck = (ast) => {
|
|
765
955
|
case STATIC_TYPES.ATOM:
|
766
956
|
case STATIC_TYPES.PREDICATE:
|
767
957
|
case STATIC_TYPES.ANY:
|
958
|
+
case STATIC_TYPES.NUMBER:
|
768
959
|
{
|
769
960
|
const ret = isLeaf(rest[0]) ? rest[0] : rest[0][0]
|
770
961
|
const ref = env[ret[VALUE]]
|
@@ -778,6 +969,12 @@ export const typeCheck = (ast) => {
|
|
778
969
|
}
|
779
970
|
break
|
780
971
|
default:
|
972
|
+
// Setters are just like DEFINE_VARIABLE as they are essentially the Var case for Collections
|
973
|
+
// So they MUST happen before Judgement
|
974
|
+
resolveSetter(first, rest, env)
|
975
|
+
// end of Var ---------------
|
976
|
+
|
977
|
+
// Judgement
|
781
978
|
stack.append(() => {
|
782
979
|
if (!isSpecial && env[first[VALUE]] === undefined)
|
783
980
|
throw new TypeError(
|
@@ -915,7 +1112,6 @@ export const typeCheck = (ast) => {
|
|
915
1112
|
setReturnRef(env[name][STATS], args[i][STATS])
|
916
1113
|
break
|
917
1114
|
}
|
918
|
-
|
919
1115
|
// TODO also handle casting
|
920
1116
|
}
|
921
1117
|
} else {
|
@@ -950,7 +1146,21 @@ export const typeCheck = (ast) => {
|
|
950
1146
|
getTypes(env[name][STATS])
|
951
1147
|
)}) (${stringifyArgs(exp)}) (check #202)`
|
952
1148
|
)
|
953
|
-
else
|
1149
|
+
else {
|
1150
|
+
// TODO the special form will set type first but it
|
1151
|
+
// might be known already
|
1152
|
+
// example
|
1153
|
+
// (let xs [])
|
1154
|
+
// (let x (array:set-and-get! xs 0 100))
|
1155
|
+
// (length x)
|
1156
|
+
//
|
1157
|
+
// if (isUnknownType(env[name][STATS])) {
|
1158
|
+
// retry(env[name][STATS], stack, () =>
|
1159
|
+
// check(exp, env, scope)
|
1160
|
+
// )
|
1161
|
+
// } else
|
1162
|
+
setType(env[name][STATS], args[i][STATS])
|
1163
|
+
}
|
954
1164
|
}
|
955
1165
|
break
|
956
1166
|
case ATOM: {
|
@@ -1177,7 +1387,11 @@ export const typeCheck = (ast) => {
|
|
1177
1387
|
}
|
1178
1388
|
} else if (env[rest[i][0][VALUE]]) {
|
1179
1389
|
const match = () => {
|
1180
|
-
const actual =
|
1390
|
+
const actual =
|
1391
|
+
rest[i][0][VALUE] === KEYWORDS.CREATE_ARRAY
|
1392
|
+
? initArrayType({ rem: rest[i], env }) ??
|
1393
|
+
env[rest[i][0][VALUE]][STATS]
|
1394
|
+
: env[rest[i][0][VALUE]][STATS]
|
1181
1395
|
const expected = args[i][STATS]
|
1182
1396
|
retryArgs(args[i][STATS], stack, () => match())
|
1183
1397
|
if (!isUnknownType(expected) && !isUnknownReturn(actual))
|
@@ -1193,13 +1407,13 @@ export const typeCheck = (ast) => {
|
|
1193
1407
|
)
|
1194
1408
|
else if (notABooleanReturn(expected, actual)) {
|
1195
1409
|
throw new TypeError(
|
1196
|
-
`Incorrect type of argument (${i}) for
|
1410
|
+
`Incorrect type of argument (${i}) for (${
|
1197
1411
|
first[VALUE]
|
1198
1412
|
}). Expected (${formatSubType(
|
1199
1413
|
getTypes(expected)
|
1200
1414
|
)}) but got (${formatSubType(
|
1201
1415
|
getReturns(actual)
|
1202
|
-
)}) (${stringifyArgs(exp)}) (check #
|
1416
|
+
)}) (${stringifyArgs(exp)}) (check #206)`
|
1203
1417
|
)
|
1204
1418
|
} else {
|
1205
1419
|
switch (getType(expected)) {
|
@@ -1331,47 +1545,6 @@ export const typeCheck = (ast) => {
|
|
1331
1545
|
}
|
1332
1546
|
match()
|
1333
1547
|
}
|
1334
|
-
// handly typehints for arrays
|
1335
|
-
// if (
|
1336
|
-
// first[TYPE] === APPLY &&
|
1337
|
-
// MUTATORS_SET.has(first[VALUE]) &&
|
1338
|
-
// env[first[VALUE]]
|
1339
|
-
// ) {
|
1340
|
-
// const current = env[rest[i][VALUE]]
|
1341
|
-
// if (current) {
|
1342
|
-
// if (rest[i][TYPE] === WORD) {
|
1343
|
-
// if (!current[STATS][TYPE_PROP][1]) {
|
1344
|
-
// current[STATS][TYPE_PROP][1] = new Set()
|
1345
|
-
// }
|
1346
|
-
// if (MULTI_DIMENTIONAL_SETTERS.has(first[VALUE])) {
|
1347
|
-
// current[STATS][TYPE_PROP][1].add(COLLECTION)
|
1348
|
-
// } else {
|
1349
|
-
// const right = isLeaf(rest.at(-1))
|
1350
|
-
// ? rest.at(-1)
|
1351
|
-
// : rest.at(-1)[0]
|
1352
|
-
// switch (right[TYPE]) {
|
1353
|
-
// case ATOM:
|
1354
|
-
// current[STATS][TYPE_PROP][1].add(ATOM)
|
1355
|
-
// break
|
1356
|
-
// case WORD:
|
1357
|
-
// if (env[right[VALUE]]) {
|
1358
|
-
// current[STATS][TYPE_PROP][1].add(
|
1359
|
-
// ...env[right[VALUE]][STATS][TYPE_PROP]
|
1360
|
-
// )
|
1361
|
-
// }
|
1362
|
-
// break
|
1363
|
-
// case APPLY:
|
1364
|
-
// if (env[right[VALUE]])
|
1365
|
-
// current[STATS][TYPE_PROP][1].add(
|
1366
|
-
// ...env[right[VALUE]][STATS][RETURNS]
|
1367
|
-
// )
|
1368
|
-
// break
|
1369
|
-
// }
|
1370
|
-
// }
|
1371
|
-
// }
|
1372
|
-
// }
|
1373
|
-
// }
|
1374
|
-
// handly typehints for arrays
|
1375
1548
|
}
|
1376
1549
|
}
|
1377
1550
|
})
|
package/src/compiler.js
CHANGED
package/src/interpreter.js
CHANGED
@@ -837,6 +837,7 @@ export const keywords = {
|
|
837
837
|
[STATIC_TYPES.ATOM]: (args, env) => evaluate(args[0], env),
|
838
838
|
[STATIC_TYPES.COLLECTION]: (args, env) => evaluate(args[0], env),
|
839
839
|
[STATIC_TYPES.PREDICATE]: (args, env) => evaluate(args[0], env),
|
840
|
+
[STATIC_TYPES.NUMBER]: (args, env) => evaluate(args[0], env),
|
840
841
|
[STATIC_TYPES.UNKNOWN]: (args, env) => evaluate(args[0], env),
|
841
842
|
[STATIC_TYPES.ANY]: (args, env) => evaluate(args[0], env)
|
842
843
|
}
|
package/src/keywords.js
CHANGED
@@ -9,6 +9,7 @@ export const PLACEHOLDER = '.'
|
|
9
9
|
export const MUTATION_SUFFIX = '!'
|
10
10
|
export const PREDICATE_SUFFIX = '?'
|
11
11
|
export const STATIC_TYPES = {
|
12
|
+
NUMBER: 'Number',
|
12
13
|
ABSTRACTION: 'Abstraction',
|
13
14
|
UNKNOWN: 'Unknown',
|
14
15
|
ATOM: 'Atom',
|
@@ -99,8 +100,6 @@ export const PREDICATES_OUTPUT_SET = new Set([
|
|
99
100
|
])
|
100
101
|
export const MUTATORS_SET = new Set([
|
101
102
|
KEYWORDS.SET_ARRAY,
|
102
|
-
'set:with!',
|
103
|
-
'map:with!',
|
104
103
|
'matrix:set!',
|
105
104
|
'matrix:set-and-get!',
|
106
105
|
'array:set-and-get!',
|
@@ -112,19 +111,19 @@ export const MUTATORS_SET = new Set([
|
|
112
111
|
'array:set!',
|
113
112
|
'array:append!',
|
114
113
|
'array:push!',
|
115
|
-
'var:set!'
|
116
|
-
'array:merge!',
|
117
|
-
'list:merge!',
|
118
|
-
'list:concat!'
|
114
|
+
'var:set!'
|
119
115
|
])
|
120
|
-
export const
|
121
|
-
|
122
|
-
'
|
123
|
-
'matrix:set!',
|
116
|
+
export const GETTERS_SET = new Set([
|
117
|
+
KEYWORDS.GET_ARRAY,
|
118
|
+
'matrix:get',
|
124
119
|
'matrix:set-and-get!',
|
125
120
|
'array:set-and-get!',
|
126
|
-
'set
|
127
|
-
'map:set!',
|
128
|
-
'
|
129
|
-
'
|
121
|
+
'var:set-and-get!',
|
122
|
+
'map:set-and-get!',
|
123
|
+
'set:add-and-get!',
|
124
|
+
'set:get',
|
125
|
+
'map:get',
|
126
|
+
'array:get',
|
127
|
+
'array:pop!',
|
128
|
+
'var:get'
|
130
129
|
])
|
package/src/types.js
CHANGED
@@ -30,6 +30,8 @@ export const NIL = 'nil'
|
|
30
30
|
export const TRUE_WORD = 'true'
|
31
31
|
export const FALSE_WORD = 'false'
|
32
32
|
export const BOOLEAN_SUBTYPE = () => new Set([PREDICATE])
|
33
|
+
export const COLLECTION_SUBTYPE = () => new Set([COLLECTION])
|
34
|
+
export const NUMBER_SUBTYPE = () => new Set([NUMBER])
|
33
35
|
|
34
36
|
export const toTypeNames = (type) => {
|
35
37
|
switch (type) {
|
@@ -37,15 +39,16 @@ export const toTypeNames = (type) => {
|
|
37
39
|
return 'Abstraction'
|
38
40
|
case PREDICATE:
|
39
41
|
return 'Boolean'
|
42
|
+
case ATOM:
|
40
43
|
case NUMBER:
|
41
44
|
return 'Number'
|
42
|
-
case ATOM:
|
43
|
-
|
45
|
+
// case ATOM:
|
46
|
+
// return 'Atom'
|
44
47
|
case UNKNOWN:
|
45
48
|
return 'Unknown'
|
46
49
|
case COLLECTION:
|
47
|
-
return 'Array'
|
48
|
-
|
50
|
+
// return 'Array'
|
51
|
+
return '[Unknown]'
|
49
52
|
case ANY:
|
50
53
|
return 'Any'
|
51
54
|
default:
|
@@ -60,6 +63,8 @@ export const toTypeNamesAnyToUknown = (type) => {
|
|
60
63
|
return toTypeNames(type)
|
61
64
|
}
|
62
65
|
}
|
66
|
+
export const GETTER = 1
|
67
|
+
export const SETTER = 2
|
63
68
|
export const SPECIAL_FORM_TYPES = {
|
64
69
|
[SCOPE_NAME]: ';',
|
65
70
|
// [ORDER]: 0,
|
@@ -128,6 +133,27 @@ export const SPECIAL_FORM_TYPES = {
|
|
128
133
|
[RETURNS]: [ATOM, BOOLEAN_SUBTYPE()]
|
129
134
|
}
|
130
135
|
},
|
136
|
+
[STATIC_TYPES.NUMBER]: {
|
137
|
+
[STATS]: {
|
138
|
+
[TYPE_PROP]: [APPLY],
|
139
|
+
[SIGNATURE]: STATIC_TYPES.NUMBER,
|
140
|
+
retried: Infinity,
|
141
|
+
[ARG_COUNT]: 1,
|
142
|
+
[ARGUMENTS]: [
|
143
|
+
{
|
144
|
+
[STATS]: {
|
145
|
+
retried: Infinity,
|
146
|
+
[SIGNATURE]: PLACEHOLDER,
|
147
|
+
[TYPE_PROP]: [UNKNOWN],
|
148
|
+
[RETURNS]: [UNKNOWN],
|
149
|
+
[ARGUMENTS]: [],
|
150
|
+
[ARG_COUNT]: 0
|
151
|
+
}
|
152
|
+
}
|
153
|
+
],
|
154
|
+
[RETURNS]: [ATOM, NUMBER_SUBTYPE()]
|
155
|
+
}
|
156
|
+
},
|
131
157
|
[STATIC_TYPES.COLLECTION]: {
|
132
158
|
[STATS]: {
|
133
159
|
[TYPE_PROP]: [APPLY],
|
@@ -718,6 +744,7 @@ export const SPECIAL_FORM_TYPES = {
|
|
718
744
|
[STATS]: {
|
719
745
|
[TYPE_PROP]: [APPLY],
|
720
746
|
[SIGNATURE]: KEYWORDS.GET_ARRAY,
|
747
|
+
tag: GETTER,
|
721
748
|
retried: Infinity,
|
722
749
|
[ARG_COUNT]: 2,
|
723
750
|
[ARGUMENTS]: [
|
@@ -750,6 +777,7 @@ export const SPECIAL_FORM_TYPES = {
|
|
750
777
|
[KEYWORDS.SET_ARRAY]: {
|
751
778
|
[STATS]: {
|
752
779
|
[TYPE_PROP]: [APPLY],
|
780
|
+
tag: SETTER,
|
753
781
|
retried: Infinity,
|
754
782
|
[ARG_COUNT]: 3,
|
755
783
|
[ARGUMENTS]: [
|
@@ -1185,18 +1213,18 @@ export const SPECIAL_FORM_TYPES = {
|
|
1185
1213
|
|
1186
1214
|
export const formatSubType = (T) => {
|
1187
1215
|
switch (T[0]) {
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1216
|
+
case COLLECTION:
|
1217
|
+
return `[${
|
1218
|
+
T[1] instanceof Set
|
1219
|
+
? [...T[1]]
|
1220
|
+
.map((x) =>
|
1221
|
+
x === COLLECTION
|
1222
|
+
? formatSubType([x])
|
1223
|
+
: toTypeNamesAnyToUknown(x)
|
1224
|
+
)
|
1225
|
+
.join(' ')
|
1226
|
+
: toTypeNamesAnyToUknown(ANY)
|
1227
|
+
}]`
|
1200
1228
|
case ATOM:
|
1201
1229
|
return `${
|
1202
1230
|
T[1] instanceof Set
|