Thanks for pointing this out, Jörg.

I think making this case *actually* undefined would be OK. In other
words, treat it like a one-armed if or (cond-expand (else)).

It might be nice to add a warning, too, but that's a bigger patch so we
can start with this. Hackers, your thoughts?

Evan
>From 399c71c30abe8c03f503a3abd6c00a636982d967 Mon Sep 17 00:00:00 2001
From: Evan Hanson <ev...@foldling.org>
Date: Tue, 10 Apr 2018 19:51:58 +1200
Subject: [PATCH] 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)'.
---
 expand.scm             | 21 +++++++++++++--------
 tests/syntax-tests.scm |  4 ++++
 2 files changed, 17 insertions(+), 8 deletions(-)

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)
-- 
2.11.0

_______________________________________________
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers

Reply via email to