<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
    <title></title>
  </head>
  <body bgcolor="#ffffff" text="#000000">
    <tt>On 06/24/2011 01:17 PM, Dan McCabe wrote:</tt>
    <blockquote cite="mid:4E04F0DE.9010109@gmail.com" type="cite"><tt>On
        06/20/2011 03:50 PM, Ian Romanick wrote:
        <br>
      </tt>
      <blockquote type="cite"><tt>-----BEGIN PGP SIGNED MESSAGE-----
          <br>
          Hash: SHA1
          <br>
          <br>
          On 06/17/2011 05:43 PM, Dan McCabe wrote:
        </tt>
        <tt><br>
        </tt>
        <blockquote type="cite"><tt>Beware! Here be dragons!
            <br>
            <br>
            <br>
          </tt>
        </blockquote>
        <tt>I think this will generate the wrong code for:
          <br>
          <br>
        </tt>
        <tt>&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i&lt;&nbsp; 10; i++) {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (i) {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: continue;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;}
          <br>
          <br>
          It seems like that will generate some approximation of:
        </tt>
        <tt><br>
          <br>
        </tt>
        <tt>&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i&lt;&nbsp; 10; i++) {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (true);
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;}
          <br>
          <br>
          Right?&nbsp; This is why I had originally tracked loops and
          switch-statements
        </tt>
        <tt><br>
          in a single stack.&nbsp; In this situation, you'd want to set a "do
          a
          <br>
          continue" flag in the switch-statement and emit a break (from
          the
          <br>
          switch).&nbsp; Something like:
          <br>
          <br>
          <br>
        </tt>
        <tt>&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i&lt;&nbsp; 10; i++) {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool do_cont = false;
          <br>
          <br>
        </tt>
        <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do {
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_cont = true;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (true);
          <br>
          <br>
        </tt>
        <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (do_cont)
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;
          <br>
          &nbsp;&nbsp;&nbsp;&nbsp;}
          <br>
          <br>
          <br>
        </tt>
      </blockquote>
      <tt>Yikes! Looks like you tripped over one of those dragons :(.
        <br>
        <br>
        Using a do_cont variable (or similar device) feels kludgey to
        me. I've been mulling this over for the last couple of days
        while I did other things and I think the right way to do this
        might be to get rid of the use of "loop" altogether.
      </tt>
      <tt><br>
        <br>
        But the devil is in the details, which I haven't worked out yet.
        Going back to the unified loop/switch stack might be needed,
        though.
      </tt>
      <tt><br>
        <br>
        cheers, danm
      </tt>
      <tt><br>
        <br>
      </tt>
    </blockquote>
    <tt><br>
      All is not lost! (But you already knew that :)<br>
      <br>
      One of the motivations of using the loop device is that it enabled
      the relatively unmodified infrastructure for break statements. But
      let's get rid of the break device and see where we go.<br>
      <br>
      Without xlating switch stmts into loops, we can still retain the
      test_val_tmp and is_fallthru_tmp temporaries (in fact, we need to;
      nothing changes there since that is how case labels are managed).<br>
      <br>
      However, the standard break processing no longer applies, since we
      are not in a loop (for the switch stmt in any event). If we
      introduce a bool temporary called is_break_tmp and initialize it
      to false, then when we encounter a break stmt, we set is_break_tmp
      to true. Now we must guard the case statement with both
      fallthru_var and is_break_var. If is_break_tmp was set, we simply
      clear is_fallthru_tmp right after all case tests to false.<br>
      <br>
      Note that this approach does require maintaining a loop/switch
      stack as the code originally did so that we can tell if a break
      statement is associate with a loop or with a switch stmt. Only if
      the top of the stack indicates that switch is being processed will
      the above break processing be invoked.<br>
      <br>
      Looking at a translation of my canonical example:<br>
    </tt>
    <blockquote><tt>switch (expr) {<br>
        case c0:<br>
        case c1:<br>
        &nbsp;&nbsp;&nbsp;&nbsp; stmt0;<br>
        case c2:<br>
        case c3:<br>
        &nbsp;&nbsp;&nbsp;&nbsp; stmt1;<br>
        &nbsp;&nbsp;&nbsp;&nbsp; break;<br>
        case c4:<br>
        default:<br>
        &nbsp;&nbsp;&nbsp;&nbsp; stmt2;<br>
        }<br>
      </tt></blockquote>
    <tt>We can translated this into:<br>
    </tt>
    <blockquote><tt>int test_val_tmp = expr;<br>
        bool is_fallthru_tmp = false;<br>
        bool is_break_tmp = false;<br>
        <br>
        if (test_val_tmp == c0) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = true;<br>
        }<br>
        if (test_val_tmp == c1) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = true;<br>
        }<br>
        if (is_break_tmp) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = false;<br>
        }<br>
        if (is_fallthru_tmp) {<br>
        &nbsp;&nbsp; stmt0;<br>
        }<br>
        <br>
        if (test_val_tmp == c2) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = true;<br>
        }<br>
        if (test_val_tmp == c3) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = true;<br>
        }<br>
        if (is_break_tmp) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = false;<br>
        }<br>
        if (is_fallthru_tmp) {<br>
        &nbsp;&nbsp; stmt1;<br>
        &nbsp;&nbsp; is_break_tmp = true; // break stmt<br>
        }<br>
        <br>
        if (test_val_tmp == c4) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = true;<br>
        }<br>
        is_fallthru_tmp = true; // default<br>
        if (is_break_tmp) {<br>
        &nbsp;&nbsp; is_fallthru_tmp = false;<br>
        }<br>
        if (is_fallthru_tmp) {<br>
        &nbsp;&nbsp; stmt2;<br>
        }<br>
      </tt></blockquote>
    <tt>Comparing this to what we did previously, the things that change
      in this code are:<br>
      1) no enclosing loop<br>
      2) create a bool is_break_tmp initialized to false<br>
      3) after all case labels and before each case statement list,
      clear is_fallthru_tmp when is_break_tmp<br>
      4) set is_break_tmp for each break statement<br>
      <br>
      And maintain the loop/switch stack again as in the original code.<br>
      <br>
      I'll get this cranked out on Monday and resubmit for review. If
      anyone has concerns or questions about what I'm doing here, please
      let me know.<br>
      <br>
      cheers, danm<br>
      <br>
    </tt>
  </body>
</html>