fez-lisp 1.5.124 → 1.5.126

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.124",
5
+ "version": "1.5.126",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
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,16 @@ 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
+ logExp,
50
56
  stringifyArgs
51
57
  } from './utils.js'
52
58
  Set.prototype.union = function (B) {
@@ -152,6 +158,7 @@ export const setPropToReturn = (stats, prop, value) => {
152
158
  }
153
159
  export const setPropToReturnRef = (stats, prop, value) => {
154
160
  return (
161
+ stats[prop] &&
155
162
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
156
163
  value[RETURNS][0] !== UNKNOWN &&
157
164
  (stats[prop] = value[RETURNS])
@@ -159,6 +166,7 @@ export const setPropToReturnRef = (stats, prop, value) => {
159
166
  }
160
167
  export const setPropToType = (stats, prop, value) => {
161
168
  return (
169
+ stats[prop] &&
162
170
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
163
171
  ((stats[prop][0] = value[TYPE_PROP][0]),
164
172
  value[TYPE_PROP][1] && (stats[prop][1] = value[TYPE_PROP][1]))
@@ -166,6 +174,7 @@ export const setPropToType = (stats, prop, value) => {
166
174
  }
167
175
  export const setPropToTypeRef = (stats, prop, value) => {
168
176
  return (
177
+ stats[prop] &&
169
178
  (stats[prop][0] === UNKNOWN || stats[prop][0] === ANY) &&
170
179
  (stats[prop] = value[TYPE_PROP])
171
180
  )
@@ -177,6 +186,9 @@ export const setReturnToAtom = (stats) => {
177
186
  }
178
187
  export const setTypeToAtom = (stats) =>
179
188
  (isUnknownType(stats) || isAnyType(stats)) && (stats[TYPE_PROP][0] = ATOM)
189
+ export const setTypeToCollection = (stats) =>
190
+ (isUnknownType(stats) || isAnyType(stats)) &&
191
+ (stats[TYPE_PROP][0] = COLLECTION)
180
192
  export const setReturnToAbbstraction = (stats) =>
181
193
  isUnknownReturn(stats) && (stats[RETURNS][0] = APPLY)
182
194
  export const setTypeRef = (stats, value) =>
@@ -217,6 +229,15 @@ export const setType = (stats, value) =>
217
229
  !isUnknownType(value) &&
218
230
  ((stats[TYPE_PROP][0] = value[TYPE_PROP][0]),
219
231
  value[TYPE_PROP][1] && (stats[TYPE_PROP][1] = value[TYPE_PROP][1]))
232
+ export const setSubType = (stats, value) =>
233
+ // makes no senseto protect this for now
234
+ hasSubType(value) && (stats[TYPE_PROP][1] = value[TYPE_PROP][1])
235
+ export const setPropToSubType = (stats, prop, value) =>
236
+ // makes no senseto protect this for now
237
+ hasSubType(value) && (stats[prop][1] = value[TYPE_PROP][1])
238
+ export const setPropToSubReturn = (stats, prop, value) =>
239
+ // makes no senseto protect this for now
240
+ hasSubType(value) && (stats[prop][1] = value[RETURNS][1])
220
241
  export const setTypeToReturn = (stats, value) =>
221
242
  (isUnknownType(stats) || isAnyType(stats)) &&
222
243
  !isUnknownReturn(value) &&
@@ -230,6 +251,10 @@ export const setReturnToType = (stats, value) =>
230
251
  export const isAnyReturn = (stats) => stats && stats[RETURNS][0] === ANY
231
252
  export const isAnyType = (stats) => stats && stats[TYPE_PROP][0] === ANY
232
253
  export const isUnknownType = (stats) => stats && stats[TYPE_PROP][0] === UNKNOWN
254
+ export const isUnknownProp = (stats, prop) => {
255
+ return stats && stats[prop][0] === UNKNOWN
256
+ }
257
+
233
258
  export const isUnknownReturn = (stats) => stats[RETURNS][0] === UNKNOWN
234
259
  export const getType = (stats) => stats && stats[TYPE_PROP][0]
235
260
  export const getTypes = (stats) => stats && stats[TYPE_PROP]
@@ -266,9 +291,7 @@ const notABooleanType = (a, b) => {
266
291
  getSubType(a).has(PREDICATE) &&
267
292
  !isUnknownType(b) &&
268
293
  !isAnyType(b) &&
269
- (!isAtomType(b) ||
270
- !hasSubType(b) ||
271
- getSubType(a).difference(getSubType(b)).size !== 0)
294
+ (!hasSubType(b) || getSubType(a).difference(getSubType(b)).size !== 0)
272
295
  )
273
296
  }
274
297
  const notABooleanReturn = (a, b) => {
@@ -482,6 +505,87 @@ const resolveCondition = ({ rem, name, env, exp, prop }) => {
482
505
  break
483
506
  }
484
507
  }
508
+ const resolveSetter = (first, rest, env) => {
509
+ if (
510
+ getSuffix(first[VALUE]) === MUTATION_SUFFIX &&
511
+ MUTATORS_SET.has(first[VALUE]) &&
512
+ rest[0] &&
513
+ isLeaf(rest[0]) &&
514
+ rest[0][TYPE] !== ATOM &&
515
+ env[rest[0][VALUE]]
516
+ ) {
517
+ const name = rest[0][VALUE]
518
+ const current = env[name]
519
+ if (!hasSubType(current[STATS])) {
520
+ const right = isLeaf(rest.at(-1)) ? rest.at(-1) : rest.at(-1)[0]
521
+ switch (right[TYPE]) {
522
+ case ATOM:
523
+ current[STATS][TYPE_PROP][1] = new Set([NUMBER])
524
+ break
525
+ case WORD:
526
+ if (env[right[VALUE]]) {
527
+ if (hasSubType(env[right[VALUE]][STATS]))
528
+ current[STATS][TYPE_PROP][1] = new Set(
529
+ getSubType(env[right[VALUE]][STATS])
530
+ )
531
+ else
532
+ current[STATS][TYPE_PROP][1] = new Set([
533
+ getType(env[right[VALUE]][STATS])
534
+ ])
535
+ }
536
+ break
537
+ case APPLY:
538
+ if (env[right[VALUE]]) {
539
+ if (hasSubReturn(env[right[VALUE]][STATS]))
540
+ current[STATS][TYPE_PROP][1] = new Set([
541
+ ...getSubReturn(env[right[VALUE]][STATS])
542
+ ])
543
+ else
544
+ current[STATS][TYPE_PROP][1] = new Set([
545
+ env[right[VALUE]][STATS][RETURNS][0]
546
+ ])
547
+ }
548
+ break
549
+ }
550
+ setTypeToCollection(current[STATS])
551
+ }
552
+ }
553
+ }
554
+ const resolveGetter = ({ rem, prop, name, env }) => {
555
+ const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
556
+ if (!env[array[VALUE]] || !env[name]) return true
557
+ switch (array[TYPE]) {
558
+ case APPLY:
559
+ if (hasSubType(env[array[VALUE]][STATS])) {
560
+ const rightSub = getSubReturn(env[array[VALUE]][STATS])
561
+ const isAtom = rightSub.has(NUMBER) || rightSub.has(PREDICATE)
562
+ const isCollection = rightSub.has(COLLECTION)
563
+ if (isAtom && !isCollection) {
564
+ setPropToAtom(env[name][STATS], prop)
565
+ setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
566
+ } else if (!isAtom && isCollection) {
567
+ setPropToReturn(env[name][STATS], env[array[VALUE]][STATS])
568
+ }
569
+ } else return false
570
+ break
571
+ case WORD:
572
+ {
573
+ if (hasSubType(env[array[VALUE]][STATS])) {
574
+ const rightSub = getSubType(env[array[VALUE]][STATS])
575
+ const isAtom = rightSub.has(NUMBER) || rightSub.has(PREDICATE)
576
+ const isCollection = rightSub.has(COLLECTION)
577
+ if (isAtom && !isCollection) {
578
+ setPropToAtom(env[name][STATS], prop)
579
+ setPropToSubType(env[name][STATS], prop, env[array[VALUE]][STATS])
580
+ } else if (!isAtom && isCollection) {
581
+ setPropToType(env[name][STATS], env[array[VALUE]][STATS])
582
+ }
583
+ } else return false
584
+ }
585
+ break
586
+ }
587
+ return true
588
+ }
485
589
  const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
486
590
  if (returns[TYPE] === ATOM) {
487
591
  // ATOM ASSIGMENT
@@ -493,6 +597,21 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
493
597
  break
494
598
  default:
495
599
  {
600
+ if (
601
+ GETTERS_SET.has(returns[VALUE]) &&
602
+ !resolveGetter({ rem, prop, name, env })
603
+ )
604
+ return retry(env[name][STATS], stack, () => {
605
+ resolveRetunType({
606
+ returns,
607
+ rem,
608
+ stack,
609
+ prop,
610
+ exp,
611
+ name,
612
+ env
613
+ })
614
+ })
496
615
  checkPredicateNameDeep(name, exp, exp.slice(1), returns)
497
616
  if (!env[returns[VALUE]]) return false
498
617
  else if (getType(env[returns[VALUE]][STATS]) === APPLY) {
@@ -508,11 +627,6 @@ const resolveRetunType = ({ returns, rem, stack, prop, exp, name, env }) => {
508
627
  env[name][STATS],
509
628
  env[returns[VALUE]][STATS]
510
629
  )
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
630
  })
517
631
  else setReturnRef(env[name][STATS], env[returns[VALUE]][STATS])
518
632
  }
@@ -567,6 +681,8 @@ export const typeCheck = (ast) => {
567
681
  break
568
682
  case APPLY: {
569
683
  switch (first[VALUE]) {
684
+ // Var
685
+ // ---------------
570
686
  case KEYWORDS.DEFINE_VARIABLE:
571
687
  if (rest.length !== 2)
572
688
  throw new TypeError(
@@ -778,6 +894,12 @@ export const typeCheck = (ast) => {
778
894
  }
779
895
  break
780
896
  default:
897
+ // Setters are just like DEFINE_VARIABLE as they are essentially the Var case for Collections
898
+ // So they MUST happen before Judgement
899
+ resolveSetter(first, rest, env)
900
+ // end of Var ---------------
901
+
902
+ // Judgement
781
903
  stack.append(() => {
782
904
  if (!isSpecial && env[first[VALUE]] === undefined)
783
905
  throw new TypeError(
@@ -915,7 +1037,6 @@ export const typeCheck = (ast) => {
915
1037
  setReturnRef(env[name][STATS], args[i][STATS])
916
1038
  break
917
1039
  }
918
-
919
1040
  // TODO also handle casting
920
1041
  }
921
1042
  } else {
@@ -1331,47 +1452,6 @@ export const typeCheck = (ast) => {
1331
1452
  }
1332
1453
  match()
1333
1454
  }
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
1455
  }
1376
1456
  }
1377
1457
  })
@@ -16,7 +16,7 @@ const deepTransform = (predicate, transform, tree) => {
16
16
  else deepTransform(predicate, transform, leaf)
17
17
  }
18
18
  }
19
- export const enhance = (ast) => {
19
+ const opt = (ast) => {
20
20
  const evaluate = (exp) => {
21
21
  const [first, ...rest] = isLeaf(exp) ? [exp] : exp
22
22
  if (first != undefined) {
@@ -213,11 +213,12 @@ export const enhance = (ast) => {
213
213
  default:
214
214
  break
215
215
  }
216
-
217
216
  for (const r of rest) evaluate(r)
218
217
  }
219
218
  }
220
- evaluate(AST.parse(AST.stringify(ast)))
219
+ evaluate(ast)
221
220
  const shaked = shake(ast[1][1].slice(1), std)
222
221
  return wrapInBlock(shaked)
223
222
  }
223
+
224
+ export const enhance = (ast) => opt(AST.parse(AST.stringify(ast))[0])
package/src/keywords.js CHANGED
@@ -99,8 +99,6 @@ export const PREDICATES_OUTPUT_SET = new Set([
99
99
  ])
100
100
  export const MUTATORS_SET = new Set([
101
101
  KEYWORDS.SET_ARRAY,
102
- 'set:with!',
103
- 'map:with!',
104
102
  'matrix:set!',
105
103
  'matrix:set-and-get!',
106
104
  'array:set-and-get!',
@@ -112,19 +110,19 @@ export const MUTATORS_SET = new Set([
112
110
  'array:set!',
113
111
  'array:append!',
114
112
  'array:push!',
115
- 'var:set!',
116
- 'array:merge!',
117
- 'list:merge!',
118
- 'list:concat!'
113
+ 'var:set!'
119
114
  ])
120
- export const MULTI_DIMENTIONAL_SETTERS = new Set([
121
- 'set:with!',
122
- 'map:with!',
123
- 'matrix:set!',
115
+ export const GETTERS_SET = new Set([
116
+ KEYWORDS.GET_ARRAY,
117
+ 'matrix:get',
124
118
  'matrix:set-and-get!',
125
119
  'array:set-and-get!',
126
- 'set:add!',
127
- 'map:set!',
128
- 'list:merge!',
129
- 'list:concat!'
120
+ 'var:set-and-get!',
121
+ 'map:set-and-get!',
122
+ 'set:add-and-get!',
123
+ 'set:get',
124
+ 'map:get',
125
+ 'array:get',
126
+ 'array:pop!',
127
+ 'var:get'
130
128
  ])
package/src/types.js CHANGED
@@ -30,6 +30,9 @@ 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 ANY_SUBTYPE = () => new Set([ANY])
34
+ export const COLLECTION_SUBTYPE = () => new Set([COLLECTION])
35
+ export const NUMBER_SUBTYPE = () => new Set([NUMBER])
33
36
 
34
37
  export const toTypeNames = (type) => {
35
38
  switch (type) {
@@ -37,15 +40,16 @@ export const toTypeNames = (type) => {
37
40
  return 'Abstraction'
38
41
  case PREDICATE:
39
42
  return 'Boolean'
43
+ case ATOM:
40
44
  case NUMBER:
41
45
  return 'Number'
42
- case ATOM:
43
- return 'Atom'
46
+ // case ATOM:
47
+ // return 'Atom'
44
48
  case UNKNOWN:
45
49
  return 'Unknown'
46
50
  case COLLECTION:
47
- return 'Array'
48
- // return '[]'
51
+ // return 'Array'
52
+ return '[Unknown]'
49
53
  case ANY:
50
54
  return 'Any'
51
55
  default:
@@ -60,6 +64,8 @@ export const toTypeNamesAnyToUknown = (type) => {
60
64
  return toTypeNames(type)
61
65
  }
62
66
  }
67
+ export const GETTER = 1
68
+ export const SETTER = 2
63
69
  export const SPECIAL_FORM_TYPES = {
64
70
  [SCOPE_NAME]: ';',
65
71
  // [ORDER]: 0,
@@ -718,6 +724,7 @@ export const SPECIAL_FORM_TYPES = {
718
724
  [STATS]: {
719
725
  [TYPE_PROP]: [APPLY],
720
726
  [SIGNATURE]: KEYWORDS.GET_ARRAY,
727
+ tag: GETTER,
721
728
  retried: Infinity,
722
729
  [ARG_COUNT]: 2,
723
730
  [ARGUMENTS]: [
@@ -750,6 +757,7 @@ export const SPECIAL_FORM_TYPES = {
750
757
  [KEYWORDS.SET_ARRAY]: {
751
758
  [STATS]: {
752
759
  [TYPE_PROP]: [APPLY],
760
+ tag: SETTER,
753
761
  retried: Infinity,
754
762
  [ARG_COUNT]: 3,
755
763
  [ARGUMENTS]: [
@@ -757,8 +765,8 @@ export const SPECIAL_FORM_TYPES = {
757
765
  [STATS]: {
758
766
  retried: 0,
759
767
  [SIGNATURE]: PLACEHOLDER,
760
- [TYPE_PROP]: [COLLECTION],
761
- [RETURNS]: [COLLECTION],
768
+ [TYPE_PROP]: [COLLECTION, ANY_SUBTYPE()],
769
+ [RETURNS]: [COLLECTION, ANY_SUBTYPE()],
762
770
 
763
771
  [ARGUMENTS]: [],
764
772
  [ARG_COUNT]: 0
@@ -787,7 +795,7 @@ export const SPECIAL_FORM_TYPES = {
787
795
  }
788
796
  }
789
797
  ],
790
- [RETURNS]: [COLLECTION]
798
+ [RETURNS]: [COLLECTION, ANY_SUBTYPE()]
791
799
  }
792
800
  },
793
801
  [KEYWORDS.POP_ARRAY]: {
@@ -1185,18 +1193,18 @@ export const SPECIAL_FORM_TYPES = {
1185
1193
 
1186
1194
  export const formatSubType = (T) => {
1187
1195
  switch (T[0]) {
1188
- // case COLLECTION:
1189
- // return `[${
1190
- // T[1] instanceof Set
1191
- // ? [...T[1]]
1192
- // .map((x) =>
1193
- // x === COLLECTION
1194
- // ? formatSubType([x])
1195
- // : toTypeNamesAnyToUknown(x)
1196
- // )
1197
- // .join(' ')
1198
- // : toTypeNamesAnyToUknown(ANY)
1199
- // }]`
1196
+ case COLLECTION:
1197
+ return `[${
1198
+ T[1] instanceof Set
1199
+ ? [...T[1]]
1200
+ .map((x) =>
1201
+ x === COLLECTION
1202
+ ? formatSubType([x])
1203
+ : toTypeNamesAnyToUknown(x)
1204
+ )
1205
+ .join(' ')
1206
+ : toTypeNamesAnyToUknown(ANY)
1207
+ }]`
1200
1208
  case ATOM:
1201
1209
  return `${
1202
1210
  T[1] instanceof Set
package/src/utils.js CHANGED
@@ -15,13 +15,13 @@ import {
15
15
  deSuggarSource,
16
16
  handleUnbalancedQuotes
17
17
  } from './macros.js'
18
- import { OPTIMIZATIONS } from './enchance.js'
18
+ import { OPTIMIZATIONS } from './enhance.js'
19
19
  export const logError = (error) =>
20
20
  console.log('\x1b[31m', `\n${error}\n`, '\x1b[0m')
21
21
  export const logSuccess = (output) => console.log('\x1b[32m', output, '\x1b[0m')
22
22
  export const wrapInBracesString = (exp) => `(${stringifyArgs(exp)})`
23
- export const logExp = function (exp, marker = ':D') {
24
- console.log(marker, wrapInBracesString(exp), ...[...arguments].slice(2))
23
+ export const logExp = function (exp, ...args) {
24
+ console.log(wrapInBracesString(exp), ...args)
25
25
  return exp
26
26
  }
27
27
  export const formatCallstack = (callstack) =>
@@ -457,6 +457,14 @@ export class Brr {
457
457
  for (let i = half; i < initial.length; ++i) this._addToRight(initial[i])
458
458
  return this
459
459
  }
460
+ // reverse() {
461
+ // const left = this._left
462
+ // const right = this._right
463
+ // right.unshift(left.shift())
464
+ // this._left = right
465
+ // this._right = left
466
+ // return this
467
+ // }
460
468
  *[Symbol.iterator]() {
461
469
  for (let i = 0, len = this.length; i < len; ++i) yield this.get(i)
462
470
  }