fez-lisp 1.2.34 → 1.2.35

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.34",
5
+ "version": "1.2.35",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/compiler.js CHANGED
@@ -109,7 +109,8 @@ const Helpers = {
109
109
  __tco: `__tco=fn=>(...args)=>{let result=fn(...args);while(typeof result==='function')result=result();return result}`,
110
110
  atom_predicate: `atom_predicate=(number)=>+(typeof number==='number')`,
111
111
  lambda_predicate: `lambda_predicate=(fm)=>+(typeof fn==='function')`,
112
- set_effect: `set_effect=(array,index,value)=>{if(index<0){const target=array.length+index;while(array.length!==target)array.pop()}else array[index] = value;return array}`
112
+ set_effect: `set_effect=(array,index,value)=>{if(index<0){const target=array.length+index;while(array.length!==target)array.pop()}else array[index] = value;return array}`,
113
+ __error: `__error=(error)=>{throw new Error(error.map((x)=>String.fromCharCode(x)).join(''))}`
113
114
  }
114
115
  const semiColumnEdgeCases = new Set([
115
116
  ';)',
@@ -141,6 +142,8 @@ const compile = (tree, Drill) => {
141
142
  const token = first[VALUE]
142
143
  if (first[TYPE] === APPLY) {
143
144
  switch (token) {
145
+ case KEYWORDS.ASSERT:
146
+ return '0'
144
147
  case KEYWORDS.BLOCK: {
145
148
  if (Arguments.length > 1) {
146
149
  return `(${Arguments.map((x) =>
@@ -292,6 +295,10 @@ const compile = (tree, Drill) => {
292
295
  out += '0);'
293
296
  return out
294
297
  }
298
+ case KEYWORDS.THROW: {
299
+ Drill.Helpers.add('__error')
300
+ return `__error(${compile(Arguments[0], Drill)})`
301
+ }
295
302
  default: {
296
303
  const camelCased = lispToJavaScriptVariableName(token)
297
304
  if (camelCased in Helpers) Drill.Helpers.add(camelCased)
@@ -1,4 +1,13 @@
1
- import { TYPE, VALUE, WORD, KEYWORDS, FALSE, TRUE, TYPES } from './keywords.js'
1
+ import {
2
+ TYPE,
3
+ VALUE,
4
+ WORD,
5
+ KEYWORDS,
6
+ FALSE,
7
+ TRUE,
8
+ TYPES,
9
+ APPLY
10
+ } from './keywords.js'
2
11
  import { evaluate } from './evaluator.js'
3
12
  import { isForbiddenVariableName, stringifyArgs } from './utils.js'
4
13
  const keywords = {
@@ -161,7 +170,9 @@ const keywords = {
161
170
  const condition = evaluate(args[0], env)
162
171
  if (condition !== FALSE && condition !== TRUE)
163
172
  throw new TypeError(
164
- `Condition of (${KEYWORDS.IF}) must be ${TRUE} or ${FALSE} but got ${condition}`
173
+ `Condition of (${KEYWORDS.IF}) must be ${TRUE} or ${FALSE} but got (${
174
+ KEYWORDS.IF
175
+ } ${stringifyArgs(args)})`
165
176
  )
166
177
  return condition
167
178
  ? evaluate(args[1], env)
@@ -190,7 +201,11 @@ const keywords = {
190
201
  const condition = evaluate(args[i], env)
191
202
  if (condition !== FALSE && condition !== TRUE)
192
203
  throw new TypeError(
193
- `Condition of (${KEYWORDS.CONDITION}) must be ${TRUE} or ${FALSE} but got ${condition}`
204
+ `Condition of (${
205
+ KEYWORDS.CONDITION
206
+ }) must be ${TRUE} or ${FALSE} but got (${
207
+ KEYWORDS.CONDITION
208
+ } ${stringifyArgs(args)})`
194
209
  )
195
210
  if (condition) return evaluate(args[i + 1], env)
196
211
  }
@@ -426,7 +441,11 @@ const keywords = {
426
441
  circuit = evaluate(args[i], env)
427
442
  if (circuit !== FALSE && circuit !== TRUE)
428
443
  throw new TypeError(
429
- `Condition of (${KEYWORDS.AND}) must be ${TRUE} or ${FALSE} but got ${circuit}`
444
+ `Condition of (${
445
+ KEYWORDS.AND
446
+ }) must be ${TRUE} or ${FALSE} but got (${
447
+ KEYWORDS.AND
448
+ } ${stringifyArgs(args)})`
430
449
  )
431
450
  if (circuit) continue
432
451
  else return 0
@@ -434,7 +453,9 @@ const keywords = {
434
453
  const end = evaluate(args.at(-1), env)
435
454
  if (end !== FALSE && end !== TRUE)
436
455
  throw new TypeError(
437
- `Condition of (${KEYWORDS.AND}) must be ${TRUE} or ${FALSE} but got ${end}`
456
+ `Condition of (${KEYWORDS.AND}) must be ${TRUE} or ${FALSE} but got (${
457
+ KEYWORDS.AND
458
+ } ${stringifyArgs(args)})`
438
459
  )
439
460
  return end
440
461
  },
@@ -450,7 +471,9 @@ const keywords = {
450
471
  circuit = evaluate(args[i], env)
451
472
  if (circuit !== FALSE && circuit !== TRUE)
452
473
  throw new TypeError(
453
- `Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got ${circuit}`
474
+ `Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got (${
475
+ KEYWORDS.OR
476
+ } ${stringifyArgs(args)})`
454
477
  )
455
478
  if (circuit) return 1
456
479
  else continue
@@ -458,7 +481,9 @@ const keywords = {
458
481
  const end = evaluate(args.at(-1), env)
459
482
  if (end !== FALSE && end !== TRUE)
460
483
  throw new TypeError(
461
- `Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got ${end}`
484
+ `Condition of (${KEYWORDS.OR}) must be ${TRUE} or ${FALSE} but got (${
485
+ KEYWORDS.OR
486
+ } ${stringifyArgs(args)})`
462
487
  )
463
488
  return end
464
489
  },
@@ -784,6 +809,66 @@ const keywords = {
784
809
  )
785
810
  console.clear()
786
811
  return 0
812
+ },
813
+
814
+ // Not sure about these
815
+ [KEYWORDS.THROW]: (args, env) => {
816
+ if (args.length !== 1)
817
+ throw new RangeError(
818
+ `Invalid number of arguments to (${KEYWORDS.THROW}) (= 1 required) (${
819
+ KEYWORDS.THROW
820
+ } ${stringifyArgs(args)})`
821
+ )
822
+ const expression = evaluate(args[0], env)
823
+ if (!Array.isArray(expression))
824
+ throw new TypeError(
825
+ `Argument of (${KEYWORDS.THROW}) must be an (${
826
+ KEYWORDS.ARRAY_TYPE
827
+ }) but got (${expression}) (${KEYWORDS.THROW} ${stringifyArgs(args)})`
828
+ )
829
+ throw new Error(expression.map((x) => String.fromCharCode(x)).join(''))
830
+ },
831
+
832
+ [KEYWORDS.ASSERT]: (args, env) => {
833
+ if (args.length < 2)
834
+ throw new RangeError(
835
+ `Invalid number of arguments for (${
836
+ KEYWORDS.ASSERT
837
+ }), expected (> 2 required) but got ${args.length} (${
838
+ KEYWORDS.ASSERT
839
+ } ${stringifyArgs(args)})`
840
+ )
841
+ if (args.length % 2 !== 0)
842
+ throw new RangeError(
843
+ `Invalid number of arguments for (${
844
+ KEYWORDS.ASSERT
845
+ }), expected even number of arguments but got ${args.length} (${
846
+ KEYWORDS.ASSERT
847
+ } ${stringifyArgs(args)})`
848
+ )
849
+ for (let i = 0; i < args.length; i += 2) {
850
+ const condition = evaluate(args[i], env)
851
+ if (condition !== FALSE && condition !== TRUE)
852
+ throw new TypeError(
853
+ `Condition of (${
854
+ KEYWORDS.ASSERT
855
+ }) must be ${TRUE} or ${FALSE} but got (${
856
+ KEYWORDS.ASSERT
857
+ } ${stringifyArgs(args)})`
858
+ )
859
+ if (condition) {
860
+ const error = args[i + 1]
861
+ if (error[0][TYPE] === APPLY && error[0][VALUE] === KEYWORDS.THROW)
862
+ return evaluate(error, env)
863
+ else
864
+ throw new TypeError(
865
+ `Concequence of (${KEYWORDS.ASSERT}) must be (${
866
+ KEYWORDS.THROW
867
+ }) but got (${KEYWORDS.ASSERT} ${stringifyArgs(args)})`
868
+ )
869
+ }
870
+ }
871
+ return 0
787
872
  }
788
873
  }
789
874
 
package/src/keywords.js CHANGED
@@ -49,6 +49,9 @@ export const KEYWORDS = {
49
49
  LOG_CHAR: 'log-char!',
50
50
  CLEAR_CONSOLE: 'clear!',
51
51
 
52
+ THROW: 'throw',
53
+ ASSERT: 'assert',
54
+
52
55
  // Syntactic suggars
53
56
  PIPE: '|>',
54
57
  NOT_EQUAL_1: '!=',