fez-lisp 1.5.158 → 1.5.160

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.158",
5
+ "version": "1.5.160",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -841,7 +841,7 @@ const resolveReturnType = ({
841
841
  // This is insitialisation of identity or any other
842
842
  // function that returns it's argument
843
843
  // Redifine the variable but since it's an error doing that
844
- // Delete it
844
+ // Delete it first
845
845
  delete env[name]
846
846
  check(
847
847
  [
@@ -920,7 +920,7 @@ const checkReturnType = ({ exp, stack, name, env, check }) => {
920
920
  const stagger = (stack, method, data, fn) => {
921
921
  stack[method]({ data, fn })
922
922
  }
923
- export const typeCheck = (ast) => {
923
+ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
924
924
  const Types = new Map()
925
925
  const stack = new Brr()
926
926
  let scopeIndex = 0
@@ -1124,6 +1124,7 @@ export const typeCheck = (ast) => {
1124
1124
  exp
1125
1125
  )})`
1126
1126
  )
1127
+ // TODO check leT define types
1127
1128
  const name = rest[0][VALUE]
1128
1129
  if (env.hasOwnProperty(name))
1129
1130
  throw new ReferenceError(
@@ -1131,6 +1132,11 @@ export const typeCheck = (ast) => {
1131
1132
  exp
1132
1133
  )})`
1133
1134
  )
1135
+
1136
+ if (name in env) {
1137
+ Types.set(withScope(name, env), () => formatType(name, env))
1138
+ break
1139
+ }
1134
1140
  // Predicate name consistency
1135
1141
  const rightHand = rest.at(-1)
1136
1142
  if (
@@ -1170,6 +1176,7 @@ export const typeCheck = (ast) => {
1170
1176
  name,
1171
1177
  check
1172
1178
  })
1179
+ // TODO: remove this as maybe it is not needed
1173
1180
  check(rightHand, env, exp)
1174
1181
  })
1175
1182
  check(rightHand, env, exp)
@@ -1307,9 +1314,9 @@ export const typeCheck = (ast) => {
1307
1314
  })
1308
1315
  break
1309
1316
  default:
1310
- if (copy[ret[VALUE]])
1317
+ if (copy[ret[VALUE]]) {
1311
1318
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
1312
- else
1319
+ } else
1313
1320
  stagger(stack, 'append', [ret, copy], () => {
1314
1321
  if (copy[ret[VALUE]])
1315
1322
  setReturnRef(ref[STATS], copy[ret[VALUE]][STATS])
@@ -1657,8 +1664,8 @@ export const typeCheck = (ast) => {
1657
1664
  }
1658
1665
  }
1659
1666
  }
1660
- check(ast, SPECIAL_FORM_TYPES, ast)
1667
+ check(ast, ctx, ast)
1661
1668
  while (stack.length) stack.cut().fn()
1662
1669
  return [ast, Types]
1663
1670
  }
1664
- export const type = (ast) => typeCheck(ast)[0]
1671
+ export const type = (ast, ctx) => typeCheck(ast, ctx)[0]
package/src/types.js CHANGED
@@ -6,9 +6,11 @@ import {
6
6
  KEYWORDS,
7
7
  PLACEHOLDER,
8
8
  STATIC_TYPES,
9
+ TYPE,
9
10
  VALUE
10
11
  } from './keywords.js'
11
- import { stringifyArgs } from './utils.js'
12
+ import { isLeaf } from './parser.js'
13
+ import { shakedList, stringifyArgs } from './utils.js'
12
14
  export const ARG_COUNT = 'argumentsN'
13
15
  export const VARIADIC = Infinity
14
16
  export const STATS = '__stats__'
@@ -61,6 +63,30 @@ export const toTypeNames = (type) => {
61
63
  break
62
64
  }
63
65
  }
