git » jacl.git » commit 42f58d4

Added JACL:REST-ARRAY declaration specifier

author Alan Dipert
2020-03-01 06:22:18 UTC
committer Alan Dipert
2020-03-01 06:22:18 UTC
parent 33055750689af12b892b4737731d13bf654e4e4f

Added JACL:REST-ARRAY declaration specifier

boot.lisp +2 -4
jacl.js +7 -5

diff --git a/boot.lisp b/boot.lisp
index e116887..44d17c4 100644
--- a/boot.lisp
+++ b/boot.lisp
@@ -203,15 +203,13 @@
 (defun functionp (x)
   (jacl:%js "~{} instanceof Function ? true : null" x))
 
-(defun %as-array (list)
-  (jacl:%js "List.toArray(~{})" list))
-
 (%export 'funcall)
 (defun funcall (f &rest args)
+  (declare (jacl:rest-array))
   (let ((func (cond ((symbolp f) (\. f (|func|)))
                     ((functionp f) f)
                     (t (%type-error "function or symbol")))))
-    (\. func (|apply| nil (%as-array args)))))
+    (\. func (|apply| nil args))))
 
 (defun %map-pairs (fun pairs)
   (let ((head nil)
diff --git a/jacl.js b/jacl.js
index 27e5c35..91062d5 100644
--- a/jacl.js
+++ b/jacl.js
@@ -434,6 +434,8 @@ CLPKG.intern('DECLARE');
 CLPKG.exportSymbol('DECLARE');
 JACLPKG.intern('ASYNC');
 JACLPKG.exportSymbol('ASYNC');
+JACLPKG.intern('REST-ARRAY');
+JACLPKG.exportSymbol('REST-ARRAY');
 
 // JS package constants
 const JSCONSTS = new Map([
@@ -1822,11 +1824,11 @@ const emitNode = (print, node) => {
       if (node.lambdaList.rest) {
         print(mungeSym(node.lambdaList.rest, 'local'));
         print('=');
-        // TODO Here we cons up a list from an array. It would be better if we
-        // could avoid copying and maybe had a 'cdr-coded' type, or array-backed
-        // pseudo-cons type thing. Then we could creat one of those in constant
-        // time.
-        print(`Cons.fromArray(Array.prototype.slice.call(arguments, ${restStart}));\n`);
+        if (node.declarations.find(x => List.first(x) === JACLPKG.intern('REST-ARRAY'))) {
+          print(`Array.prototype.slice.call(arguments, ${restStart});\n`);
+        } else {
+          print(`Cons.fromArray(Array.prototype.slice.call(arguments, ${restStart}));\n`);
+        }
       }
       // &key
       if (node.lambdaList.key.length) {