fez-lisp 1.2.43 → 1.2.44
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/README.md +39 -29
- package/lib/baked/std.js +1 -1
- package/package.json +1 -1
- package/src/compiler.js +43 -5
- package/src/interpreter.js +1 -1
- package/src/keywords.js +3 -1
- package/src/utils.js +4 -3
package/package.json
CHANGED
package/src/compiler.js
CHANGED
@@ -8,13 +8,22 @@ import {
|
|
8
8
|
WORD
|
9
9
|
} from './keywords.js'
|
10
10
|
import { leaf, isLeaf } from './parser.js'
|
11
|
-
const
|
11
|
+
const deepRenameTco = (name, newName, tree) => {
|
12
12
|
if (!isLeaf(tree))
|
13
13
|
for (const leaf of tree) {
|
14
14
|
// Figure out a non mutable solution so
|
15
15
|
// I can get rid of deep copy
|
16
16
|
if (leaf[VALUE] === name) leaf[VALUE] = `()=>${newName}`
|
17
|
-
|
17
|
+
deepRenameTco(name, newName, leaf)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
const deepRenameCache = (name, newName, tree) => {
|
21
|
+
if (!isLeaf(tree))
|
22
|
+
for (const leaf of tree) {
|
23
|
+
// Figure out a non mutable solution so
|
24
|
+
// I can get rid of deep copy
|
25
|
+
if (leaf[VALUE] === name) leaf[VALUE] = newName
|
26
|
+
deepRenameCache(name, newName, leaf)
|
18
27
|
}
|
19
28
|
}
|
20
29
|
const earMuffsToLodashes = (name) => name.replace(new RegExp(/\*/g), '_')
|
@@ -166,16 +175,20 @@ const compile = (tree, Drill) => {
|
|
166
175
|
}
|
167
176
|
case KEYWORDS.DEFINE_VARIABLE: {
|
168
177
|
const n = Arguments[0][VALUE]
|
169
|
-
|
178
|
+
const prefix = n.split(':')[0]
|
179
|
+
if (prefix === KEYWORDS.RECURSION) {
|
170
180
|
const name = lispToJavaScriptVariableName(n)
|
171
|
-
const newName = `
|
181
|
+
const newName = `recursive_${performance
|
182
|
+
.now()
|
183
|
+
.toString()
|
184
|
+
.replace('.', 7)}`
|
172
185
|
Drill.Variables.add(name)
|
173
186
|
Drill.Variables.add(newName)
|
174
187
|
Drill.Helpers.add('__tco')
|
175
188
|
const functionArgs = Arguments.at(-1).slice(1)
|
176
189
|
const body = functionArgs.pop()
|
177
190
|
const FunctionDrill = { Variables: new Set(), Helpers: Drill.Helpers }
|
178
|
-
|
191
|
+
deepRenameTco(n, newName, body)
|
179
192
|
const evaluatedBody = compile(body, FunctionDrill)
|
180
193
|
const vars = FunctionDrill.Variables.size
|
181
194
|
? `var ${[...FunctionDrill.Variables].join(',')};`
|
@@ -186,6 +199,31 @@ const compile = (tree, Drill) => {
|
|
186
199
|
)})=>{${vars}return ${evaluatedBody
|
187
200
|
.toString()
|
188
201
|
.trim()}}, ${newName})));`
|
202
|
+
} else if (prefix === KEYWORDS.CACHE) {
|
203
|
+
// memoization here
|
204
|
+
const name = lispToJavaScriptVariableName(n)
|
205
|
+
const newName = name.substring(2)
|
206
|
+
Drill.Variables.add(name)
|
207
|
+
Drill.Variables.add(newName)
|
208
|
+
const functionArgs = Arguments.at(-1).slice(1)
|
209
|
+
const body = functionArgs.pop()
|
210
|
+
deepRenameCache(n, newName, body)
|
211
|
+
const FunctionDrill = { Variables: new Set(), Helpers: Drill.Helpers }
|
212
|
+
const evaluatedBody = compile(body, FunctionDrill)
|
213
|
+
const vars = FunctionDrill.Variables.size
|
214
|
+
? `var ${[...FunctionDrill.Variables].join(',')};`
|
215
|
+
: ''
|
216
|
+
return `(${name}=function(){const __${newName}_map = new Map();
|
217
|
+
var ${newName} = (function(${parseArgs(functionArgs, Drill)}){${vars};
|
218
|
+
var __key = [...arguments].join(',')
|
219
|
+
if (__${newName}_map.has(__key)) return __${newName}_map.get(__key)
|
220
|
+
else {
|
221
|
+
const __res = ${evaluatedBody.toString().trim()}
|
222
|
+
__${newName}_map.set(__key, __res)
|
223
|
+
return __res
|
224
|
+
}})
|
225
|
+
return ${newName}(...arguments)
|
226
|
+
});`
|
189
227
|
} else {
|
190
228
|
const name = lispToJavaScriptVariableName(n)
|
191
229
|
Drill.Variables.add(name)
|
package/src/interpreter.js
CHANGED
package/src/keywords.js
CHANGED
package/src/utils.js
CHANGED
@@ -102,6 +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
107
|
return true
|
106
108
|
default:
|
107
109
|
return !isNaN(name[0])
|
@@ -262,9 +264,8 @@ export const fez = (source, options = {}) => {
|
|
262
264
|
}
|
263
265
|
} catch (error) {
|
264
266
|
// console.log(error)
|
265
|
-
const err = error.message
|
266
|
-
|
267
|
-
.replace('object', '(array)')
|
267
|
+
const err = error.message.replace("'[object Array]'", '(array)')
|
268
|
+
// .replace('object', '(array)')
|
268
269
|
logError(err)
|
269
270
|
if (options.throw) throw err
|
270
271
|
return err
|