fez-lisp 1.2.10 → 1.2.12

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.2.10",
5
+ "version": "1.2.12",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/compiler.js CHANGED
@@ -107,6 +107,7 @@ const Helpers = {
107
107
  length: 'length=(arr)=>arr.length',
108
108
  __tco: `__tco=fn=>(...args)=>{let result=fn(...args);while(typeof result==='function')result=result();return result}`,
109
109
  atomPredicate: `atomPredicate=(number)=>+(typeof number==='number')`,
110
+ lambdaPredicate: `lambdaPredicate=(fm)=>+(typeof fn==='function')`,
110
111
  setEffect: `setEffect=(array,index,value)=>{if(index<0){const target=array.length+index;while(array.length!==target)array.pop()}else array[index] = value;return array}`
111
112
  }
112
113
  const semiColumnEdgeCases = new Set([
@@ -144,7 +145,7 @@ const compile = (tree, Drill) => {
144
145
  return `(${Arguments.map((x) =>
145
146
  (compile(x, Drill) ?? '').toString().trim()
146
147
  )
147
- .filter(Boolean)
148
+ .filter((x) => x !== undefined)
148
149
  .join(',')});`
149
150
  } else {
150
151
  const res = compile(Arguments[0], Drill)
@@ -191,6 +192,9 @@ const compile = (tree, Drill) => {
191
192
  case KEYWORDS.IS_ATOM:
192
193
  Drill.Helpers.add('atomPredicate')
193
194
  return `atomPredicate(${compile(Arguments[0], Drill)});`
195
+ case KEYWORDS.IS_LAMBDA:
196
+ Drill.Helpers.add('lambdaPredicate')
197
+ return `lambdaPredicate(${compile(Arguments[0], Drill)});`
194
198
  case KEYWORDS.NUMBER_TYPE:
195
199
  return '0'
196
200
  case KEYWORDS.BOOLEAN_TYPE:
@@ -311,7 +315,7 @@ export const comp = (ast) => {
311
315
  const Drill = { Variables: new Set(), Helpers: new Set() }
312
316
  const raw = ast
313
317
  .map((tree) => compile(tree, Drill))
314
- .filter(Boolean)
318
+ .filter((x) => x !== undefined)
315
319
  .join('\n')
316
320
  let program = ''
317
321
  for (let i = 0; i < raw.length; ++i) {
@@ -101,6 +101,15 @@ const keywords = {
101
101
  )
102
102
  return +(typeof evaluate(args[0], env) === 'number')
103
103
  },
104
+ [KEYWORDS.IS_LAMBDA]: (args, env) => {
105
+ if (args.length !== 1)
106
+ throw new RangeError(
107
+ `Invalid number of arguments for (${
108
+ KEYWORDS.IS_LAMBDA
109
+ }) (= 1 required) (${KEYWORDS.IS_LAMBDA} ${stringifyArgs(args)})`
110
+ )
111
+ return +(typeof evaluate(args[0], env) === 'function')
112
+ },
104
113
  [KEYWORDS.ADDITION]: (args, env) => {
105
114
  if (args.length < 2)
106
115
  throw new RangeError(
@@ -180,6 +189,14 @@ const keywords = {
180
189
  KEYWORDS.CONDITION
181
190
  } ${stringifyArgs(args)})`
182
191
  )
192
+ if (args.length % 2 !== 0)
193
+ throw new RangeError(
194
+ `Invalid number of arguments for (${
195
+ KEYWORDS.CONDITION
196
+ }), expected even number of arguments but got ${args.length} (${
197
+ KEYWORDS.CONDITION
198
+ } ${stringifyArgs(args)})`
199
+ )
183
200
  for (let i = 0; i < args.length; i += 2) {
184
201
  const condition = evaluate(args[i], env)
185
202
  if (condition !== FALSE && condition !== TRUE)
package/src/keywords.js CHANGED
@@ -14,6 +14,7 @@ export const KEYWORDS = {
14
14
  IDENTITY: 'identity',
15
15
  ARRAY_LENGTH: 'length',
16
16
  IS_ATOM: 'atom?',
17
+ IS_LAMBDA: 'lambda?',
17
18
  ADDITION: '+',
18
19
  SUBTRACTION: '-',
19
20
  MULTIPLICATION: '*',
@@ -54,7 +55,6 @@ export const KEYWORDS = {
54
55
  CLEAR_CONSOLE: 'clear!'
55
56
  }
56
57
 
57
-
58
58
  export const TYPES = {
59
59
  [APPLY]: 'APPLY',
60
60
  [WORD]: 'WORD',