VALUES-LIST
authorDavid Vazquez <davazp@gmail.com>
Thu, 24 Jan 2013 22:46:50 +0000 (22:46 +0000)
committerDavid Vazquez <davazp@gmail.com>
Thu, 24 Jan 2013 22:46:50 +0000 (22:46 +0000)
ecmalisp.lisp

index 6a7e019..995632c 100644 (file)
@@ -23,7 +23,7 @@
 ;;; language to the compiler to be able to run.
 
 #+ecmalisp
 ;;; language to the compiler to be able to run.
 
 #+ecmalisp
-(js-eval "function id (x) { return x; }")
+(js-eval "function id (x) { return 'car' in x ? x.car : x; }")
 
 #+ecmalisp
 (progn
 
 #+ecmalisp
 (progn
     (revappend list '()))
 
   (defmacro psetq (&rest pairs)
     (revappend list '()))
 
   (defmacro psetq (&rest pairs)
-    (let (;; For each pair, we store here a list of the form
+    (let ( ;; For each pair, we store here a list of the form
          ;; (VARIABLE GENSYM VALUE).
          (assignments '()))
       (while t
          ;; (VARIABLE GENSYM VALUE).
          (assignments '()))
       (while t
         (oset exports (symbol-name symb) symb))))
 
   (defun get-universal-time ()
         (oset exports (symbol-name symb) symb))))
 
   (defun get-universal-time ()
-    (+ (get-unix-time) 2208988800)))
+    (+ (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)))
 
 
 ;;; The compiler offers some primitives and special forms which are
 
 
 ;;; The compiler offers some primitives and special forms which are
   (concat "(" var " = " (ls-compile val) ")"))
 
 
   (concat "(" var " = " (ls-compile val) ")"))
 
 
+
 ;;; Literals
 (defun escape-string (string)
   (let ((output "")
 ;;; Literals
 (defun escape-string (string)
   (let ((output "")
           "})" *newline*)
         (error (concat "Unknown tag `" n "'.")))))
 
           "})" *newline*)
         (error (concat "Unknown tag `" n "'.")))))
 
-
 (define-compilation unwind-protect (form &rest clean-up)
   (js!selfcall
     "var ret = " (ls-compile nil) ";" *newline*
 (define-compilation unwind-protect (form &rest clean-up)
   (js!selfcall
     "var ret = " (ls-compile nil) ";" *newline*
     "}" *newline*
     "return ret;" *newline*))
 
     "}" *newline*
     "return ret;" *newline*))
 
+(define-compilation multiple-value-call (func-form &rest forms)
+  (let ((func (ls-compile func-form)))
+    (js!selfcall
+      "var args = [values];" *newline*
+      "function values(){" *newline*
+      (indent "var result = [];" *newline*
+              "for (var i=0; i<arguments.length; i++)" *newline*
+              (indent "result.push(arguments[i]);"))
+      "}" *newline*
+      (mapconcat (lambda (form)
+                   (ls-compile form))
+                 forms)
+      "return (" func ").apply(window, [args]);")))
+
+
 
 ;;; A little backquote implementation without optimizations of any
 ;;; kind for ecmalisp.
 
 ;;; A little backquote implementation without optimizations of any
 ;;; kind for ecmalisp.
 (define-builtin get-unix-time ()
   (concat "(Math.round(new Date() / 1000))"))
 
 (define-builtin get-unix-time ()
   (concat "(Math.round(new Date() / 1000))"))
 
+(define-raw-builtin values-list (list)
+  (concat "values(" list ")"))
 
 (defun macro (x)
   (and (symbolp x)
 
 (defun macro (x)
   (and (symbolp x)