home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / me34src.zip / me3 / mc / control.c < prev    next >
C/C++ Source or Header  |  1995-01-14  |  5KB  |  186 lines

  1. /* control.c : Compile control structures like while, for next, etc.
  2.  * Return: class
  3.  */
  4.  
  5. /* Copyright 1990, 1991, 1992 Craig Durland
  6.  *   Distributed under the terms of the GNU General Public License.
  7.  *   Distributed "as is", without warranties of any kind, but comments,
  8.  *     suggestions and bug reports are welcome.
  9.  */
  10.  
  11. #include <os.h>
  12. #include "mc.h"
  13. #include "mm.h"
  14. #include "opcode.h"
  15.  
  16. extern char token[];
  17.  
  18. extern int
  19.     breaklabel, contlabel,        /* in mc.c */
  20.     btv;
  21. extern unsigned int class;        /* in mc.c */
  22.  
  23.     /* (while (test)(body))
  24.      * Compiles down to:
  25.      *   1: if (test) is FALSE goto 2    ; ignore if (test) ==TRUE
  26.      *    (body)
  27.      *    goto 1
  28.      *   2:
  29.      */
  30. comp_while()
  31. {
  32.   int l1, ldone, savebl = breaklabel, savecl = contlabel,z;
  33.  
  34.   l1 = contlabel = genlabel(); ldone = breaklabel = genlabel();
  35.   stufflabel(l1);
  36.   lookahead();            /* check for TRUE or FALSE */
  37.   if (class == BOOLEAN)
  38.   {
  39.     if (btv == FALSE)        /* (while FALSE (body) */
  40.     {
  41.       groan("while loop never executed.");
  42.       gojmp(JMP,ldone);
  43.     }
  44.     get_token();
  45.   }
  46.   else                /* compile (test) */
  47.     { compile(); type_check(BOOLEAN,0); gojmp(JMPFALSE,ldone); }
  48.   compile(); z = class;        /* compile (body), save result */
  49.   gojmp(JMP,l1);        /* jump back to (test) */
  50.   stufflabel(ldone);        /* next address after (body) */
  51.   breaklabel = savebl; contlabel = savecl;
  52.       /* If we did a (push-arg) and we are compiling args for a fcn
  53.        *   call, don't push RV.
  54.        * Else we don't know what RV is because of possible
  55.        *   (break)
  56.        */
  57.   return (z == PUSHEDARGS) ? PUSHEDARGS : UNKNOWN;
  58. }
  59.  
  60.     /* (for (init)(test)(inc)(body)) : a glorified while
  61.      * Compiles down to:
  62.      *    (init)
  63.      *   1: if (test) is FALSE goto 3
  64.      *    (goto 2)
  65.      *    (inc)
  66.      *   2: (body)
  67.      *    (goto 1) 
  68.      *   3:
  69.      */
  70. comp_for()
  71. {
  72.   int l1, l2, savebl = breaklabel, savecl = contlabel, z;
  73.  
  74.   l1 = genlabel(); contlabel = genlabel(); l2 = genlabel();
  75.   breaklabel = genlabel();
  76.   compile();                /* (init) */
  77.   stufflabel(l1);            /* (test) */
  78.   compile(); type_check(BOOLEAN,0); gojmp(JMPFALSE,breaklabel);
  79.   gojmp(JMP,l2);            /* jmp around (inc) */
  80.   stufflabel(contlabel); compile(); gojmp(JMP,l1);         /* (inc) */
  81.   stufflabel(l2); compile(); z = class; gojmp(JMP,contlabel);     /* (body) */
  82.   stufflabel(breaklabel);
  83.   breaklabel = savebl; contlabel = savecl;
  84.   return (z == PUSHEDARGS) ? PUSHEDARGS : UNKNOWN;    /* same as (while) */
  85. }
  86.  
  87.     /* (if (test) (t) (f))
  88.      * Compiles down to:
  89.      *    if (test) is FALSE goto 1
  90.      *    (t)
  91.      *    goto 2        ; not used if no else clause
  92.      *   1: (f)        ; not used if no else clause
  93.      *   2:            ; not used if no else clause
  94.      * Note:
  95.      *   (if () ...) means use RV for the test.
  96.      */
  97. comp_if(lastclass) unsigned int lastclass;
  98. {
  99.   int l1, l2, z;
  100.  
  101.   l1 = genlabel();
  102.   compile(); if (class == EMPTY) class = lastclass;
  103.   type_check(BOOLEAN,0); gojmp(JMPFALSE,l1);
  104.   compile(); z = class;
  105.   lookahead();                /* check for else block */
  106.   if (class == DELIMITER && *token == ')') stufflabel(l1);
  107.   else
  108.   {
  109.     l2 = genlabel();
  110.     gojmp(JMP,l2); stufflabel(l1);
  111.     compile(); if (z != class) z = UNKNOWN;
  112.     stufflabel(l2);
  113.   }
  114.   return z;
  115. }
  116.  
  117.     /* (cond (test1) (body1) (test2) (body2) ...)
  118.      * A glorified if then else if then else if then else ...
  119.      * Compiles down to:
  120.      *    if (test1) is FALSE goto 2
  121.      *    (body1)
  122.      *    goto done
  123.      *   2: if (test2) is FALSE goto 3
  124.      *    (body2)
  125.      *    goto done
  126.      *   3:
  127.      *   done:
  128.      */
  129. comp_cond()
  130. {
  131.   int l1, ldone;
  132.  
  133.   ldone = genlabel();
  134.   do
  135.   {
  136.     l1 = genlabel();
  137.     compile(); type_check(BOOLEAN,0); gojmp(JMPFALSE,l1);
  138.     compile(); gojmp(JMP,ldone);
  139.     stufflabel(l1);
  140.   }
  141.   while (gaze_ahead(BOOLEAN,0));
  142.   stufflabel(ldone);
  143.   return UNKNOWN;
  144. }
  145.  
  146.     /* (switch val  val1 (body1) val2 (body2) ... [default (dbody)])
  147.      * A simplified if then else if then else if then else
  148.      * Compiles down to:
  149.      *    push val
  150.      *    if val1 != val goto 2
  151.      *    body1
  152.      *    goto done
  153.      *   2: if val2 != val goto 3
  154.      *    body2
  155.      *    goto done
  156.      *   3:  ...
  157.      *    (dbody)        ; the default case
  158.      *   done: pop val
  159.      */
  160. comp_switch()
  161. {
  162.   int l1, ldone, z;
  163.  
  164.   ldone = genlabel();
  165.   compile(); z = class;
  166.   checkit("switch",STRING,NUMBER,BOOLEAN,0);
  167.   pushpush();
  168.   do
  169.   {
  170.     lookahead();
  171.     if (class == TOKEN && strcmp(token,"default") == 0)
  172.       { get_token(); compile(); break; }
  173.     else
  174.     {
  175.       l1 = genlabel();
  176.       genop(DUP); compile(); 
  177.       if (z != UNKNOWN) type_check(z,0);    /* yukk!!! */
  178.       genop(CMP); gojmp(JMPFALSE,l1);
  179.       compile(); gojmp(JMP,ldone);
  180.       stufflabel(l1);
  181.     }
  182.   } while (gaze_ahead(TOKEN,STRING,NUMBER,BOOLEAN,0));
  183.   stufflabel(ldone); genop(POP);
  184.   return UNKNOWN;
  185. }
  186.