Values is inlined only in functions
[jscl.git] / ecmalisp.lisp
index 995632c..0801df4 100644 (file)
@@ -23,7 +23,7 @@
 ;;; language to the compiler to be able to run.
 
 #+ecmalisp
-(js-eval "function id (x) { return 'car' in x ? x.car : x; }")
+(js-eval "function pv (x) { return typeof x === 'object' && 'car' in x ? x.car : x; }")
 
 #+ecmalisp
 (progn
         (oset exports (symbol-name symb) symb))))
 
   (defun get-universal-time ()
-    (+ (get-unix-time) 2208988800))
-
-  ;; The `values-list' primitive cannot be inlined out of functions as
-  ;; the VALUES argument is not available there. We declare it
-  ;; NOTINLINE to avoid it.
-  (declaim (notinline values-list))
-  (defun values-list (list)
-    (values-list list))
-
-  (defun values (&rest args)
-    (values-list args)))
+    (+ (get-unix-time) 2208988800)))
 
 
 ;;; The compiler offers some primitives and special forms which are
       (aset v i x)
       (incf i))))
 
+#+ecmalisp
+(progn
+  (defun values-list (list)
+    (values-array (list-to-vector list)))
+
+  (defun values (&rest args)
+    (values-list args)))
+
+
 ;;; Like CONCAT, but prefix each line with four spaces. Two versions
 ;;; of this function are available, because the Ecmalisp version is
 ;;; very slow and bootstraping was annoying.
         "return func;" *newline*)
       (join strs)))
 
+
+(defvar *compiling-lambda-p* nil)
+
 (define-compilation lambda (lambda-list &rest body)
   (let ((required-arguments (lambda-list-required-arguments lambda-list))
         (optional-arguments (lambda-list-optional-arguments lambda-list))
         (rest-argument (lambda-list-rest-argument lambda-list))
+        (*compiling-lambda-p* t)
         documentation)
     ;; Get the documentation string for the lambda function
     (when (and (stringp (car body))
 
 (define-raw-builtin funcall (func &rest args)
   (concat "(" (ls-compile func) ")("
-          (join (cons "id" (mapcar #'ls-compile args))
+          (join (cons "pv" (mapcar #'ls-compile args))
                 ", ")
           ")"))
 
             (last (car (last args))))
         (js!selfcall
           "var f = " (ls-compile func) ";" *newline*
-          "var args = [" (join (cons "id" (mapcar #'ls-compile args))
+          "var args = [" (join (cons "pv" (mapcar #'ls-compile args))
                                ", ")
           "];" *newline*
           "var tail = (" (ls-compile last) ");" *newline*
 (define-builtin get-unix-time ()
   (concat "(Math.round(new Date() / 1000))"))
 
-(define-raw-builtin values-list (list)
-  (concat "values(" list ")"))
+(define-builtin values-array (array)
+  (concat "values.apply(this, " array ")"))
+
+(define-raw-builtin values (&rest args)
+  (if *compiling-lambda-p*
+      (concat "values(" (join (mapcar #'ls-compile args) ", ") ")")
+      (compile-funcall 'values args)))
+
 
 (defun macro (x)
   (and (symbolp x)
   (if (and (symbolp function)
            (claimp function 'function 'non-overridable))
       (concat (ls-compile `',function) ".fvalue("
-              (join (cons "id" (mapcar #'ls-compile args))
+              (join (cons "pv" (mapcar #'ls-compile args))
                     ", ")
               ")")
       (concat (ls-compile `#',function) "("
-              (join (cons "id" (mapcar #'ls-compile args))
+              (join (cons "pv" (mapcar #'ls-compile args))
                     ", ")
               ")")))