home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume5 / smallc / part2 / stmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  6.5 KB  |  426 lines

  1. /*    File stmt.c: 2.1 (83/03/20,16:02:17) */
  2. /*% cc -O -c %
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "defs.h"
  8. #include "data.h"
  9.  
  10. /*
  11.  *    statement parser
  12.  *
  13.  *    called whenever syntax requires a statement.  this routine
  14.  *    performs that statement and returns a number telling which one
  15.  *
  16.  *    'func' is true if we require a "function_statement", which
  17.  *    must be compound, and must contain "statement_list" (even if
  18.  *    "declaration_list" is omitted)
  19.  */
  20.  
  21. statement (func)
  22. int    func;
  23. {
  24.     if ((ch () == 0) & feof (input))
  25.         return (0);
  26.     lastst = 0;
  27.     if (func)
  28.         if (match ("{")) {
  29.             compound (YES);
  30.             return (lastst);
  31.         } else
  32.             error ("function requires compound statement");
  33.     if (match ("{"))
  34.         compound (NO);
  35.     else
  36.         stst ();
  37.     return (lastst);
  38. }
  39.  
  40. /*
  41.  *    declaration
  42.  */
  43. stdecl ()
  44. {
  45.     if (amatch("register", 8))
  46.         doldcls(DEFAUTO);
  47.     else if (amatch("auto", 4))
  48.         doldcls(DEFAUTO);
  49.     else if (amatch("static", 6))
  50.         doldcls(LSTATIC);
  51.     else if (doldcls(AUTO)) ;
  52.     else
  53.         return (NO);
  54.     return (YES);
  55. }
  56.  
  57. doldcls(stclass)
  58. int    stclass;
  59. {
  60.     blanks();
  61.     if (amatch("char", 4))
  62.         declloc(CCHAR, stclass);
  63.     else if (amatch("int", 3))
  64.         declloc(CINT, stclass);
  65.     else if (stclass == LSTATIC || stclass == DEFAUTO)
  66.         declloc(CINT, stclass);
  67.     else
  68.         return(0);
  69.     ns();
  70.     return(1);
  71. }
  72.  
  73.  
  74. /*
  75.  *    non-declaration statement
  76.  */
  77. stst ()
  78. {
  79.     if (amatch ("if", 2)) {
  80.         doif ();
  81.         lastst = STIF;
  82.     } else if (amatch ("while", 5)) {
  83.         dowhile ();
  84.         lastst = STWHILE;
  85.     } else if (amatch ("switch", 6)) {
  86.         doswitch ();
  87.         lastst = STSWITCH;
  88.     } else if (amatch ("do", 2)) {
  89.         dodo ();
  90.         ns ();
  91.         lastst = STDO;
  92.     } else if (amatch ("for", 3)) {
  93.         dofor ();
  94.         lastst = STFOR;
  95.     } else if (amatch ("return", 6)) {
  96.         doreturn ();
  97.         ns ();
  98.         lastst = STRETURN;
  99.     } else if (amatch ("break", 5)) {
  100.         dobreak ();
  101.         ns ();
  102.         lastst = STBREAK;
  103.     } else if (amatch ("continue", 8)) {
  104.         docont ();
  105.         ns ();
  106.         lastst = STCONT;
  107.     } else if (match (";"))
  108.         ;
  109.     else if (amatch ("case", 4)) {
  110.         docase ();
  111.         lastst = statement (NO);
  112.     } else if (amatch ("default", 7)) {
  113.         dodefault ();
  114.         lastst = statement (NO);
  115.     } else if (match ("#asm")) {
  116.         doasm ();
  117.         lastst = STASM;
  118.     } else if (match ("{"))
  119.         compound (NO);
  120.     else {
  121.         expression (YES);
  122. /*        if (match (":")) {
  123.             dolabel ();
  124.             lastst = statement (NO);
  125.         } else {
  126. */            ns ();
  127.             lastst = STEXP;
  128. /*        }
  129. */    }
  130. }
  131.  
  132. /*
  133.  *    compound statement
  134.  *
  135.  *    allow any number of statements to fall between "{" and "}"
  136.  *
  137.  *    'func' is true if we are in a "function_statement", which
  138.  *    must contain "statement_list"
  139.  */
  140. compound (func)
  141. int    func;
  142. {
  143.     int    decls;
  144.  
  145.     decls = YES;
  146.     ncmp++;
  147.     while (!match ("}")) {
  148.         if (feof (input))
  149.             return;
  150.         if (decls) {
  151.             if (!stdecl ())
  152.                 decls = NO;
  153.         } else
  154.             stst ();
  155.     }
  156.     ncmp--;
  157. }
  158.  
  159. /*
  160.  *    "if" statement
  161.  */
  162. doif ()
  163. {
  164.     int    fstkp, flab1, flab2;
  165.     char    *flev;
  166.  
  167.     flev = locptr;
  168.     fstkp = stkp;
  169.     flab1 = getlabel ();
  170.     test (flab1, FALSE);
  171.     statement (NO);
  172.     stkp = modstk (fstkp);
  173.     locptr = flev;
  174.     if (!amatch ("else", 4)) {
  175.         gnlabel (flab1);
  176.         return;
  177.     }
  178.     jump (flab2 = getlabel ());
  179.     gnlabel (flab1);
  180.     statement (NO);
  181.     stkp = modstk (fstkp);
  182.     locptr = flev;
  183.     gnlabel (flab2);
  184. }
  185.  
  186. /*
  187.  *    "while" statement
  188.  */
  189. dowhile ()
  190. {
  191.     int    ws[7];
  192.  
  193.     ws[WSSYM] = locptr;
  194.     ws[WSSP] = stkp;
  195.     ws[WSTYP] = WSWHILE;
  196.     ws[WSTEST] = getlabel ();
  197.     ws[WSEXIT] = getlabel ();
  198.     addwhile (ws);
  199.     gnlabel (ws[WSTEST]);
  200.     test (ws[WSEXIT], FALSE);
  201.     statement (NO);
  202.     jump (ws[WSTEST]);
  203.     gnlabel (ws[WSEXIT]);
  204.     locptr = ws[WSSYM];
  205.     stkp = modstk (ws[WSSP]);
  206.     delwhile ();
  207. }
  208.  
  209. /*
  210.  *    "do" statement
  211.  */
  212. dodo ()
  213. {
  214.     int    ws[7];
  215.  
  216.     ws[WSSYM] = locptr;
  217.     ws[WSSP] = stkp;
  218.     ws[WSTYP] = WSDO;
  219.     ws[WSBODY] = getlabel ();
  220.     ws[WSTEST] = getlabel ();
  221.     ws[WSEXIT] = getlabel ();
  222.     addwhile (ws);
  223.     gnlabel (ws[WSBODY]);
  224.     statement (NO);
  225.     if (!match ("while")) {
  226.         error ("missing while");
  227.         return;
  228.     }
  229.     gnlabel (ws[WSTEST]);
  230.     test (ws[WSBODY], TRUE);
  231.     gnlabel (ws[WSEXIT]);
  232.     locptr = ws[WSSYM];
  233.     stkp = modstk (ws[WSSP]);
  234.     delwhile ();
  235. }
  236.  
  237. /*
  238.  *    "for" statement
  239.  */
  240. dofor ()
  241. {
  242.     int    ws[7],
  243.         *pws;
  244.  
  245.     ws[WSSYM] = locptr;
  246.     ws[WSSP] = stkp;
  247.     ws[WSTYP] = WSFOR;
  248.     ws[WSTEST] = getlabel ();
  249.     ws[WSINCR] = getlabel ();
  250.     ws[WSBODY] = getlabel ();
  251.     ws[WSEXIT] = getlabel ();
  252.     addwhile (ws);
  253.     pws = readwhile ();
  254.     needbrack ("(");
  255.     if (!match (";")) {
  256.         expression (YES);
  257.         ns ();
  258.     }
  259.     gnlabel (pws[WSTEST]);
  260.     if (!match (";")) {
  261.         expression (YES);
  262.         testjump (pws[WSBODY], TRUE);
  263.         jump (pws[WSEXIT]);
  264.         ns ();
  265.     } else
  266.         pws[WSTEST] = pws[WSBODY];
  267.     gnlabel (pws[WSINCR]);
  268.     if (!match (")")) {
  269.         expression (YES);
  270.         needbrack (")");
  271.         jump (pws[WSTEST]);
  272.     } else
  273.         pws[WSINCR] = pws[WSTEST];
  274.     gnlabel (pws[WSBODY]);
  275.     statement (NO);
  276.     jump (pws[WSINCR]);
  277.     gnlabel (pws[WSEXIT]);
  278.     locptr = pws[WSSYM];
  279.     stkp = modstk (pws[WSSP]);
  280.     delwhile ();
  281. }
  282.  
  283. /*
  284.  *    "switch" statement
  285.  */
  286. doswitch ()
  287. {
  288.     int    ws[7];
  289.     int    *ptr;
  290.  
  291.     ws[WSSYM] = locptr;
  292.     ws[WSSP] = stkp;
  293.     ws[WSTYP] = WSSWITCH;
  294.     ws[WSCASEP] = swstp;
  295.     ws[WSTAB] = getlabel ();
  296.     ws[WSDEF] = ws[WSEXIT] = getlabel ();
  297.     addwhile (ws);
  298.     immed ();
  299.     printlabel (ws[WSTAB]);
  300.     nl ();
  301.     gpush ();
  302.     needbrack ("(");
  303.     expression (YES);
  304.     needbrack (")");
  305.     stkp = stkp + intsize();  /* '?case' will adjust the stack */
  306.     gjcase ();
  307.     statement (NO);
  308.     ptr = readswitch ();
  309.     jump (ptr[WSEXIT]);
  310.     dumpsw (ptr);
  311.     gnlabel (ptr[WSEXIT]);
  312.     locptr = ptr[WSSYM];
  313.     stkp = modstk (ptr[WSSP]);
  314.     swstp = ptr[WSCASEP];
  315.     delwhile ();
  316. }
  317.  
  318. /*
  319.  *    "case" label
  320.  */
  321. docase ()
  322. {
  323.     int    val;
  324.  
  325.     val = 0;
  326.     if (readswitch ()) {
  327.         if (!number (&val))
  328.             if (!pstr (&val))
  329.                 error ("bad case label");
  330.         addcase (val);
  331.         if (!match (":"))
  332.             error ("missing colon");
  333.     } else
  334.         error ("no active switch");
  335. }
  336.  
  337. /*
  338.  *    "default" label
  339.  */
  340. dodefault ()
  341. {
  342.     int    *ptr,
  343.         lab;
  344.  
  345.     if (ptr = readswitch ()) {
  346.         ptr[WSDEF] = lab = getlabel ();
  347.         gnlabel (lab);
  348.         if (!match (":"))
  349.             error ("missing colon");
  350.     } else
  351.         error ("no active switch");
  352. }
  353.  
  354. /*
  355.  *    "return" statement
  356.  */
  357. doreturn ()
  358. {
  359.     if (endst () == 0)
  360.         expression (YES);
  361.     jump(fexitlab);
  362. }
  363.  
  364. /*
  365.  *    "break" statement
  366.  */
  367. dobreak ()
  368. {
  369.     int    *ptr;
  370.  
  371.     if ((ptr = readwhile ()) == 0)
  372.         return;
  373.     modstk (ptr[WSSP]);
  374.     jump (ptr[WSEXIT]);
  375. }
  376.  
  377. /*
  378.  *    "continue" statement
  379.  */
  380. docont ()
  381. {
  382.     int    *ptr;
  383.  
  384.     if ((ptr = findwhile ()) == 0)
  385.         return;
  386.     modstk (ptr[WSSP]);
  387.     if (ptr[WSTYP] == WSFOR)
  388.         jump (ptr[WSINCR]);
  389.     else
  390.         jump (ptr[WSTEST]);
  391. }
  392.  
  393. /*
  394.  *    dump switch table
  395.  */
  396. dumpsw (ws)
  397. int    ws[];
  398. {
  399.     int    i,j;
  400.  
  401.     gdata ();
  402.     gnlabel (ws[WSTAB]);
  403.     if (ws[WSCASEP] != swstp) {
  404.         j = ws[WSCASEP];
  405.         while (j < swstp) {
  406.             defword ();
  407.             i = 4;
  408.             while (i--) {
  409.                 onum (swstcase[j]);
  410.                 outbyte (',');
  411.                 printlabel (swstlab[j++]);
  412.                 if ((i == 0) | (j >= swstp)) {
  413.                     nl ();
  414.                     break;
  415.                 }
  416.                 outbyte (',');
  417.             }
  418.         }
  419.     }
  420.     defword ();
  421.     printlabel (ws[WSDEF]);
  422.     outstr (",0");
  423.     nl ();
  424.     gtext ();
  425. }
  426.