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