git » jacl.git » commit e7b1898

Ensure locals and 'flocals' don't collide in JS

author Alan Dipert
2020-06-19 14:00:01 UTC
committer Alan Dipert
2020-06-19 14:00:01 UTC
parent 4a65f75fecccfba6b81fe1a3d730d1be888518b3

Ensure locals and 'flocals' don't collide in JS

jacl-tests.lisp +4 -3
jacl.js +8 -3

diff --git a/jacl-tests.lisp b/jacl-tests.lisp
index 6dc7cd8..5a65ff4 100644
--- a/jacl-tests.lisp
+++ b/jacl-tests.lisp
@@ -175,9 +175,10 @@
 (deftest "Named JACL:%LAMBDA"
   (let* ((invocations 0)
          (f (jacl:%lambda self (x y)
-                          (when (< x y)
-                            (setq invocations (1+ invocations))
-                            (self (1+ x) y)))))
+                          (let ((self nil))
+                            (when (< x y)
+                              (setq invocations (1+ invocations))
+                              (self (1+ x) y))))))
     (funcall f 0 10)
     (assert= invocations 10)))
 
diff --git a/jacl.js b/jacl.js
index 66d9afe..856e7f3 100644
--- a/jacl.js
+++ b/jacl.js
@@ -1500,7 +1500,7 @@ const parseCall = (env, parent, form) => {
   if (isLambdaForm(func)) {
     node.f = analyze(env.withContext('expr'), parent, func);
   } else if (env.hasLocalFunction(func)) {
-    node.f = makeNode('local', {
+    node.f = makeNode('flocal', {
       env: env.withContext('expr'),
       parent: node,
       form: func,
@@ -1783,6 +1783,11 @@ const emitNode = (print, node) => {
       print(mungeSym(form, 'local'));
       if (context !== 'expr') print(';\n');
       break;
+    case 'flocal':
+      if (context === 'return') print('return ');
+      print(mungeSym(form, 'flocal'));
+      if (context !== 'expr') print(';\n');
+      break;
     case 'global':
       if (context === 'return') print('return ');
       if (form.packageName === 'COMMON-LISP' && form.name === 'NIL') {
@@ -1880,9 +1885,9 @@ const emitNode = (print, node) => {
     }
     case 'lambda': {
       if (node.declarations.find(x => List.first(x) === JACLPKG.intern('ASYNC'))) {
-        print(`(async function ${mungeSym(node.name, 'local')}(`);
+        print(`(async function ${mungeSym(node.name, 'flocal')}(`);
       } else {
-        print(`(function ${mungeSym(node.name, 'local')}(`);
+        print(`(function ${mungeSym(node.name, 'flocal')}(`);
       }
       // Emit required argument names
       // TODO Move lambda list production to a function for use by macro ll,