fez-lisp 1.6.90 → 1.6.91
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 +52 -65
package/package.json
CHANGED
package/src/check.js
CHANGED
@@ -614,7 +614,29 @@ const IfApplyBranch = ({
|
|
614
614
|
return setPropToReturn(ref[STATS], prop, branch[STATS])
|
615
615
|
}
|
616
616
|
}
|
617
|
-
|
617
|
+
const inferIf = (branch, re, env, name) => {
|
618
|
+
switch (branch[TYPE]) {
|
619
|
+
case ATOM:
|
620
|
+
return [[ATOM, NUMBER_SUBTYPE()]]
|
621
|
+
case WORD:
|
622
|
+
if (branch[VALUE] === NIL) return [[UNKNOWN]]
|
623
|
+
if (env[branch[VALUE]]) return [env[branch[VALUE]][STATS][TYPE_PROP]]
|
624
|
+
break
|
625
|
+
case APPLY:
|
626
|
+
if (branch[VALUE] !== name && env[branch[VALUE]])
|
627
|
+
if (branch[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
628
|
+
return [initArrayType({ rem: re, env })[RETURNS]]
|
629
|
+
} else if (branch[VALUE] === KEYWORDS.IF) {
|
630
|
+
const conc = isLeaf(re[2]) ? re[2] : re[2][0]
|
631
|
+
const alt = isLeaf(re[3]) ? re[3] : re[3][0]
|
632
|
+
return inferIf(conc, re[2], env, name).concat(
|
633
|
+
inferIf(alt, re[3], env, name)
|
634
|
+
)
|
635
|
+
} else return [env[branch[VALUE]][STATS][RETURNS]]
|
636
|
+
break
|
637
|
+
}
|
638
|
+
return []
|
639
|
+
}
|
618
640
|
const validateIfMatchingBranches = (
|
619
641
|
concequent,
|
620
642
|
alternative,
|
@@ -623,75 +645,40 @@ const validateIfMatchingBranches = (
|
|
623
645
|
re,
|
624
646
|
name
|
625
647
|
) => {
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
break
|
632
|
-
case WORD:
|
633
|
-
if (concequent[VALUE] === NIL) return
|
634
|
-
if (env[concequent[VALUE]]) A = env[concequent[VALUE]][STATS][TYPE_PROP]
|
635
|
-
break
|
636
|
-
case APPLY:
|
637
|
-
if (concequent[VALUE] !== name && env[concequent[VALUE]])
|
638
|
-
if (concequent[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
639
|
-
A = initArrayType({ rem: re[0], env })[RETURNS]
|
640
|
-
} else if (concequent[VALUE] === KEYWORDS.IF && re[0][2]) {
|
641
|
-
const conc = isLeaf(re[0][2]) ? re[0][2] : re[0][2][0]
|
642
|
-
validateIfMatchingBranches(
|
643
|
-
conc,
|
644
|
-
alternative,
|
645
|
-
env,
|
646
|
-
exp,
|
647
|
-
isLeaf(re[0]) ? re[0].slice(2) : re[0].slice(2),
|
648
|
-
name
|
649
|
-
)
|
650
|
-
} else A = env[concequent[VALUE]][STATS][RETURNS]
|
651
|
-
break
|
652
|
-
}
|
653
|
-
switch (alternative[TYPE]) {
|
654
|
-
case ATOM:
|
655
|
-
B = [ATOM, NUMBER_SUBTYPE()]
|
656
|
-
break
|
657
|
-
case WORD:
|
658
|
-
if (alternative[VALUE] === NIL) return
|
659
|
-
if (env[alternative[VALUE]]) B = env[alternative[VALUE]][STATS][TYPE_PROP]
|
660
|
-
break
|
661
|
-
case APPLY:
|
662
|
-
if (alternative[VALUE] !== name && env[alternative[VALUE]])
|
663
|
-
if (alternative[VALUE] === KEYWORDS.CREATE_ARRAY) {
|
664
|
-
B = initArrayType({ rem: re[1], env })[RETURNS]
|
665
|
-
} else if (alternative[VALUE] === KEYWORDS.IF && re[1][2]) {
|
666
|
-
const alt = isLeaf(re[1][2]) ? re[1][2] : re[1][2][0]
|
667
|
-
validateIfMatchingBranches(
|
668
|
-
concequent,
|
669
|
-
alt,
|
670
|
-
env,
|
671
|
-
exp,
|
672
|
-
isLeaf(re[1]) ? re[1].slice(2) : re[1].slice(2),
|
673
|
-
name
|
674
|
-
)
|
675
|
-
} else B = env[alternative[VALUE]][STATS][RETURNS]
|
676
|
-
break
|
677
|
-
}
|
678
|
-
if (
|
679
|
-
A === null ||
|
680
|
-
B === null ||
|
681
|
-
A[0] === UNKNOWN ||
|
682
|
-
B[0] === UNKNOWN ||
|
683
|
-
A[0] === ANY ||
|
684
|
-
B[0] === ANY
|
648
|
+
const A = inferIf(concequent, re[0], env, name).filter(
|
649
|
+
(x) => x[0] !== UNKNOWN && x[0] !== ANY
|
650
|
+
)
|
651
|
+
const B = inferIf(alternative, re[1], env, name).filter(
|
652
|
+
(x) => x[0] !== UNKNOWN && x[0] !== ANY
|
685
653
|
)
|
686
|
-
|
654
|
+
|
655
|
+
if (!A.length || !B.length) return
|
656
|
+
|
657
|
+
const isSame = (A, B) => {
|
658
|
+
if (
|
659
|
+
A[0] !== B[0] ||
|
660
|
+
(isSubType(A[1]) && isSubType(B[1]) && !A[1].isMatching(B[1]))
|
661
|
+
) {
|
662
|
+
throw new TypeError(
|
663
|
+
`(if) needs to have matching concequent and alternative branches but got (${formatSubType(
|
664
|
+
A
|
665
|
+
)}) and (${formatSubType(B)}) (${stringifyArgs(exp)}) (check #1005)`
|
666
|
+
)
|
667
|
+
}
|
668
|
+
}
|
669
|
+
A.forEach((x) => isSame(A[0], x))
|
670
|
+
B.forEach((x) => isSame(B[0], x))
|
671
|
+
|
672
|
+
const FA = A[0]
|
673
|
+
const FB = B[0]
|
687
674
|
if (
|
688
|
-
|
689
|
-
(isSubType(
|
675
|
+
FA[0] !== FB[0] ||
|
676
|
+
(isSubType(FA[1]) && isSubType(FB[1]) && !FA[1].isMatching(FB[1]))
|
690
677
|
) {
|
691
678
|
throw new TypeError(
|
692
679
|
`(if) needs to have matching concequent and alternative branches but got (${formatSubType(
|
693
|
-
|
694
|
-
)}) and (${formatSubType(
|
680
|
+
FA
|
681
|
+
)}) and (${formatSubType(FB)}) (${stringifyArgs(exp)}) (check #1005)`
|
695
682
|
)
|
696
683
|
}
|
697
684
|
}
|