ref2test finds reference.lisp in docs dir
authorHenrik Hjelte <henrik.hjelte@poboxes.com>
Wed, 1 Feb 2006 11:17:12 +0000 (11:17 +0000)
committerHenrik Hjelte <henrik.hjelte@poboxes.com>
Wed, 1 Feb 2006 11:17:12 +0000 (11:17 +0000)
docs/reference.lisp
src/js.lisp
t/ref2test.lisp
t/reference-tests.lisp
t/test.lisp

index f0f9e40..1828d3b 100644 (file)
@@ -758,30 +758,54 @@ a-variable  => aVariable
 
 ;;;# The `CASE' statement
 ;;;t \index{CASE}
+;;;t \index{SWITCH}
 ;;;t \index{switch}
 
 ; (CASE case-value clause*)
 ;
-; clause     ::= (value body)
+; clause     ::= (value body) | ((value*) body) | t-clause
 ; case-value ::= a ParenScript expression
 ; value      ::= a ParenScript expression
+; t-clause   ::= {t | otherwise | default} body
 ; body       ::= a list of ParenScript statements
 
 ;;; The Lisp `CASE' form is transformed to a `switch' statement in
 ;;; JavaScript. Note that `CASE' is not an expression in
-;;; ParenScript. The default case is not named `T' in ParenScript, but
-;;; `DEFAULT' instead.
+;;; ParenScript. 
 
 (case (aref blorg i)
-  (1 (alert "one"))
+  ((1 "one") (alert "one"))
   (2 (alert "two"))
-  (default (alert "default clause")))
+  (t (alert "default clause")))
     => switch (blorg[i]) {
-         case 1:   alert('one');
-         case 2:   alert('two');
+         case 1:   ;
+         case 'one':
+                   alert('one');
+                   break;
+         case 2:
+                   alert('two');
+                   break;
          default:   alert('default clause');
        }
 
+; (SWITCH case-value clause*)
+; clause     ::= (value body) | (default body)
+
+;;; The `SWITCH' form is the equivalent to a javascript switch statement.
+;;; No break statements are inserted, and the default case is named `DEFAULT'.
+;;; The `CASE' form should be prefered in most cases.
+
+(switch (aref blorg i)
+  (1 (alert "If I get here"))
+  (2 (alert "I also get here"))
+  (default (alert "I always get here")))
+    => switch (blorg[i]) {
+         case 1:   alert('If I get here');
+         case 2:   alert('I also get here');
+         default:   alert('I always get here');
+       }
+
+
 ;;;# The `WITH' statement
 ;;;t \index{WITH}
 ;;;t \index{dynamic scope}
index 9263ffd..ae3bcb7 100644 (file)
@@ -1114,11 +1114,11 @@ this macro."
 
 ;;; case
 
