fez-lisp 1.6.59 → 1.6.61

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.59",
5
+ "version": "1.6.61",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/check.js CHANGED
@@ -56,7 +56,9 @@ import {
56
56
  hasBlock,
57
57
  log,
58
58
  logExp,
59
- stringifyArgs
59
+ stringifyArgs,
60
+ wrapInApplyLambda,
61
+ wrapInBlock
60
62
  } from './utils.js'
61
63
 
62
64
  export const identity = (name) => [
@@ -603,10 +605,9 @@ const resolveCondition = ({ rem, name, env, exp, prop, stack, check }) => {
603
605
  const resolveGetter = ({ rem, prop, name, env }) => {
604
606
  const array = isLeaf(rem[1]) ? rem[1] : rem[1][0]
605
607
  if (!env[array[VALUE]] || !env[name]) return true
606
-
607
608
  switch (array[TYPE]) {
608
609
  case APPLY:
609
- if (hasSubType(env[array[VALUE]][STATS])) {
610
+ if (hasSubReturn(env[array[VALUE]][STATS])) {
610
611
  const rightSub = getSubReturn(env[array[VALUE]][STATS])
611
612
  const isAtom = rightSub.has(NUMBER) || rightSub.has(BOOLEAN)
612
613
  const isCollection = rightSub.has(COLLECTION)
@@ -614,12 +615,12 @@ const resolveGetter = ({ rem, prop, name, env }) => {
614
615
  setPropToAtom(env[name][STATS], prop)
615
616
  setPropToSubReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
616
617
  } else if (!isAtom && isCollection) {
617
- setPropToReturn(env[name][STATS], prop, env[array[VALUE]][STATS])
618
- // TODO: handle this nested array overwrite better
619
- if (getSubReturn(env[array[VALUE]][STATS]).has(COLLECTION))
620
- setPropToSubReturn(env[name][STATS], prop, {
621
- [RETURNS]: [COLLECTION, UNKNOWN_SUBTYPE()]
622
- })
618
+ setPropToReturn(env[name][STATS], prop, {
619
+ [RETURNS]: [
620
+ env[array[VALUE]][STATS][RETURNS][1].types[0],
621
+ new SubType(env[array[VALUE]][STATS][RETURNS][1].types.slice(1))
622
+ ]
623
+ })
623
624
  } else return false
624
625
  } else return false
625
626
  break
@@ -713,10 +714,12 @@ const resolveSetter = (first, rest, env, stack) => {
713
714
  case APPLY:
714
715
  if (env[right[VALUE]]) {
715
716
  if (right[VALUE] === KEYWORDS.CREATE_ARRAY) {
716
- current[STATS][TYPE_PROP][1] = initArrayType({
717
+ const inner = initArrayType({
717
718
  rem: rest.at(-1),
718
719
  env
719
720
  })[RETURNS][1]
721
+ current[STATS][TYPE_PROP][0] = COLLECTION
722
+ if (!inner.has(UNKNOWN)) current[STATS][TYPE_PROP][1] = inner
720
723
  break
721
724
  }
722
725
  if (hasSubReturn(env[right[VALUE]][STATS])) {
@@ -782,7 +785,6 @@ const initArrayTypeRec = ({ rem, env }) => {
782
785
  const initArrayType = ({ rem, env }) => {
783
786
  const ret = initArrayTypeRec({ rem, env })
784
787
  const known = ret.find((x) => x[0] !== ANY && x[0] !== UNKNOWN)
785
- // console.log(known[0], ret[0])
786
788
  if (known && ret.length) {
787
789
  if (Array.isArray(ret[0][0])) {
788
790
  let head = ret[0][0]
@@ -796,6 +798,7 @@ const initArrayType = ({ rem, env }) => {
796
798
  if (head) subT.add(head[1].types[0])
797
799
  }
798
800
  const [main, sub] = ret[0]
801
+ if (isSubType(sub) && sub.types.at(-1) === COLLECTION) sub.types.pop()
799
802
  return {
800
803
  [TYPE_PROP]: [APPLY],
801
804
  [RETURNS]: [COLLECTION, new SubType(isSubType(sub) ? [...sub] : [main])]
@@ -1204,7 +1207,7 @@ export const typeCheck = (
1204
1207
  if (name in env) {
1205
1208
  // Types.set(withScope(name, env), () => formatType(name, env))
1206
1209
  // If current scope is root then these are user defined types
1207
- if (isLambda && !isUnknownReturn(env[name][STATS])) {
1210
+ if (isLambda) {
1208
1211
  const lambdaName = `${PLACEHOLDER}${name}`
1209
1212
  check(
1210
1213
  [
@@ -1259,6 +1262,26 @@ export const typeCheck = (
1259
1262
  }
1260
1263
  checkReturns()
1261
1264
  checkArgs()
1265
+ // Check lambda body with defined types
1266
+ const copy = Object.create(env)
1267
+ for (let i = 0; i < env[name][STATS][ARGUMENTS].length; ++i) {
1268
+ const A = env[lambdaName][STATS][ARGUMENTS][i]
1269
+ const B = env[name][STATS][ARGUMENTS][i]
1270
+ copy[A[STATS][SIGNATURE]] = {
1271
+ [STATS]: {
1272
+ [SIGNATURE]: A[STATS][SIGNATURE],
1273
+ [TYPE_PROP]: B[STATS][TYPE_PROP],
1274
+ [RETURNS]: B[STATS][RETURNS]
1275
+ }
1276
+ }
1277
+ }
1278
+ check(
1279
+ wrapInApplyLambda(exp.at(-1).slice(2)).at(-1),
1280
+ copy,
1281
+ scope
1282
+ )
1283
+ // console.log(exp.at(-1).slice(1))
1284
+ // check(exp.at(-1), env, scope)
1262
1285
  // Types.delete(`; ${rootScopeIndex} ${lambdaName}`)
1263
1286
  }
1264
1287
  typeSet(Types, name, env, exp)
package/src/keywords.js CHANGED
@@ -110,8 +110,8 @@ export const MUTATORS_SET = new Set([
110
110
  'array:set!',
111
111
  'push!',
112
112
  'array:append!',
113
- 'array:push!',
114
- 'var:set!'
113
+ 'array:push!'
114
+ // 'var:set!'
115
115
  ])
116
116
  export const GETTERS_SET = new Set([
117
117
  KEYWORDS.GET_ARRAY,
package/src/types.js CHANGED
@@ -91,49 +91,39 @@ export const toTypeNames = (type) => {
91
91
  return 'Atom'
92
92
  case NUMBER:
93
93
  return 'Number'
94
- // case ATOM:
95
- // return 'Atom'
96
94
  case UNKNOWN:
97
95
  return 'Unknown'
98
96
  case COLLECTION:
99
- // return 'Array'
100
97
  return 'Unknown[]'
101
98
  case ANY:
102
99
  return 'Any'
103
100
  default:
104
- break
101
+ return 'Unknown'
105
102
  }
106
103
  }
104
+
105
+ export const extractArrayType = (type) => {
106
+ const arr = [...type].filter((x) => x === '[')
107
+ return [type.split('[')[0], arr.length]
108
+ }
109
+ const fillArrayType = (n) => Array.from({ length: n - 1 }).fill(COLLECTION)
107
110
  export const toTypeCodes = (type) => {
108
- switch (type) {
111
+ const [t, n] = extractArrayType(type)
112
+ switch (t) {
109
113
  case 'Abstraction':
110
114
  return [APPLY]
111
115
  case 'Boolean':
116
+ if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(BOOLEAN))]
112
117
  return [ATOM, BOOLEAN_SUBTYPE()]
113
118
  case 'Atom':
119
+ if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(ATOM))]
114
120
  return [ATOM]
115
121
  case 'Number':
122
+ if (n) return [COLLECTION, new SubType(fillArrayType(n).concat(NUMBER))]
116
123
  return [ATOM, NUMBER_SUBTYPE()]
117
124
  case 'Unknown':
125
+ if (n) return [COLLECTION, new SubType(fillArrayType(n))]
118
126
  return [UNKNOWN]
119
- case 'Unknown[]':
120
- case 'Unknowns':
121
- // case 'Collection':
122
- return [COLLECTION, new SubType([ANY])]
123
- case 'Numbers':
124
- case 'Number[]':
125
- return [COLLECTION, NUMBER_SUBTYPE()]
126
- case 'Booleans':
127
- case 'Boolean[]':
128
- return [COLLECTION, BOOLEAN_SUBTYPE()]
129
- // case 'Collections':
130
- // case 'Collection[]':
131
- case 'Unknown[][]':
132
- return [COLLECTION, COLLECTION_SUBTYPE()]
133
- case 'Boolean[][]':
134
- return [COLLECTION, new SubType([COLLECTION, BOOLEAN])]
135
- case 'Number[][]':
136
- return [COLLECTION, new SubType([COLLECTION, NUMBER])]
137
127
  case 'Any':
138
128
  return [ANY]
139
129
  default:
package/src/utils.js CHANGED
@@ -304,6 +304,10 @@ export const wrapInBlock = (ast) => [
304
304
  [[APPLY, KEYWORDS.BLOCK], ...ast]
305
305
  ]
306
306
  ]
307
+ export const wrapInApplyLambda = (ast) => [
308
+ [APPLY, KEYWORDS.CALL_FUNCTION],
309
+ [[APPLY, KEYWORDS.ANONYMOUS_FUNCTION], ...ast]
310
+ ]
307
311
  export const interpret = (ast, keywords) =>
308
312
  ast.reduce((_, x) => evaluate(x, keywords), 0)
309
313
  export const shake = (parsed, std) => treeShake(parsed, std).concat(parsed)