Re: [C--] qc-- fails to compile switch statement

Ning Wang <[email protected]> Sat, 21 Mar 2009 09:03:01 -0700
Newsgroups gmane.comp.lang.c--
Message-ID <[email protected]>
Norman Ramsey wrote:
>  > Hi,
>  > 
>  > It seems qc-- cannot compile test-047.c-- in the test2 folder.
>
> If you look in the output directory, it's not supposed to
> compile---it's supposed to produce error messages.
>
>  > I have a switch statement which is compiled as the follow:
>  > 
>  > switch bits8[_mlcc_ea__tmp_ce_7]
>  >          {
>  >             case 119::bits8: {
>  >                                 goto main0000019;
>  >                              }
>  >             case 87::bits8: {
>  >                                goto main0000020;
>  >                             }
>  >             case 116::bits8: {
>  >                                 goto main0000023;
>  >                              }
>  >             case 84::bits8: {
>  >                                goto main0000024;
>  >                             }
>  >             case 100::bits8: {
>  >                                 goto main0000027;
>  >                              }
>  >             case : {
>  >                       goto main0000030;
>  >                    }
>  >          }
>  > 
>  > 
>  > The last case represents a default case in the original C code. But qc-- 
>  > reports "Error: case arm has an empty range list"
>  > 
>  > Did I do something wrong? What's the correct way to represent C default 
>  > case in C--?
>
> There is no default case, so you did do something wrong---you need
> either to assert a limited set of ranges on the switch, or give all
> the missing values in the case.  Example
>
>    case 0..83, 85, 85, 88..99, 101..115, 117, 118, 120..255:
>
>
> I never should have let the Nameless One talk me into a switch statement :-)
>   
Don't mean to be offensive, but if the range is known, why should not 
the Nameless one be allowed?  Given the following code snippet which is 
in test-047.c--:

 switch [1 .. 3] i {
            case :              { return (i); }
            case 2 .. 3:        { return (i); }
        }

The range of the Nameless one has no ambiguity.  IMHO, allowing this 
special case is consistent with the design goal of C--.  Especially, 
when the only code generator is implemented in OCaml, I could not image 
front-ends implemented in other languages (except Haskell) can handle 
this more elegantly than the code generator.:-)  My code used to compute 
unused ranges is attached.

Thanks,
Ning

_______________________________________________
Cminusminus mailing list
[email protected]
https://www.eecs.harvard.edu/mailman/listinfo/cminusminus
sort_ranges.ml (text/plain, 1 KB)
type range_list = (int * int) list


(* i_start = inclusive start, and i_end = inclusive end *)
let add_range (l:range_list) ~(i_start:int) ~(i_end:int) : range_list = 
  (i_start, i_end)::l


let sort_range_list (l:range_list) = 
  let cmp (i_start0, i_end0) (i_start1, i_end1) =
    if i_start0 = i_start1 then
      begin
	assert (i_end0 = i_end1);
	0
      end
    else if i_start0 < i_start1 then
      begin
	assert (i_end0 < i_end1);
	-1
      end
    else (* i_start0 > i_start1 *)
      begin
	assert (i_end0 > i_end1);
	1
      end
  in List.sort cmp l
  

let unused_range_list (l:range_list) ~(min:int) ~(max:int) : range_list = 
  let sorted_list = sort_range_list l
  in
  let (ulist, cur_min) = 
    List.fold_left
      (fun (ulist, cur_min) (a,b) ->
	if (cur_min < a) then
	  ((cur_min, a - 1)::ulist, b + 1)
	else if (cur_min = a) then
	  (ulist, b+1)
	else 
	  assert false
	) ([], min) sorted_list
  in
  let ulist = 
    if (cur_min <= max) then
      (cur_min, max)::ulist
    else
      assert false
  in sort_range_list ulist