-(defjsclass js-case (statement)
+(defjsclass js-switch (statement)
   ((value :initarg :value :accessor case-value)
    (clauses :initarg :clauses :accessor case-clauses)))
 
-(define-js-compiler-macro case (value &rest clauses)
+(define-js-compiler-macro switch (value &rest clauses)
   (let ((clauses (mapcar #'(lambda (clause)
                             (let ((val (first clause))
                                   (body (cdr clause)))
@@ -1128,10 +1128,10 @@ this macro."
                                     (js-compile-to-body (cons 'progn body) :indent "  "))))
                         clauses))
        (check (js-compile-to-expression value)))
-    (make-instance 'js-case :value check
+    (make-instance 'js-switch :value check
                   :clauses clauses)))
 
-(defmethod js-to-statement-strings ((case js-case) start-pos)
+(defmethod js-to-statement-strings ((case js-switch) start-pos)
   (let ((body   (mapcan #'(lambda (clause)
                     (let ((val (car clause))
                           (body (second clause)))
@@ -1152,6 +1152,21 @@ this macro."
           body
           (list "}"))))
 
+(defjsmacro case (value &rest clauses)
+  (labels ((make-clause (val body more)
+             (cond ((listp val)
+                    (append (mapcar #'list (butlast val))
+                            (make-clause (first (last val)) body more)))
+                   ((member val '(t otherwise))
+                    (make-clause 'default body more))
+                   (more `((,val ,@body break)))
+                   (t `((,val ,@body))))))
+    `(switch ,value ,@(mapcon #'(lambda (x)
+                                  (make-clause (car (first x))
+                                               (cdr (first x))
+                                               (rest x)))
+                              clauses))))
+
 ;;; throw catch
 
 (defjsclass js-try (statement)
index 43a4e66..f49677b 100644 (file)
@@ -1,9 +1,13 @@
 (in-package :js-test)
 ;;Generates automatic tests from the reference
 
-(defparameter +reference-file+ (make-pathname :name "reference"
-                                              :type "lisp"
-                                              :defaults *load-truename*))
+(defparameter +reference-file+ (merge-pathnames
+                                (make-pathname :directory '(:relative :back "docs"))
+                                (make-pathname :name "reference"
+                                               :type "lisp"
+                                               :defaults *load-truename*)))
+
+
 (defparameter +generate-file+ (make-pathname :name "reference-tests"
                                               :type "lisp"
                                               :defaults *load-truename*))
@@ -66,7 +70,7 @@
                        (= 2 heading-count)) ;requires cl-interpol reader
                   (format t "Skipping regex-test two~&"))
                  ((and lisp-part javascript-part)
-                  (format out-stream "(test-ps-js ~a-~a ~%  ~a ~%  \"~a\")~%~%"
+                  (format out-stream "(test-ps-js ~a-~a~%  ~a~%  \"~a\")~%~%"
                           heading heading-count
                           (trim-whitespace lisp-part)
                           (strip-indentation javascript-part js-indent-width)))
index 971a506..f67ad03 100644 (file)
@@ -400,15 +400,31 @@ x = a + b + c;")
 
 (test-ps-js the-case-statement-1
   (case (aref blorg i)
-  (1 (alert "one"))
+  ((1 "one") (alert "one"))
   (2 (alert "two"))
-  (default (alert "default clause")))
+  (t (alert "default clause")))
   "switch (blorg[i]) {
-  case 1:   alert('one');
-  case 2:   alert('two');
+  case 1:   ;
+  case 'one':
+            alert('one');
+            break;
+  case 2:
+            alert('two');
+            break;
   default:   alert('default clause');
 }")
 
+(test-ps-js the-case-statement-2
+  (switch (aref blorg i)
+  (1 (alert "If I get here"))
+  (2 (alert "I also get here"))
+  (default (alert "I always get here")))
+  "switch (blorg[i]) {
+  case 1:   alert('If I get here');
+  case 2:   alert('I also get here');
+  default:   alert('I always get here');
+}")
+
 (test-ps-js the-with-statement-1
   (with ((create :foo "foo" :i "i"))
   (alert (+ "i is now intermediary scoped: " i)))
index 651c6cb..73f7d0a 100644 (file)
 (test-ps-js buggy-slot-value-two
   (slot-value foo (get-slot-name))
   "foo[getSlotName()]")
+
+(test-ps-js old-case-is-now-switch
+  ;; Switch was "case" before, but that was very non-lispish.
+  ;; For example, this code makes three messages and not one
+  ;; which may have been expected. This is because a switch
+  ;; statment must have a break statement for it to return
+  ;; after the alert. Otherwise it continues on the next
+  ;; clause.
+  (switch (aref blorg i)
+     (1 (alert "one"))
+     (2 (alert "two"))
+     (default (alert "default clause")))
+     "switch (blorg[i]) {
+         case 1:   alert('one');
+         case 2:   alert('two');
+         default:   alert('default clause');
+         }")
+
+(test-ps-js lisp-like-case
+   (case (aref blorg i)
+     (1 (alert "one"))
+     (2 (alert "two"))
+     (default (alert "default clause")))    
+     "switch (blorg[i]) {
+         case 1:
+                   alert('one');
+                   break;
+         case 2:
+                   alert('two');
+                   break;
+         default:   alert('default clause');
+         }")
+
+
+(test-ps-js even-lispier-case
+  (case (aref blorg i)
+      ((1 2) (alert "Below three"))
+      (3 (alert "Three"))
+      (t (alert "Something else")))
+   "switch (blorg[i]) {
+         case 1:   ;
+         case 2:
+                   alert('Below three');
+                   break;
+         case 3:
+                   alert('Three');
+                   break;
+         default:   alert('Something else');
+    }")
+
+(test-ps-js otherwise-case
+   (case (aref blorg i)
+     (1 (alert "one"))
+     (otherwise (alert "default clause")))    
+     "switch (blorg[i]) {
+         case 1:
+                   alert('one');
+                   break;
+         default:   alert('default clause');
+         }")