diff --git a/src/docode.c b/src/docode.c
index 67fbe6f7056338d894ca489239f5da82a56b6435..3b4c414b3d9ce27c0470515ef41e7a9c2ca7a5d1 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.21 1997/09/09 03:36:11 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.22 1997/09/19 06:45:31 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -802,11 +802,16 @@ static int do_docode2(node *n,int flags)
     /* Check for cases inside a range */
     for(e=0; e<cases-1; e++)
     {
-      if(current_switch_jumptable[ order[e]*2+2 ] != -1)
+      if(order[e] < cases-1)
       {
-	if(current_switch_jumptable[ order[e]*2+2 ] !=
-	   current_switch_jumptable[ order[e+1]*2+1 ])
-	  yyerror("Case inside range.");
+	int o1=order[e]+1;
+	if(current_switch_jumptable[o1]==current_switch_jumptable[o1+1] &&
+	   current_switch_jumptable[o1]==current_switch_jumptable[o1+2])
+	{
+	  if(order[e]+1 != order[e+1])
+	    yyerror("Case inside range.");
+          e++;
+	}
       }
     }
 
@@ -852,10 +857,13 @@ static int do_docode2(node *n,int flags)
     {
       yyerror("Case outside switch.");
     }else{
-      if(!is_const(CAR(n)))
+      node *lower=CAR(n);
+      if(!lower) lower=CDR(n);
+
+      if(!is_const(lower))
 	yyerror("Case label isn't constant.");
 
-      tmp1=eval_low(CAR(n));
+      tmp1=eval_low(lower);
       if(tmp1<1)
       {
 	yyerror("Error in case label.");
@@ -872,27 +880,36 @@ static int do_docode2(node *n,int flags)
 
       if(CDR(n))
       {
-	if(!is_const(CDR(n)))
-	  yyerror("Case label isn't constant.");
+	current_switch_jumptable[current_switch_case]=
+	  current_switch_jumptable[current_switch_case-1];
+	current_switch_case++;
 
-	current_switch_jumptable[current_switch_case+1]=
+	if(CAR(n))
+	{
+	  if(!is_const(CDR(n)))
+	    yyerror("Case label isn't constant.");
+	  
 	  current_switch_jumptable[current_switch_case]=
 	    current_switch_jumptable[current_switch_case-1];
-	current_switch_case+=2;
-	tmp1=eval_low(CDR(n));
-	if(tmp1<1)
-	{
-	  yyerror("Error in second half of case label.");
-	  push_int(0);
-	  tmp1=1;
+	  current_switch_case++;
+
+	  tmp1=eval_low(CDR(n));
+	  if(tmp1<1)
+	  {
+	    yyerror("Error in second half of case label.");
+	    push_int(0);
+	    tmp1=1;
+	  }
+	  pop_n_elems(tmp1-1);
+	  current_switch_values_on_stack++;
+	  for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
+	    if(is_equal(sp-tmp1, sp-1))
+	      yyerror("Duplicate case.");
+	  current_switch_jumptable[current_switch_case++]=-1;
 	}
-	pop_n_elems(tmp1-1);
-	current_switch_values_on_stack++;
-	for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
-	  if(is_equal(sp-tmp1, sp-1))
-	    yyerror("Duplicate case.");
+      }else{
+	current_switch_jumptable[current_switch_case++]=-1;
       }
-      current_switch_jumptable[current_switch_case++]=-1;
     }
     return 0;
   }
diff --git a/src/language.yacc b/src/language.yacc
index 1446eff7d1a196be5c43c4a60d19f09aaf087ebb..0f7eb4d4bfbcf4ac7facc0549c218bcc2c53444f 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -156,7 +156,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.48 1997/09/11 19:53:44 grubba Exp $");
+RCSID("$Id: language.yacc,v 1.49 1997/09/19 06:45:32 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -331,6 +331,7 @@ int yylex(YYSTYPE *yylval);
 %type <n> m_expr_list
 %type <n> m_expr_list2
 %type <n> new_local_name
+%type <n> optional_comma_expr
 %type <n> optional_else_part
 %type <n> return
 %type <n> sscanf
@@ -1010,9 +1011,9 @@ case: F_CASE comma_expr ':'
   {
     $$=mknode(F_CASE,$2,0);
   }
-  | F_CASE comma_expr F_DOT_DOT comma_expr ':'
+  | F_CASE comma_expr F_DOT_DOT optional_comma_expr ':'
   {
-    $$=mknode(F_CASE,$2,$4);
+    $$=mknode(F_CASE,$4?$2:0,$4?$4:$2);
   }
   ;
 
@@ -1037,6 +1038,10 @@ unused: { $$=0; }
 
 unused2: comma_expr { $$=mkcastnode(void_type_string,$1);  } ;
 
+optional_comma_expr: { $$=0; }
+  | comma_expr
+  ;
+
 comma_expr: comma_expr2
   | type2
   {