fez-lisp 1.0.41 → 1.0.42

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.0.41",
5
+ "version": "1.0.42",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "keywords": [
package/src/parser.js CHANGED
@@ -1,5 +1,5 @@
1
- import { APPLY, ATOM, WORD } from './enums.js'
2
- import { escape } from './utils.js'
1
+ import { APPLY, ATOM, TYPE, WORD, VALUE } from './enums.js'
2
+ import { escape, preserveEscape } from './utils.js'
3
3
  export const leaf = (type, value) => [type, value]
4
4
  export const isLeaf = ([car]) => car === APPLY || car === ATOM || car === WORD
5
5
  export const LISP = {
@@ -39,21 +39,44 @@ export const LISP = {
39
39
  }
40
40
  return tree
41
41
  },
42
- stringify: (ast) => {
43
- if (ast == undefined) return '()'
44
- else if (typeof ast === 'object')
45
- if (Array.isArray(ast))
46
- return ast.length
47
- ? `(array ${ast.map(LISP.stringify).join(' ')})`
42
+ stringify: (array) => {
43
+ if (array == undefined) return '()'
44
+ else if (typeof array === 'object')
45
+ if (Array.isArray(array))
46
+ return array.length
47
+ ? `(array ${array.map(LISP.stringify).join(' ')})`
48
48
  : '()'
49
49
  else
50
- return `(array ${ast
50
+ return `(array ${array
51
51
  .map(([key, value]) => `("${key}" ${LISP.stringify(value)})`)
52
52
  .join(' ')})`
53
- else if (typeof ast === 'string') return `"${ast}"`
54
- else if (typeof ast === 'function') return '()'
55
- else if (typeof ast === 'boolean') return +ast
56
- else return ast
53
+ else if (typeof array === 'string') return `"${array}"`
54
+ else if (typeof array === 'function') return '()'
55
+ else if (typeof array === 'boolean') return +array
56
+ else return array
57
+ },
58
+ source: (ast) => {
59
+ const dfs = (exp) => {
60
+ let out = ''
61
+ const [first, ...rest] = isLeaf(exp) ? [exp] : exp
62
+ if (first == undefined) return (out += '()')
63
+ switch (first[TYPE]) {
64
+ case WORD:
65
+ out += first[VALUE]
66
+ break
67
+ case ATOM:
68
+ out +=
69
+ typeof first[VALUE] === 'string'
70
+ ? `"${preserveEscape(first[VALUE])}"`
71
+ : first[VALUE]
72
+ break
73
+ case APPLY:
74
+ out += `(${first[VALUE]} ${rest.map(dfs).join(' ')})`
75
+ break
76
+ }
77
+ return out
78
+ }
79
+ return ast.map(dfs).join(' ')
57
80
  }
58
81
  }
59
82
  export const AST = {
@@ -94,6 +117,6 @@ export const AST = {
94
117
  typeof ast === 'object'
95
118
  ? `[${ast.map(AST.stringify).join(',')}]`
96
119
  : typeof ast === 'string'
97
- ? `"${ast}"`
120
+ ? `"${preserveEscape(ast)}"`
98
121
  : ast
99
122
  }
package/src/utils.js CHANGED
@@ -39,6 +39,15 @@ export const escape = (Char) => {
39
39
  return ''
40
40
  }
41
41
  }
42
+ const escapeChars = {
43
+ '\n': '\\n',
44
+ '\r': '\\r',
45
+ '\t': '\\t',
46
+ s: '\\s',
47
+ '"': '\\"'
48
+ }
49
+ export const preserveEscape = (str) =>
50
+ str.replace(/[\n\r\t\s\"]/g, (match) => escapeChars[match] || match)
42
51
  export const stringifyType = (type) =>
43
52
  !isLeaf(type)
44
53
  ? `(array ${type.map((t) => stringifyType(t)).join(' ')})`