~ chicken-core (chicken-5) ed979783046e687ccbbdf612a84166150667c777


commit ed979783046e687ccbbdf612a84166150667c777
Author:     Evan Hanson <evhan@foldling.org>
AuthorDate: Tue Apr 10 19:51:58 2018 +1200
Commit:     Kooda <kooda@upyum.com>
CommitDate: Tue Apr 17 18:02:41 2018 +0200

    Make result of empty "else" clause undefined in `cond' and `case' forms
    
    Rather than resulting in a compiler error ("unbound variable: else"),
    make empty "else" clauses in these forms behave like they do in
    cond-expand and return `(##core#undefined)'.
    
    Signed-off-by: Kooda <kooda@upyum.com>

diff --git a/expand.scm b/expand.scm
index fad7e7cb..d3fcdbbe 100644
--- a/expand.scm
+++ b/expand.scm
@@ -1384,10 +1384,12 @@
 		     (cond ((and (fx= (length clause) 3)
 				 (c %=> (cadr clause)))
 			    `(,(caddr clause) ,(car clause)))
-			   ((null? (cdr clause))
-			    (car clause))
-			   (else `(##core#begin ,@(cdr clause)))))
-		    ((null? (cdr clause)) 
+			   ((pair? (cdr clause))
+			    `(##core#begin ,@(cdr clause)))
+			   ((c %else (car clause))
+			    `(##core#undefined))
+			   (else (car clause))))
+		    ((null? (cdr clause))
 		     `(,%or ,(car clause) ,(expand rclauses #f)))
 		    ((and (fx= (length clause) 3)
 			  (c %=> (cadr clause)))
@@ -1438,10 +1440,13 @@
 			   '(##core#begin))
 			  ((c %else (car clause))
 			   (expand rclauses #t)
-			   (if (and (fx= (length clause) 3) ; (else => expr)
-				    (c %=> (cadr clause)))
-			       `(,(caddr clause) ,tmp)
-			       `(##core#begin ,@(cdr clause))))
+			   (cond ((null? (cdr clause))
+				  `(##core#undefined))
+				 ((and (fx= (length clause) 3) ; (else => expr)
+				       (c %=> (cadr clause)))
+				  `(,(caddr clause) ,tmp))
+				 (else
+				  `(##core#begin ,@(cdr clause)))))
 			  (else
 			   `(##core#if (,%or ,@(##sys#map
 						(lambda (x) `(,%eqv? ,tmp ',x))
diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm
index 6bdfec45..d01d8883 100644
--- a/tests/syntax-tests.scm
+++ b/tests/syntax-tests.scm
@@ -732,6 +732,10 @@
       (1 ==> (lambda (x) x))
       (else 'yep))))
 
+;; Undefined value (but no compiler error) on empty `else' clauses
+(t (void) (cond (else)))
+(t (void) (case 1 (else)))
+
 ;; Literal quotation of a symbol, injected or not, should always result in that symbol
 (module ir-se-test (run)
   (import scheme chicken.base)
Trap