fez-lisp 1.6.89 → 1.6.90

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.6.89",
5
+ "version": "1.6.90",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -614,27 +614,108 @@ const IfApplyBranch = ({
614
614
  return setPropToReturn(ref[STATS], prop, branch[STATS])
615
615
  }
616
616
  }
617
+
618
+ const validateIfMatchingBranches = (
619
+ concequent,
620
+ alternative,
621
+ env,
622
+ exp,
623
+ re,
624
+ name
625
+ ) => {
626
+ let A = null
627
+ let B = null
628
+ switch (concequent[TYPE]) {
629
+ case ATOM:
630
+ A = [ATOM, NUMBER_SUBTYPE()]
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
685
+ )
686
+ return
687
+ if (
688
+ A[0] !== B[0] ||
689
+ (isSubType(A[1]) && isSubType(B[1]) && !A[1].isMatching(B[1]))
690
+ ) {
691
+ throw new TypeError(
692
+ `(if) needs to have matching concequent and alternative branches but got (${formatSubType(
693
+ A
694
+ )}) and (${formatSubType(B)}) (${stringifyArgs(exp)}) (check #1005)`
695
+ )
696
+ }
697
+ }
617
698
  const ifExpression = ({ re, env, ref, prop, stack, exp, check }) => {
618
- if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM)
619
- return setPropToAtom(ref[STATS], prop)
699
+ const conc = isLeaf(re[0]) ? re[0] : re[0][0]
700
+ const alt = isLeaf(re[1]) ? re[1] : re[1][0]
701
+ const concequent = env[conc[VALUE]]
702
+ const alternative = env[alt[VALUE]]
703
+ if (re[0][TYPE] === ATOM || re[1][TYPE] === ATOM) {
704
+ setPropToAtom(ref[STATS], prop)
705
+ }
620
706
  // TODO check that both branches are predicates if one is
621
707
  else {
622
- const conc = isLeaf(re[0]) ? re[0] : re[0][0]
623
- const alt = isLeaf(re[1]) ? re[1] : re[1][0]
624
- const concequent = env[conc[VALUE]]
625
- const alternative = env[alt[VALUE]]
626
-
627
708
  // TODO make this more simple - it's so many different things just because types are functions or not
628
709
  // WHY not consider making return types for everything
629
710
  if (concequent)
630
711
  if (conc[TYPE] === WORD) {
631
- return setPropToTypeRef(ref[STATS], prop, concequent[STATS])
712
+ setPropToTypeRef(ref[STATS], prop, concequent[STATS])
632
713
  } else if (
633
714
  conc[TYPE] === APPLY &&
634
715
  getType(concequent[STATS]) === APPLY &&
635
716
  // Making sure the recursive function don't look for their own return type
636
717
  concequent[STATS][SIGNATURE] !== ref[STATS][SIGNATURE]
637
- ) {
718
+ )
638
719
  IfApplyBranch({
639
720
  leaf: conc,
640
721
  branch: concequent,
@@ -646,16 +727,15 @@ const ifExpression = ({ re, env, ref, prop, stack, exp, check }) => {
646
727
  exp,
647
728
  check
648
729
  })
649
- }
650
- if (alternative) {
730
+ if (alternative)
651
731
  if (alt[TYPE] === WORD) {
652
- return setPropToTypeRef(ref[STATS], prop, alternative[STATS])
732
+ setPropToTypeRef(ref[STATS], prop, alternative[STATS])
653
733
  } else if (
654
734
  alt[TYPE] === APPLY &&
655
735
  getType(alternative[STATS]) === APPLY &&
656
736
  // Making sure the recursive function don't look for their own return type
657
737
  alternative[STATS][SIGNATURE] !== ref[STATS][SIGNATURE]
658
- ) {
738
+ )
659
739
  IfApplyBranch({
660
740
  leaf: alt,
661
741
  branch: alternative,
@@ -667,9 +747,8 @@ const ifExpression = ({ re, env, ref, prop, stack, exp, check }) => {
667
747
  exp,
668
748
  check
669
749
  })
670
- }
671
- }
672
750
  }
