!parse-integer: trailing whitespace also increments index, when junk
[jscl.git] / ecmalisp.lisp
index 8fe11a9..cd93750 100644 (file)
     `(setq ,x (- ,x ,delta)))
 
   (defmacro push (x place)
-    `(setq ,place (cons ,x ,place)))
+    (multiple-value-bind (dummies vals newval setter getter)
+        (get-setf-expansion place)
+      (let ((g (gensym)))
+        `(let* ((,g ,x)
+                ,@(mapcar #'list dummies vals)
+                (,(car newval) (cons ,g ,getter))
+                ,@(cdr newval))
+           ,setter))))
 
   (defmacro dolist (iter &body body)
     (let ((var (first iter))
       ((funcall func (car list))
        (remove-if func (cdr list)))
       (t
+       ;;
        (cons (car list) (remove-if func (cdr list))))))
 
   (defun remove-if-not (func list)
         (return-from every nil)))
     t)
 
+  (defun position (elt sequence)
+    (let ((pos 0))
+      (do-sequence (x seq)
+        (when (eq elt x)
+          (return))
+        (incf pos))
+      pos))
+
   (defun assoc (x alist)
     (while alist
       (if (eql x (caar alist))
               `(progn (rplacd ,cons ,new-value) ,new-value)
               `(car ,cons))))
 
-  (defmacro push (x place)
-    (multiple-value-bind (dummies vals newval setter getter)
-        (get-setf-expansion place)
-      (let ((g (gensym)))
-        `(let* ((,g ,x)
-                ,@(mapcar #'list dummies vals)
-                (,(car newval) (cons ,g ,getter))
-                ,@(cdr newval))
-           ,setter))))
-
   ;; Incorrect typecase, but used in NCONC.
   (defmacro typecase (x &rest clausules)
     (let ((value (gensym)))
                      (concat (prin1-to-string (car last)) " . " (prin1-to-string (cdr last)))))
                ")"))
       ((arrayp form)
-       (concat "#" (prin1-to-string (vector-to-list form))))
+       (concat "#" (if (zerop (length form))
+                       "()"
+                       (prin1-to-string (vector-to-list form)))))
       ((packagep form)
-       (concat "#<PACKAGE " (package-name form) ">"))))
+       (concat "#<PACKAGE " (package-name form) ">"))
+      (t
+       (concat "#<javascript object>"))))
 
   (defun write-line (x)
     (write-string x)
 (defun !parse-integer (string junk-allow)
   (block nil
     (let ((value 0)
-         (index 0)
-         (size (length string))
-         (sign 1))
+          (index 0)
+          (size (length string))
+          (sign 1))
       (when (zerop size) (return (values nil 0)))
       ;; Optional sign
       (case (char string 0)
-       (#\+ (incf index))
-       (#\- (setq sign -1)
-            (incf index)))
+        (#\+ (incf index))
+        (#\- (setq sign -1)
+             (incf index)))
       ;; First digit
       (unless (and (< index size)
-                  (setq value (digit-char-p (char string index))))
-       (return (values nil index)))
+                   (setq value (digit-char-p (char string index))))
+        (return (values nil index)))
       (incf index)
       ;; Other digits
       (while (< index size)
-       (let ((digit (digit-char-p (char string index))))
-         (unless digit (return))
-         (setq value (+ (* value 10) digit))
-         (incf index)))
+        (let ((digit (digit-char-p (char string index))))
+          (unless digit (return))
+          (setq value (+ (* value 10) digit))
+          (incf index)))
+      ;; Trailing whitespace
+      (do ((i index (1+ i)))
+          ((or (= i size) (not (whitespacep (char string i))))
+           (and (= i size) (setq index i))))
       (if (or junk-allow
-             (= index size)
-             (char= (char string index) #\space))
-         (values (* sign value) index)
-         (values nil index)))))
+              (= index size))
+          (values (* sign value) index)
+          (values nil index)))))
 
 #+ecmalisp
 (defun parse-integer (string)
       (t
        (error (concat "How should I compile " (prin1-to-string sexp) "?"))))))
 
+
+(defvar *compile-print-toplevels* nil)
+
+(defun truncate-string (string &optional (width 60))
+    (let ((size (length string))
+          (n (or (position #\newline string)
+                 (min width (length string)))))
+      (subseq string 0 n)))
+
 (defun ls-compile-toplevel (sexp &optional multiple-value-p)
   (let ((*toplevel-compilations* nil))
     (cond
                            (cdr sexp))))
          (join (remove-if #'null-or-empty-p subs))))
       (t
+       (when *compile-print-toplevels*
+         (let ((form-string (prin1-to-string sexp)))
+           (write-string "Compiling ")
+           (write-string (truncate-string form-string))
+           (write-line "...")))
+       
        (let ((code (ls-compile sexp multiple-value-p)))
          (code (join-trailing (get-toplevel-compilations)
                               (code ";" *newline*))
         (read-sequence seq in)
         seq)))
 
-  (defun ls-compile-file (filename output)
-    (let ((*compiling-file* t))
+  (defun ls-compile-file (filename output &key print)
+    (let ((*compiling-file* t)
+          (*compile-print-toplevels* print))
       (with-open-file (out output :direction :output :if-exists :supersede)
         (write-string (read-whole-file "prelude.js") out)
         (let* ((source (read-whole-file filename))
           *gensym-counter* 0
           *literal-counter* 0
           *block-counter* 0)
-    (ls-compile-file "ecmalisp.lisp" "ecmalisp.js")))
+    (ls-compile-file "ecmalisp.lisp" "ecmalisp.js" :print t)))