fez-lisp 1.6.25 → 1.6.27

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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { evaluate } from './src/evaluator.js'
2
2
  import { compile } from './src/compiler.js'
3
- import { parse, fez, UTILS } from './src/utils.js'
3
+ import { parse, fez, UTILS, atst } from './src/utils.js'
4
4
  import { LISP, AST } from './src/parser.js'
5
5
  import { type } from './src/check.js'
6
6
  import { enhance } from './src/enhance.js'
7
- export { parse, evaluate, compile, type, enhance, fez, LISP, AST, UTILS }
7
+ export { parse, evaluate, compile, type, atst, enhance, fez, LISP, AST, UTILS }
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.25",
5
+ "version": "1.6.27",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  VALUE,
17
17
  WORD
18
18
  } from './keywords.js'
19
- import { isLeaf, LISP } from './parser.js'
19
+ import { isLeaf } from './parser.js'
20
20
  import {
21
21
  SPECIAL_FORM_TYPES,
22
22
  toTypeNames,
@@ -91,6 +91,9 @@ export const identity = (name) => [
91
91
  [1, 'x']
92
92
  ]
93
93
  ]
94
+ export const typeSetDefaultFunction = (Types, name, env, exp) =>
95
+ Types.set(withScope(name, env), () => formatType(name, env))
96
+
94
97
  const returnType = (rest) => {
95
98
  const body = rest.at(-1)
96
99
  const rem = hasBlock(body) ? body.at(-1) : body
@@ -459,7 +462,7 @@ const getScopeNames = (scope) => {
459
462
  }
460
463
  return scopeNames.reverse()
461
464
  }
