fez-lisp 1.5.63 → 1.5.65

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "fez-lisp",
3
3
  "description": "Lisp interpreted & compiled to JavaScript",
4
4
  "author": "AT290690",
5
- "version": "1.5.63",
5
+ "version": "1.5.65",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -1270,7 +1270,8 @@ export const typeCheck = (ast) => {
1270
1270
  T[TYPE_PROP][0]
1271
1271
  )}) (check #32)`
1272
1272
  )
1273
- } else T[TYPE_PROP] = [COLLECTION]
1273
+ }
1274
+ //else T[TYPE_PROP] = [COLLECTION]
1274
1275
  break
1275
1276
  default:
1276
1277
  {
@@ -1465,13 +1466,14 @@ export const typeCheck = (ast) => {
1465
1466
  const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
1466
1467
  resolveRetunType(returns, rem, RETURNS, isPredicate)
1467
1468
  }
1469
+ const rightHand = rest.at(-1)
1468
1470
  if (
1469
- rest.at(-1) &&
1470
- rest.at(-1)[0] &&
1471
- rest.at(-1)[0][TYPE] === APPLY &&
1472
- rest.at(-1)[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
1471
+ rightHand &&
1472
+ rightHand[0] &&
1473
+ rightHand[0][TYPE] === APPLY &&
1474
+ rightHand[0][VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
1473
1475
  ) {
1474
- const n = rest.at(-1).length
1476
+ const n = rightHand.length
1475
1477
  env[name] = {
1476
1478
  [STATS]: {
1477
1479
  [TYPE_PROP]: [APPLY],
@@ -1490,15 +1492,16 @@ export const typeCheck = (ast) => {
1490
1492
  env[name][STATS].retried += 1
1491
1493
  stack.unshift(() => {
1492
1494
  checkReturnType()
1493
- check(rest.at(-1), env, exp)
1495
+ check(rightHand, env, exp)
1494
1496
  })
1495
- check(rest.at(-1), env, exp)
1497
+ check(rightHand, env, exp)
1496
1498
  } else {
1497
- check(rest.at(-1), env, exp)
1499
+ check(rightHand, env, exp)
1498
1500
  }
1499
1501
  } else {
1502
+ const isL = isLeaf(rightHand)
1500
1503
  // if (!(name in env)) {
1501
- if (rest[1][TYPE] === WORD) {
1504
+ if (isL && rightHand[TYPE] === WORD) {
1502
1505
  env[name] = env[rest[1][VALUE]]
1503
1506
 
1504
1507
  if (
@@ -1515,115 +1518,114 @@ export const typeCheck = (ast) => {
1515
1518
  warningStack.add(
1516
1519
  `${name} is assigned to ${rest[1][VALUE]} which ends in (${MUTATION_SUFFIX}) so ${name} must also end in (${MUTATION_SUFFIX}) (check #18)`
1517
1520
  )
1518
- } else {
1519
- const isL = isLeaf(rest.at(-1))
1520
- const right = isL ? rest.at(-1) : rest.at(-1)[0]
1521
- if (isL && right[TYPE] === ATOM) {
1522
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
1523
- // This never happens
1524
- // if (
1525
- // isPredicate &&
1526
- // right[VALUE] !== TRUE &&
1527
- // right[VALUE] !== FALSE
1528
- // ) {
1529
- // }
1530
- env[name] = {
1531
- [STATS]: {
1532
- retried: 0,
1533
- [TYPE_PROP]: [ATOM],
1534
- [RETURNS]: [ATOM]
1535
- }
1521
+ } else if (isL && rightHand[TYPE] === ATOM) {
1522
+ const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
1523
+ // This never happens
1524
+ // if (
1525
+ // isPredicate &&
1526
+ // right[VALUE] !== TRUE &&
1527
+ // right[VALUE] !== FALSE
1528
+ // ) {
1529
+ // }
1530
+ env[name] = {
1531
+ [STATS]: {
1532
+ retried: 0,
1533
+ [TYPE_PROP]: [ATOM],
1534
+ [RETURNS]: [ATOM]
1536
1535
  }
1537
- if (isPredicate) {
1538
- env[name][STATS][TYPE_PROP][1] = PREDICATE
1539
- env[name][STATS][RETURNS] = [ATOM, PREDICATE]
1540
- }
1541
- } else {
1542
- const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
1543
- if (
1544
- right &&
1545
- right[VALUE] &&
1546
- getSuffix(right[VALUE]) === PREDICATE_SUFFIX &&
1547
- !isPredicate
1548
- )
1536
+ }
1537
+ if (isPredicate) {
1538
+ if (rightHand[VALUE] !== TRUE && rightHand !== FALSE) {
1549
1539
  warningStack.add(
1550
- `${name} is assigned to ${right[VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #19)`
1540
+ `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but the (Atom) value is neither ${TRUE} or ${FALSE} (${stringifyArgs(
1541
+ exp
1542
+ )}) (check #14)`
1551
1543
  )
1552
- env[name] = {
1553
- [STATS]: {
1554
- retried: 0,
1555
- [TYPE_PROP]: [
1556
- isL
1557
- ? right[TYPE]
1558
- : env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
1559
- UNKNOWN
1560
- ],
1561
- [RETURNS]: [UNKNOWN]
1562
- }
1563
- }
1564
- if (isPredicate) {
1544
+ } else {
1565
1545
  env[name][STATS][TYPE_PROP][1] = PREDICATE
1566
1546
  env[name][STATS][RETURNS] = [ATOM, PREDICATE]
1567
1547
  }
1568
- if (right && right[VALUE]) {
1569
- if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
1570
- if (isLeaf(rest.at(-1).at(-1))) {
1571
- const fnName = rest.at(-1).at(-1)[VALUE]
1572
- const fn = env[fnName]
1573
- if (
1574
- !isPredicate &&
1575
- fn[STATS][RETURNS][1] === PREDICATE
1576
- ) {
1577
- warningStack.add(
1578
- `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
1579
- )
1580
- } else if (
1581
- isPredicate &&
1582
- fn[STATS][RETURNS][1] !== PREDICATE
1583
- ) {
1584
- warningStack.add(
1585
- `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
1586
- )
1587
- }
1588
- env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
1589
- env[name][STATS][RETURNS] = fn[STATS][RETURNS]
1590
- } else {
1591
- const body = rest.at(-1).at(-1).at(-1)
1592
- const rem = hasBlock(body) ? body.at(-1) : body
1593
- const returns = isLeaf(rem) ? rem : rem[0]
1594
- resolveRetunType(
1595
- returns,
1596
- rem,
1597
- TYPE_PROP,
1598
- isPredicate
1548
+ }
1549
+ } else {
1550
+ const right = rightHand[0]
1551
+ const isPredicate = getSuffix(name) === PREDICATE_SUFFIX
1552
+ if (
1553
+ right &&
1554
+ right[VALUE] &&
1555
+ getSuffix(right[VALUE]) === PREDICATE_SUFFIX &&
1556
+ !isPredicate
1557
+ )
1558
+ warningStack.add(
1559
+ `${name} is assigned to ${right[VALUE]} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #19)`
1560
+ )
1561
+ env[name] = {
1562
+ [STATS]: {
1563
+ retried: 0,
1564
+ [TYPE_PROP]: [
1565
+ isL
1566
+ ? right[TYPE]
1567
+ : env[right?.[VALUE]]?.[STATS]?.[RETURNS]?.[0] ??
1568
+ UNKNOWN
1569
+ ],
1570
+ [RETURNS]: [UNKNOWN]
1571
+ }
1572
+ }
1573
+ if (isPredicate) {
1574
+ env[name][STATS][TYPE_PROP][1] = PREDICATE
1575
+ env[name][STATS][RETURNS] = [ATOM, PREDICATE]
1576
+ }
1577
+ if (right && right[VALUE]) {
1578
+ if (right[VALUE] === KEYWORDS.CALL_FUNCTION) {
1579
+ if (isLeaf(rightHand.at(-1))) {
1580
+ const fnName = rightHand.at(-1)[VALUE]
1581
+ const fn = env[fnName]
1582
+ if (
1583
+ !isPredicate &&
1584
+ fn[STATS][RETURNS][1] === PREDICATE
1585
+ ) {
1586
+ warningStack.add(
1587
+ `${name} is assigned to ${fnName} which ends in (${PREDICATE_SUFFIX}) so ${name} must also end in (${PREDICATE_SUFFIX}) (check #24)`
1588
+ )
1589
+ } else if (
1590
+ isPredicate &&
1591
+ fn[STATS][RETURNS][1] !== PREDICATE
1592
+ ) {
1593
+ warningStack.add(
1594
+ `${name} ends in (${PREDICATE_SUFFIX}) and is expected to return (Predicate) but it doesn't (check #25)`
1599
1595
  )
1600
1596
  }
1597
+ env[name][STATS][TYPE_PROP] = fn[STATS][RETURNS]
1598
+ env[name][STATS][RETURNS] = fn[STATS][RETURNS]
1601
1599
  } else {
1602
- const body = rest.at(-1)
1600
+ const body = rightHand.at(-1).at(-1)
1603
1601
  const rem = hasBlock(body) ? body.at(-1) : body
1604
1602
  const returns = isLeaf(rem) ? rem : rem[0]
1605
1603
  resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
1606
1604
  }
1607
- if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
1608
- if (
1609
- env[right[VALUE]][STATS][RETURNS][1] ===
1610
- PREDICATE &&
1611
- !isPredicate
1612
- ) {
1613
- warningStack.add(
1614
- `${name} is assigned to the result of a (${toTypeNames(
1615
- PREDICATE
1616
- )}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
1617
- )
1618
- }
1619
- env[name][STATS][RETURNS] =
1620
- env[right[VALUE]][STATS][RETURNS]
1605
+ } else {
1606
+ const body = rightHand
1607
+ const rem = hasBlock(body) ? body.at(-1) : body
1608
+ const returns = isLeaf(rem) ? rem : rem[0]
1609
+ resolveRetunType(returns, rem, TYPE_PROP, isPredicate)
1610
+ }
1611
+ if (env[right[VALUE]]?.[STATS]?.[RETURNS]?.[1]) {
1612
+ if (
1613
+ env[right[VALUE]][STATS][RETURNS][1] === PREDICATE &&
1614
+ !isPredicate
1615
+ ) {
1616
+ warningStack.add(
1617
+ `${name} is assigned to the result of a (${toTypeNames(
1618
+ PREDICATE
1619
+ )}) so ${name} must end in (${PREDICATE_SUFFIX}) (check #23)`
1620
+ )
1621
1621
  }
1622
+ env[name][STATS][RETURNS] =
1623
+ env[right[VALUE]][STATS][RETURNS]
1622
1624
  }
1623
1625
  }
1624
1626
  }
1625
1627
  // }
1626
- check(rest.at(-1), env, scope)
1628
+ check(rightHand, env, scope)
1627
1629
  }
1628
1630
  Types.set(withScope(name, env), () => formatType(name, env))
1629
1631
  }
@@ -1723,6 +1725,7 @@ export const typeCheck = (ast) => {
1723
1725
  if (copy[ret[VALUE]])
1724
1726
  ref[STATS][RETURNS] =
1725
1727
  copy[ret[VALUE]][STATS][RETURNS]
1728
+ // function is anonymous
1726
1729
  break
1727
1730
  }
1728
1731
  }
@@ -1756,6 +1759,7 @@ export const typeCheck = (ast) => {
1756
1759
  )
1757
1760
  } else {
1758
1761
  const isSpecial = SPECIAL_FORMS_SET.has(first[VALUE])
1762
+
1759
1763
  if (first[TYPE] === APPLY && !isSpecial) {
1760
1764
  if (env[first[VALUE]][STATS][TYPE_PROP][0] === ATOM) {
1761
1765
  errorStack.add(
@@ -1876,16 +1880,31 @@ export const typeCheck = (ast) => {
1876
1880
  env[current[VALUE]] &&
1877
1881
  env[current[VALUE]][STATS][RETURNS][1] !== PRED_TYPE
1878
1882
  ) {
1879
- errorStack.add(
1880
- `Incorrect type of arguments (${i}) for (${
1881
- first[VALUE]
1882
- }). Expected (${toTypeNames(
1883
- PRED_TYPE
1884
- )}) but got (${toTypeNames(
1885
- env[current[VALUE]][STATS][RETURNS][1] ??
1886
- env[current[VALUE]][STATS][RETURNS][0]
1887
- )}) (${stringifyArgs(exp)}) (check #21)`
1888
- )
1883
+ if (
1884
+ current[VALUE] === KEYWORDS.ANONYMOUS_FUNCTION
1885
+ ) {
1886
+ const body = rest[i].at(-1)
1887
+ const rem = hasBlock(body) ? body.at(-1) : body
1888
+ const returns = isLeaf(rem) ? rem : rem[0]
1889
+ if (
1890
+ env[returns[VALUE]] &&
1891
+ root[returns[VALUE]][STATS][RETURNS][1] ===
1892
+ PREDICATE
1893
+ ) {
1894
+ // TODO invert this logic
1895
+ } else {
1896
+ errorStack.add(
1897
+ `Incorrect type of arguments (${i}) for (${
1898
+ first[VALUE]
1899
+ }). Expected (${toTypeNames(
1900
+ PRED_TYPE
1901
+ )}) but got (${toTypeNames(
1902
+ env[current[VALUE]][STATS][RETURNS][1] ??
1903
+ env[current[VALUE]][STATS][RETURNS][0]
1904
+ )}) (${stringifyArgs(exp)}) (check #21)`
1905
+ )
1906
+ }
1907
+ }
1889
1908
  }
1890
1909
  }
1891
1910
  }
@@ -2106,6 +2125,19 @@ export const typeCheck = (ast) => {
2106
2125
  ) {
2107
2126
  args[i][STATS].retried += 1
2108
2127
  stack.unshift(() => check(exp, env, scope))
2128
+ } else {
2129
+ if (
2130
+ env[rest[i][VALUE]] &&
2131
+ args[i][STATS][TYPE_PROP][0] !== UNKNOWN &&
2132
+ env[rest[i][VALUE]][STATS][TYPE_PROP][0] ===
2133
+ UNKNOWN &&
2134
+ args[i][STATS][TYPE_PROP][0] !== APPLY
2135
+ ) {
2136
+ env[rest[i][VALUE]][STATS][TYPE_PROP] =
2137
+ args[i][STATS][TYPE_PROP]
2138
+ env[rest[i][VALUE]][STATS][RETURNS] =
2139
+ args[i][STATS][RETURNS]
2140
+ }
2109
2141
  }
2110
2142
  }
2111
2143
  } else if (