751
+ validateIfMatchingBranches(conc, alt, env, exp, re, ref[STATS][SIGNATURE])
673
752
  }
674
753
  const resolveCondition = ({ rem, name, env, exp, prop, stack, check }) => {
675
754
  const ret = rem[0]
@@ -958,8 +1037,13 @@ const initArrayTypeRec = ({ rem, env }) =>
958
1037
  x[TYPE] === ATOM ? NUMBER_SUBTYPE() : new SubType([UNKNOWN])
959
1038
  ]
960
1039
  else if (env[x[0][VALUE]])
961
- if (x.length > 1 && env[x[0][VALUE]][STATS][RETURNS][0] === COLLECTION)
1040
+ if (x.length > 1 && x[0][VALUE] === KEYWORDS.CREATE_ARRAY)
962
1041
  return initArrayTypeRec({ rem: x, env })
1042
+ else if (
1043
+ x.length > 1 &&
1044
+ env[x[0][VALUE]][STATS][RETURNS][0] === COLLECTION
1045
+ )
1046
+ return [getReturns(env[x[0][VALUE]][STATS])]
963
1047
  else if (GET_ARRAY_INFERENCE_SET.has(x[0][VALUE])) {
964
1048
  const res = resolveGetterRec(x, env)
965
1049
  if (!res) return [UNKNOWN]
@@ -2114,7 +2198,7 @@ export const typeCheck = (
2114
2198
  (x) => isGenericType(x[STATS]) || isGenericReturn(x[STATS])
2115
2199
  )
2116
2200
  ) {
2117
- const rec = (ref) => {
2201
+ const genericRecursiveDecent = (ref) => {
2118
2202
  if (isGenericReturn(ref[STATS])) {
2119
2203
  const [index, multiplier] = ref[STATS][RETURNS][2]
2120
2204
  const desiredTypeIndex = env[first[VALUE]][STATS][
@@ -2229,7 +2313,8 @@ export const typeCheck = (
2229
2313
  expected[STATS][TYPE_PROP].length = 2
2230
2314
  }
2231
2315
  }
2232
- if (expected[STATS][ARGUMENTS].length) rec(expected)
2316
+ if (expected[STATS][ARGUMENTS].length)
2317
+ genericRecursiveDecent(expected)
2233
2318
  }
2234
2319
  }
2235
2320
  const copy = Object.create(env)
@@ -2240,7 +2325,7 @@ export const typeCheck = (
2240
2325
  }
2241
2326
  copy[newName][STATS][SIGNATURE] = newName
2242
2327
 
2243
- rec(copy[newName])
2328
+ genericRecursiveDecent(copy[newName])
2244
2329
 
2245
2330
  const cexp = structuredClone(exp)
2246
2331
  copy[newName][STATS].source = structuredClone(
@@ -2260,6 +2345,7 @@ export const typeCheck = (
2260
2345
  }
2261
2346
  }
2262
2347
  }
2348
+
2263
2349
  stagger(stack, 'append', [first, env], judge)
2264
2350
  stagger(stack, 'prepend', [first, env], judge)
2265
2351
  for (let i = 0; i < rest.length; ++i) {
package/src/compiler.js CHANGED
@@ -276,18 +276,17 @@ const comp = (tree, Drill) => {
276
276
  )}}return -1})();`
277
277
  }
278
278
 
279
- case STATIC_TYPES.ABSTRACTION:
280
- case STATIC_TYPES.COLLECTION:
281
- case STATIC_TYPES.UNKNOWN:
282
- case STATIC_TYPES.ATOM:
283
- case STATIC_TYPES.BOOLEAN:
284
- case STATIC_TYPES.ANY:
285
- case STATIC_TYPES.NUMBER:
286
- case STATIC_TYPES.NUMBERS:
287
- case STATIC_TYPES.ABSTRACTIONS:
288
- case STATIC_TYPES.BOOLEANS:
289
- case STATIC_TYPES.COLLECTIONS:
290
- case STATIC_TYPES.AS_NUMBER:
279
+ // case STATIC_TYPES.ABSTRACTION:
280
+ // case STATIC_TYPES.COLLECTION:
281
+ // case STATIC_TYPES.UNKNOWN:
282
+ // case STATIC_TYPES.ATOM:
283
+ // case STATIC_TYPES.BOOLEAN:
284
+ // case STATIC_TYPES.ANY:
285
+ // case STATIC_TYPES.NUMBER:
286
+ // case STATIC_TYPES.NUMBERS:
287
+ // case STATIC_TYPES.ABSTRACTIONS:
288
+ // case STATIC_TYPES.BOOLEANS:
289
+ // case STATIC_TYPES.COLLECTIONS:
291
290
  case DEBUG.LOG:
292
291
  case DEBUG.STRING:
293
292
  case DEBUG.UNQUOTED_STRING:
package/src/enhance.js CHANGED
@@ -36,11 +36,6 @@ const opt = (ast) => {
36
36
  case APPLY:
37
37
  {
38
38
  switch (first[VALUE]) {
39
- case STATIC_TYPES.AS_NUMBER:
40
- exp.length = 0
41
- for (let i = 0; i < rest.length; ++i) exp.push(...rest[i])
42
- evaluate(exp)
43
- break
44
39
  case KEYWORDS.DEFINE_VARIABLE:
45
40
  {
46
41
  const last = exp.at(-1)
@@ -257,7 +252,6 @@ export const removeCast = (ast) => {
257
252
  case STATIC_TYPES.ABSTRACTIONS:
258
253
  case STATIC_TYPES.BOOLEANS:
259
254
  case STATIC_TYPES.COLLECTIONS:
260
- case STATIC_TYPES.AS_NUMBER:
261
255
  exp.length = 0
262
256
  for (let i = 0; i < rest.length; ++i) exp.push(...rest[i])
263
257
  evaluate(exp)
package/src/keywords.js CHANGED
@@ -20,7 +20,6 @@ export const STATIC_TYPES = {
20
20
  BOOLEANS: 'Booleans',
21
21
  ABSTRACTIONS: 'Abstractions',
22
22
  COLLECTIONS: 'Collections',
23
- AS_NUMBER: 'numberp',
24
23
  ANY: 'Any',
25
24
  DEFINE_TYPE: 'the'
26
25
  }
package/src/macros.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  VALUE,
17
17
  WORD
18
18
  } from './keywords.js'
19
- import { hasBlock, stringifyArgs } from './utils.js'
19
+ import { hasBlock, logExp, stringifyArgs } from './utils.js'
20
20
  import { NIL } from './types.js'
21
21
  export const SUGGAR = {
22
22
  // Syntactic suggars
@@ -382,6 +382,15 @@ export const deSuggarAst = (ast, scope) => {
382
382
  exp[0][TYPE] = ATOM
383
383
  exp[0][VALUE] = FALSE
384
384
  } else if (rest.length > 2) {
385
+ // TODO: maybe one day implement
386
+ // Constant folding
387
+ // it works sort of like this
388
+ // while (
389
+ // rest.at(-2) &&
390
+ // rest.at(-1)[TYPE] === ATOM &&
391
+ // rest.at(-2)[TYPE] === ATOM
392
+ // )
393
+ // rest[rest.length - 2][VALUE] += rest.pop()[VALUE]
385
394
  exp.length = 0
386
395
  let temp = exp
387
396
  for (let i = 0; i < rest.length; i += 1) {
@@ -522,7 +531,11 @@ export const deSuggarAst = (ast, scope) => {
522
531
  KEYWORDS.IF
523
532
  } ${stringifyArgs(rest)})`