462
- const withScope = (name, scope) => {
465
+ export const withScope = (name, scope) => {
463
466
  const chain = getScopeNames(scope)
464
467
  return `${chain.join(' ')} ${name}`
465
468
  }
@@ -990,7 +993,11 @@ const checkReturnType = ({ exp, stack, name, env, check }) => {
990
993
  const stagger = (stack, method, data, fn) => {
991
994
  stack[method]({ data, fn })
992
995
  }
993
- export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
996
+ export const typeCheck = (
997
+ ast,
998
+ ctx = SPECIAL_FORM_TYPES,
999
+ typeSet = typeSetDefaultFunction
1000
+ ) => {
994
1001
  const Types = new Map()
995
1002
  const stack = new Brr()
996
1003
  const rootScopeIndex = 1
@@ -1204,7 +1211,8 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
1204
1211
  )})`
1205
1212
  )
1206
1213
  if (name in env) {
1207
- Types.set(withScope(name, env), () => formatType(name, env))
1214
+ typeSet(Types, name, env, exp)
1215
+ // Types.set(withScope(name, env), () => formatType(name, env))
1208
1216
  // If current scope is root then these are user defined types
1209
1217
  if (env[SCOPE_NAME] === rootScopeIndex) break
1210
1218
  }
@@ -1344,7 +1352,8 @@ export const typeCheck = (ast, ctx = SPECIAL_FORM_TYPES) => {
1344
1352
  }
1345
1353
  check(rightHand, env, scope)
1346
1354
  }
1347
- Types.set(withScope(name, env), () => formatType(name, env))
1355
+ typeSet(Types, name, env, exp)
1356
+ // Types.set(withScope(name, env), () => formatType(name, env))
1348
1357
  break
1349
1358
  case KEYWORDS.ANONYMOUS_FUNCTION:
1350
1359
  {
package/src/keywords.js CHANGED
@@ -3,6 +3,7 @@ export const VALUE = 1
3
3
  export const APPLY = 0
4
4
  export const WORD = 1
5
5
  export const ATOM = 2
6
+ export const FLAG = 3
6
7
  export const TRUE = 1
7
8
  export const FALSE = 0
8
9
  export const PLACEHOLDER = '.'
package/src/types.js CHANGED
@@ -5,11 +5,13 @@ import {
5
5
  APPLY,
6
6
  ATOM,
7
7
  DEBUG,
8
+ FLAG,
8
9
  KEYWORDS,
9
10
  PLACEHOLDER,
10
11
  STATIC_TYPES,
11
12
  TYPE,
12
- VALUE
13
+ VALUE,
14
+ WORD
13
15
  } from './keywords.js'
14
16
  import { isLeaf } from './parser.js'
15
17
  import { shakedList, stringifyArgs } from './utils.js'
@@ -1368,7 +1370,72 @@ export const formatType = (name, env) => {
1368
1370
  : `(let ${name} ${formatSubType(getTypes(stats))})`
1369
1371
  : name
1370
1372
  }
1371
-
1373
+ export const formatInlineType = (name, env) => {
1374
+ const stats = env[name][STATS]
1375
+ return stats
1376
+ ? getType(stats) === APPLY
1377
+ ? `(lambda ${
1378
+ stats[ARG_COUNT] === VARIADIC
1379
+ ? '... '
1380
+ : stats[ARGUMENTS]?.length
1381
+ ? stats[ARGUMENTS].map(
1382
+ (x, i) =>
1383
+ `${
1384
+ getType(x[STATS]) === APPLY
1385
+ ? `${formatType(i, stats[ARGUMENTS])}`
1386
+ : `${formatSubType(getTypes(x[STATS]))}`
1387
+ }`
1388
+ ).join(' ') + ' '
1389
+ : ''
1390
+ // TODO format returned functions when type support is added
1391
+ }(${KEYWORDS.BLOCK} ${formatSubType(getReturns(stats))}))`
1392
+ : formatSubType(getTypes(stats))
1393
+ : name
1394
+ }
1395
+ export const formatAstSubType = (T) => {
1396
+ switch (T[0]) {
1397
+ case COLLECTION:
1398
+ return `${
1399
+ T[1] instanceof Set
1400
+ ? [...T[1]]
1401
+ .map((x) =>
1402
+ x === COLLECTION
1403
+ ? formatAstSubType([x])
1404
+ : toTypeNamesAnyToUknown(x)
1405
+ )
1406
+ .join(' ') || toTypeNames(UNKNOWN)
1407
+ : toTypeNames(UNKNOWN)
1408
+ }[]`
1409
+ case ATOM:
1410
+ return `${
1411
+ T[1] instanceof Set
1412
+ ? [...T[1]].map((x) => toTypeNamesAnyToUknown(x)).join(' ')
1413
+ : toTypeNamesAnyToUknown(NUMBER)
1414
+ }`
1415
+ default:
1416
+ return toTypeNamesAnyToUknown(T[0])
1417
+ }
1418
+ }
1419
+ export const formatAstTypes = (name, env) => {
1420
+ const stats = env[name][STATS]
1421
+ return stats
1422
+ ? getType(stats) === APPLY
1423
+ ? [
1424
+ FLAG,
1425
+ ...(stats[ARG_COUNT] === VARIADIC
1426
+ ? []
1427
+ : stats[ARGUMENTS]?.length
1428
+ ? stats[ARGUMENTS].map((x, i) =>
1429
+ getType(x[STATS]) === APPLY
1430
+ ? formatAstTypes(i, stats[ARGUMENTS])
1431
+ : formatAstSubType(getTypes(x[STATS]))
1432
+ )
1433
+ : []),
1434
+ formatAstSubType(getReturns(stats))
1435
+ ]
1436
+ : [FLAG, formatAstSubType(getTypes(stats))]
1437
+ : [FLAG, name]
1438
+ }
1372
1439
  export const validateLambda = (exp, name) => {
1373
1440
  if (exp.length === 1)
1374
1441
  throw new TypeError(
package/src/utils.js CHANGED
@@ -2,6 +2,7 @@ import std from '../lib/baked/std.js'
2
2
  import {
3
3
  APPLY,
4
4
  ATOM,
5
+ FLAG,
5
6
  KEYWORDS,
6
7
  STATIC_TYPES,
7
8
  TYPE,
@@ -16,9 +17,14 @@ import {
16
17
  handleUnbalancedQuotes
17
18
  } from './macros.js'
18
19
  import { enhance, OPTIMIZATIONS } from './enhance.js'
19
- import { type } from './check.js'
20
+ import { type, typeCheck, withScope } from './check.js'
20
21
  import stdT from '../lib/baked/std-T.js'
21
- import { definedTypes, withCtxTypes } from './types.js'
22
+ import {
23
+ definedTypes,
24
+ filteredDefinedTypes,
25
+ formatAstTypes,
26
+ withCtxTypes
27
+ } from './types.js'
22
28
  import { compile } from './compiler.js'
23
29
  export const logError = (error) =>
24
30
  console.log('\x1b[31m', `\n${error}\n`, '\x1b[0m')
@@ -520,3 +526,32 @@ export const fez = (ast, c = false) => {
520
526
  return [null, err]
521
527
  }
522
528
  }
529
+
530
+ export const toTypedAst = (ast, userDefinedTypes) => {
531
+ try {
532
+ const types = typeCheck(
533
+ ast,
534
+ withCtxTypes(
535
+ userDefinedTypes
536
+ ? {
537
+ ...definedTypes(filteredDefinedTypes(ast, std, stdT)),
538
+ ...definedTypes(LISP.parse(removeNoCode(userDefinedTypes)))
539
+ }
540
+ : definedTypes(filteredDefinedTypes(ast, std, stdT))
541
+ ),
542
+ (Types, name, env, exp) => {
543
+ Types.set(withScope(name, env), () => {
544
+ if (exp.at(-1)[TYPE] !== FLAG) exp.push(formatAstTypes(name, env))
545
+ else exp[exp.length - 1] = formatAstTypes(name, env)
546
+ return ''
547
+ })
548
+ }
549
+ )
550
+ for (const v of types[1].values()) v()
551
+ // types[0][1][1].slice(1)
552
+ return types
553
+ } catch (error) {
554
+ logError(error.message)
555
+ }
556
+ }
557
+ export const atst = (ast, ctx) => toTypedAst(ast, ctx)[0]