fez-lisp 1.2.48 → 1.2.50

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.48",
5
+ "version": "1.2.50",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/compiler.js CHANGED
@@ -5,7 +5,8 @@ import {
5
5
  KEYWORDS,
6
6
  TYPE,
7
7
  VALUE,
8
- WORD
8
+ WORD,
9
+ SUGGAR
9
10
  } from './keywords.js'
10
11
  import { leaf, isLeaf } from './parser.js'
11
12
  const deepRenameTco = (name, newName, tree) => {
@@ -176,9 +177,9 @@ const compile = (tree, Drill) => {
176
177
  case KEYWORDS.DEFINE_VARIABLE: {
177
178
  const n = Arguments[0][VALUE]
178
179
  const prefix = n.split(':')[0]
179
- if (prefix === KEYWORDS.RECURSION) {
180
+ if (prefix === SUGGAR.RECURSION) {
180
181
  const name = lispToJavaScriptVariableName(n)
181
- const newName = `recursive_${performance
182
+ const newName = `${SUGGAR.RECURSION}_${performance
182
183
  .now()
183
184
  .toString()
184
185
  .replace('.', 7)}`
@@ -199,10 +200,10 @@ const compile = (tree, Drill) => {
199
200
  )})=>{${vars}return ${evaluatedBody
200
201
  .toString()
201
202
  .trim()}}, ${newName})));`
202
- } else if (prefix === KEYWORDS.CACHE) {
203
+ } else if (prefix === SUGGAR.CACHE) {
203
204
  // memoization here
204
205
  const name = lispToJavaScriptVariableName(n)
205
- const newName = name.substring(KEYWORDS.CACHE.length + 1)
206
+ const newName = name.substring(SUGGAR.CACHE.length + 1)
206
207
  Drill.Variables.add(name)
207
208
  const functionArgs = Arguments.at(-1).slice(1)
208
209
  const body = functionArgs.pop()
@@ -651,29 +651,6 @@ export const keywords = {
651
651
  )
652
652
  return operands.reduce((acc, x) => acc >>> x)
653
653
  },
654
- // [KEYWORDS.PIPE]: (args, env) => {
655
- // if (args.length < 1)
656
- // throw new RangeError(
657
- // `Invalid number of arguments to (${KEYWORDS.PIPE}) (>= 1 required). (${
658
- // KEYWORDS.PIPE
659
- // } ${stringifyArgs(args)})`
660
- // )
661
- // let inp = args[0]
662
- // for (let i = 1; i < args.length; ++i) {
663
- // if (!args[i].length || args[i][0][TYPE] !== APPLY)
664
- // throw new TypeError(
665
- // `Argument at position (${i}) of (${
666
- // KEYWORDS.PIPE
667
- // }) is not an invoked (${KEYWORDS.ANONYMOUS_FUNCTION}). (${
668
- // KEYWORDS.PIPE
669
- // } ${stringifyArgs(args)})`
670
- // )
671
- // const [first, ...rest] = args[i]
672
- // const arr = [first, inp, ...rest]
673
- // inp = arr
674
- // }
675
- // return evaluate(inp, env)
676
- // },
677
654
  [KEYWORDS.SET_ARRAY]: (args, env) => {
678
655
  if (args.length !== 1 && args.length !== 3)
679
656
  throw new RangeError(
package/src/keywords.js CHANGED
@@ -6,6 +6,19 @@ export const ATOM = 2
6
6
  export const TRUE = 1
7
7
  export const FALSE = 0
8
8
  export const PLACEHOLDER = '.'
9
+ export const SUGGAR = {
10
+ // Syntactic suggars
11
+ PIPE: '|>',
12
+ NOT_EQUAL_1: '!=',
13
+ NOT_EQUAL_2: '<>',
14
+ UNLESS: 'unless',
15
+ LIST_TYPE: 'list',
16
+ POWER: '**',
17
+ INTEGER_DEVISION: '//',
18
+
19
+ RECURSION: 'recursive',
20
+ CACHE: 'memoized'
21
+ }
9
22
  export const KEYWORDS = {
10
23
  NUMBER_TYPE: 'number',
11
24
  ARRAY_TYPE: 'array',
@@ -49,17 +62,7 @@ export const KEYWORDS = {
49
62
  LOG_CHAR: 'log-char!',
50
63
  CLEAR_CONSOLE: 'clear!',
51
64
 
52
- THROW: 'throw',
53
-
54
- // Syntactic suggars
55
- PIPE: '|>',
56
- NOT_EQUAL_1: '!=',
57
- NOT_EQUAL_2: '<>',
58
- UNLESS: 'unless',
59
- LIST_TYPE: 'list',
60
-
61
- RECURSION: 'recursive',
62
- CACHE: 'memoized'
65
+ THROW: 'throw'
63
66
  }
64
67
 
65
68
  export const TYPES = {
package/src/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import std from '../lib/baked/std.js'
2
2
  import { comp } from './compiler.js'
3
- import { APPLY, ATOM, KEYWORDS, TYPE, VALUE, WORD } from './keywords.js'
3
+ import { APPLY, ATOM, KEYWORDS, SUGGAR, TYPE, VALUE, WORD } from './keywords.js'
4
4
  import { evaluate, run } from './evaluator.js'
5
5
  import { AST, isLeaf, LISP } from './parser.js'
6
6
  export const logError = (error) =>
@@ -102,8 +102,8 @@ export const isForbiddenVariableName = (name) => {
102
102
  switch (name) {
103
103
  case '_':
104
104
  case KEYWORDS.DEFINE_VARIABLE:
105
- case KEYWORDS.RECURSION:
106
- case KEYWORDS.CACHE:
105
+ case SUGGAR.RECURSION:
106
+ case SUGGAR.CACHE:
107
107
  return true
108
108
  default:
109
109
  return !isNaN(name[0])
@@ -410,13 +410,13 @@ export const deSuggar = (ast) => {
410
410
  // }
411
411
  // }
412
412
  // break
413
- case KEYWORDS.PIPE:
413
+ case SUGGAR.PIPE:
414
414
  {
415
415
  if (rest.length < 1)
416
416
  throw new RangeError(
417
417
  `Invalid number of arguments to (${
418
- KEYWORDS.PIPE
419
- }) (>= 1 required). (${KEYWORDS.PIPE} ${stringifyArgs(
418
+ SUGGAR.PIPE
419
+ }) (>= 1 required). (${SUGGAR.PIPE} ${stringifyArgs(
420
420
  rest
421
421
  )})`
422
422
  )
@@ -426,10 +426,10 @@ export const deSuggar = (ast) => {
426
426
  if (!rest[i].length || rest[i][0][TYPE] !== APPLY)
427
427
  throw new TypeError(
428
428
  `Argument at position (${i}) of (${
429
- KEYWORDS.PIPE
429
+ SUGGAR.PIPE
430
430
  }) is not an invoked (${
431
431
  KEYWORDS.ANONYMOUS_FUNCTION
432
- }). (${KEYWORDS.PIPE} ${stringifyArgs(rest)})`
432
+ }). (${SUGGAR.PIPE} ${stringifyArgs(rest)})`
433
433
  )
434
434
  inp = [rest[i].shift(), inp, ...rest[i]]
435
435
  }
@@ -437,7 +437,7 @@ export const deSuggar = (ast) => {
437
437
  deSuggar(exp)
438
438
  }
439
439
  break
440
- case KEYWORDS.LIST_TYPE:
440
+ case SUGGAR.LIST_TYPE:
441
441
  {
442
442
  exp.length = 0
443
443
  let temp = exp
@@ -449,6 +449,58 @@ export const deSuggar = (ast) => {
449
449
  deSuggar(exp)
450
450
  }
451
451
  break
452
+ case SUGGAR.INTEGER_DEVISION:
453
+ {
454
+ if (rest.some((x) => x[TYPE] === APPLY))
455
+ throw new TypeError(
456
+ `Arguments of (${
457
+ SUGGAR.INTEGER_DEVISION
458
+ }), must be (or atom word) (hint use (math:floor (${
459
+ KEYWORDS.DIVISION
460
+ } a b)) instead) (${
461
+ SUGGAR.INTEGER_DEVISION
462
+ } ${stringifyArgs(rest)})`
463
+ )
464
+ else {
465
+ exp.length = 1
466
+ exp[0] = [APPLY, KEYWORDS.BITWISE_OR]
467
+ exp.push([[APPLY, KEYWORDS.DIVISION], ...rest])
468
+ exp.push([ATOM, 0])
469
+ }
470
+ }
471
+ break
472
+ case SUGGAR.POWER:
473
+ {
474
+ if (rest.length !== 2)
475
+ throw new RangeError(
476
+ `Invalid number of arguments for (${
477
+ SUGGAR.POWER
478
+ }), expected (= 2) but got ${rest.length} (${
479
+ SUGGAR.POWER
480
+ } ${stringifyArgs(rest)})`
481
+ )
482
+ if (
483
+ (exp[2][TYPE] === ATOM || exp[2][TYPE] === WORD) &&
484
+ (exp[1][TYPE] === WORD || exp[1][TYPE] === ATOM)
485
+ ) {
486
+ exp[0][VALUE] = KEYWORDS.MULTIPLICATION
487
+ const exponent = exp[1]
488
+ const power = exp[2][VALUE]
489
+ exp.length = 1
490
+ const right = Array.from({ length: power })
491
+ .fill(0)
492
+ .map(() => [exponent[TYPE], exponent[VALUE]])
493
+ exp.push(...right)
494
+ } else
495
+ throw new TypeError(
496
+ `ArgumentS of (${
497
+ SUGGAR.POWER
498
+ }), must be (or atom word) (hint use math:power instead) (${
499
+ SUGGAR.POWER
500
+ } ${stringifyArgs(rest)})`
501
+ )
502
+ }
503
+ break
452
504
  case KEYWORDS.MULTIPLICATION:
453
505
  if (!rest.length) {
454
506
  exp[0][0] = 2
@@ -462,14 +514,14 @@ export const deSuggar = (ast) => {
462
514
  exp[0][1] = 0
463
515
  }
464
516
  break
465
- case KEYWORDS.UNLESS:
517
+ case SUGGAR.UNLESS:
466
518
  {
467
519
  if (rest.length > 3 || rest.length < 2)
468
520
  throw new RangeError(
469
521
  `Invalid number of arguments for (${
470
- KEYWORDS.UNLESS
522
+ SUGGAR.UNLESS
471
523
  }), expected (or (= 3) (= 2)) but got ${rest.length} (${
472
- KEYWORDS.UNLESS
524
+ SUGGAR.UNLESS
473
525
  } ${stringifyArgs(rest)})`
474
526
  )
475
527
  exp[0][1] = KEYWORDS.IF
@@ -480,8 +532,8 @@ export const deSuggar = (ast) => {
480
532
  deSuggar(exp)
481
533
  break
482
534
 
483
- case KEYWORDS.NOT_EQUAL_1:
484
- case KEYWORDS.NOT_EQUAL_2:
535
+ case SUGGAR.NOT_EQUAL_1:
536
+ case SUGGAR.NOT_EQUAL_2:
485
537
  {
486
538
  if (rest.length > 3 || rest.length < 2)
487
539
  throw new RangeError(