524
533
  )
525
- if (rest.length === 2) exp.push([WORD, NIL])
534
+ if (rest.length === 2) {
535
+ // for this to work also make nil to be a false boolean
536
+ // exp[2] = [[APPLY, 'logic:true'], exp[2]]
537
+ exp.push([WORD, NIL])
538
+ }
526
539
  }
527
540
  deSuggarAst(exp[1], scope)
528
541
  break
package/src/parser.js CHANGED
@@ -150,7 +150,6 @@ export const AST = {
150
150
  case STATIC_TYPES.ABSTRACTIONS:
151
151
  case STATIC_TYPES.BOOLEANS:
152
152
  case STATIC_TYPES.COLLECTIONS:
153
- case STATIC_TYPES.AS_NUMBER:
154
153
  out += dfs(tail[0])
155
154
  break
156
155
  default:
@@ -193,7 +192,6 @@ export const AST = {
193
192
  case STATIC_TYPES.ABSTRACTIONS:
194
193
  case STATIC_TYPES.BOOLEANS:
195
194
  case STATIC_TYPES.COLLECTIONS:
196
- case STATIC_TYPES.AS_NUMBER:
197
195
  out += dfs(tail[0])
198
196
  break
199
197
  default:
@@ -241,7 +239,6 @@ pub fn ${mod}() -> Expression { ${str} }`
241
239
  case STATIC_TYPES.ABSTRACTIONS:
242
240
  case STATIC_TYPES.BOOLEANS:
243
241
  case STATIC_TYPES.COLLECTIONS:
244
- case STATIC_TYPES.AS_NUMBER:
245
242
  out += dfs(tail[0])
246
243
  break
247
244
  default:
package/src/types.js CHANGED
@@ -234,27 +234,6 @@ export const SPECIAL_FORM_TYPES = {
234
234
  [RETURNS]: [ATOM]
235
235
  }
236
236
  },
237
- [STATIC_TYPES.AS_NUMBER]: {
238
- [STATS]: {
239
- [TYPE_PROP]: [APPLY],
240
- [SIGNATURE]: STATIC_TYPES.AS_NUMBER,
241
- retried: Infinity,
242
- [ARG_COUNT]: 1,
243
- [ARGUMENTS]: [
244
- {
245
- [STATS]: {
246
- retried: Infinity,
247
- [SIGNATURE]: PLACEHOLDER,
248
- [TYPE_PROP]: [ATOM, SPECIAL_BOOLEAN],
249
- [RETURNS]: [ATOM, SPECIAL_BOOLEAN],
250
- [ARGUMENTS]: [],
251
- [ARG_COUNT]: 0
252
- }
253
- }
254
- ],
255
- [RETURNS]: [ATOM, SPECIAL_NUMBER]
256
- }
257
- },
258
237
  [STATIC_TYPES.BOOLEAN]: {
259
238
  [STATS]: {
260
239
  [TYPE_PROP]: [APPLY],
package/src/utils.js CHANGED
@@ -273,7 +273,7 @@ const toIgnore = (ast) => {
273
273
  break
274
274
  }
275
275
  }
276
- dfs(ast[0])
276
+ dfs(ast)
277
277
  return out
278
278
  // ast.filter(([x]) => isDefinition(x)).map(([_, x]) => x[VALUE])
279
279
  }
@@ -282,12 +282,12 @@ export const treeShake = (ast, libs) => {
282
282
  const visited = new Set()
283
283
  const ignored = new Set(toIgnore(ast))
284
284
  deepShake(ast, deps, visited, ignored)
285
- return extractDeps(visited, deps)
285
+ return [extractDeps(visited, deps), visited]
286
286
  }
287
287
  export const shakedList = (ast, libs) => {
288
288
  const deps = toDeps(libs)
289
289
  const visited = new Set()
290
- const ignored = new Set(toIgnore(ast))
290
+ const ignored = new Set(toIgnore(ast[0]))
291
291
  deepShake(ast, deps, visited, ignored)
292
292
  const out = []
293
293
  for (const [key] of deps) if (visited.has(key)) out.push(key)
@@ -311,7 +311,10 @@ export const wrapInApplyLambda = (ast) => [
311
311
  ]
312
312
  export const interpret = (ast, keywords) =>
313
313
  ast.reduce((_, x) => evaluate(x, keywords), 0)
314
- export const shake = (parsed, std) => treeShake(parsed, std).concat(parsed)
314
+ export const shake = (parsed, std) => {
315
+ const [shaked] = treeShake(parsed, std)
316
+ return shaked.concat(parsed)
317
+ }
315
318
  export const tree = (source, std) =>
316
319
  std
317
320
  ? shake(LISP.parse(deSuggarSource(removeNoCode(source))), std)