66
+ export const toTypeCodes = (type) => {
67
+ switch (type) {
68
+ case 'Abstraction':
69
+ return [APPLY]
70
+ case 'Boolean':
71
+ return [ATOM, BOOLEAN_SUBTYPE()]
72
+ case 'Atom':
73
+ return [ATOM]
74
+ case 'Number':
75
+ return [ATOM, NUMBER_SUBTYPE()]
76
+ case 'Unknown':
77
+ return [UNKNOWN]
78
+ case 'Unknowns':
79
+ return [COLLECTION]
80
+ case 'Numbers':
81
+ return [COLLECTION, NUMBER_SUBTYPE()]
82
+ case 'Booleans':
83
+ return [COLLECTION, BOOLEAN_SUBTYPE()]
84
+ case 'Any':
85
+ return [ANY]
86
+ default:
87
+ break
88
+ }
89
+ }
64
90
  export const toTypeNamesAnyToUknown = (type) => {
65
91
  switch (type) {
66
92
  case ANY:
@@ -1330,3 +1356,62 @@ export const validateLambda = (exp, name) => {
1330
1356
  )})`
1331
1357
  )
1332
1358
  }
1359
+
1360
+ export const lambdaType = (t) => [t.slice(1, -1), t.at(-1)[1]]
1361
+ export const toArgType = (A, i) => {
1362
+ const out = []
1363
+ const arg = isLeaf(A) ? A : A[0]
1364
+ if (arg[TYPE] === APPLY) {
1365
+ const [args, returns] = lambdaType(A)
1366
+ out.push({
1367
+ [STATS]: {
1368
+ argIndex: i,
1369
+ retried: Infinity,
1370
+ [IS_ARGUMENT]: true,
1371
+ [SIGNATURE]: PLACEHOLDER,
1372
+ [TYPE_PROP]: [APPLY],
1373
+ [RETURNS]: toTypeCodes(returns[VALUE]),
1374
+ [ARGUMENTS]: args.map(toArgType).flat(1),
1375
+ [ARG_COUNT]: args.length
1376
+ }
1377
+ })
1378
+ } else {
1379
+ out.push({
1380
+ [STATS]: {
1381
+ argIndex: i,
1382
+ retried: Infinity,
1383
+ [IS_ARGUMENT]: true,
1384
+ [SIGNATURE]: PLACEHOLDER,
1385
+ [TYPE_PROP]: toTypeCodes(arg[VALUE]),
1386
+ [RETURNS]: toTypeCodes(arg[VALUE]),
1387
+ [ARGUMENTS]: [],
1388
+ [ARG_COUNT]: 0
1389
+ }
1390
+ })
1391
+ }
1392
+ return out
1393
+ }
1394
+ export const fromSourceToType = (T) => {
1395
+ const out = {}
1396
+ for (const t of T) {
1397
+ const name = t[1][VALUE]
1398
+ const [args, returns] = lambdaType(t[2])
1399
+ out[name] = {
1400
+ [STATS]: {
1401
+ retried: Infinity,
1402
+ [TYPE_PROP]: [APPLY],
1403
+ [SIGNATURE]: name,
1404
+ [ARG_COUNT]: args.length,
1405
+ [ARGUMENTS]: args.map(toArgType).flat(1),
1406
+ [RETURNS]: toTypeCodes(returns[VALUE])
1407
+ }
1408
+ }
1409
+ }
1410
+ return out
1411
+ }
1412
+ export const withCtxTypes = (T) => ({ ...SPECIAL_FORM_TYPES, ...T })
1413
+ export const filteredDefinedTypes = (program, lib, libT) => {
1414
+ const deps = new Set(shakedList(program, lib))
1415
+ return libT.filter((x) => deps.has(x[1][1]))
1416
+ }
1417
+ export const definedTypes = (T) => fromSourceToType(T)
package/src/utils.js CHANGED
@@ -175,10 +175,13 @@ const isDefinition = (x) =>
175
175
  x[TYPE] === APPLY && x[VALUE] === KEYWORDS.DEFINE_VARIABLE
176
176
  // [[, [, libs]]] is because std is wrapped in (apply (lambda (do ...)))
177
177
  const toDeps = ([[, [, libs]]]) =>
178
- libs.reduce(
179
- (a, x, i) => a.set(x.at(1)[VALUE], { value: x, index: i }),
180
- new Map()
181
- )
178
+ // slice 1 so we get rid of do
179
+ libs
180
+ .slice(1)
181
+ .reduce(
182
+ (a, x, i) => a.set(x.at(1)[VALUE], { value: x, index: i }),
183
+ new Map()
184
+ )
182
185
  const deepShake = (tree, deps, visited = new Set(), ignored = new Set()) => {
183
186
  const type = tree[TYPE]
184
187
  const value = tree[VALUE]