home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / if.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  4KB  |  236 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LOCALDEBUG   0
  7. #include "defines.h"
  8. #include "nasm.h"
  9. #include "labels.h"
  10. #include "y_tab.h"
  11. #include "debug.h"
  12. #include "buffer.h"
  13. #if LOCALDEBUG
  14. #include <stdio.h>
  15. #endif
  16.  
  17. #define STKSIZE  1024       /* nesting depth */
  18.  
  19. #if __NSTDC__
  20. static void   ignore( void);
  21. #else
  22. static void   ignore();
  23. #endif
  24.  
  25. int            _in_if;
  26. static char    stack[ STKSIZE],
  27.                *s = stack,
  28.                nest[] = "Too many nested .IFs",
  29.                spls[] = ".ELSE or .ENDIF w/o a leading .IF";
  30. extern buffer huge   *bp;
  31.  
  32. #if ! VERSION
  33. void vpushchk()
  34. {
  35.    if( s == stack + STKSIZE)
  36.       nferror( nest);
  37. }
  38.  
  39. int push( v)
  40. int   v;
  41. {
  42.    ENTER("push");
  43.    IMESS("Pushing %d", (lword) v, 2);
  44.    LEAVE();
  45.    return( (int) (*s++ = v));
  46. }
  47.  
  48. #define vpush( v)    vpushchk(); push( v)
  49.  
  50. void vpopchk()
  51. {
  52.    if( s == stack)
  53.    {
  54.       *(s = stack+1) = 1;
  55.       nerror( spls);
  56.    }
  57. }
  58.  
  59. char pop()
  60. {
  61.    ENTER("pop");
  62.    IMESS("returning %d", (lword) s[-1], 2);
  63.    LEAVE();
  64.    return( *--s);
  65. }
  66.  
  67. void dpop()
  68. {
  69.    ENTER("dpop");
  70.    MESS("just adjusting the stack");
  71.    s--;
  72.    LEAVE();
  73. }
  74.  
  75. char look()
  76. {
  77.    ENTER("look");
  78.    IMESS("returning %d", (lword) s[-1], 2);
  79.    LEAVE();
  80.    return( s[-1]);
  81. }
  82.  
  83. void mark()
  84. {
  85.    ENTER("mark");
  86.    s[-1] |= 0x80;
  87.    LEAVE();
  88. }
  89.  
  90. int ismarked()
  91. {
  92.    ENTER("ismarked");
  93.    IMESS("returning %d", (lword) s[-1] < 0, 2);
  94.    LEAVE();
  95.    return( s[-1] < 0);
  96. }
  97.  
  98. #if LOCALDEBUG
  99. void  dump_stack()
  100. {
  101.    char  *p = stack;
  102.  
  103.    if( p == s)
  104.       fprintf( ESTREAM, "Stack empty\n");
  105.    else
  106.    {
  107.       do
  108.         putc( '0' + *p, ESTREAM);
  109.       while( ++p < s);
  110.       putc( '\n', ESTREAM);
  111.    }
  112. }
  113. #endif
  114. # else
  115. #define vpushchk()   if( s == stack + STKSIZE) nferror( nest)
  116. #define push( v)     *s++ = v
  117. #define vpush( v)    vpushchk(); push( v)
  118.  
  119. #define vpopchk()    if( s == stack) { *(s = stack+1) = 1; nerror( spls); return; }
  120. #define pop()        *--s
  121. #define dpop()       s--
  122.  
  123. #define look()       s[-1]
  124. #define mark()       s[-1] |= 0x80
  125. #define ismarked()   s[-1] < 0
  126.  
  127. #define dump_stack()
  128. #endif
  129.  
  130.  
  131.  
  132. void   if_treat( e)
  133. register expr  *e;
  134. {
  135.    ENTER("if_treat");
  136.    vpushchk();
  137.    if( unvalued( e))
  138.    {
  139.       nerror("Forward ref in .IF <expression>");
  140.       push( 0);     /* for a following possible .ELSE */
  141.       LEAVE();
  142.       return;
  143.    }
  144.    if( ! (push( e->val ? 1 : 0)))
  145.       ignore();
  146.    LEAVE();
  147. }
  148.  
  149. void   else_treat()
  150. {
  151.    ENTER("else_treat");
  152.    if( ismarked())
  153.       nerror(".ELSE belonging to noone found");
  154.    else
  155.    {
  156.       mark();
  157.       ignore();
  158.    }
  159.    LEAVE();
  160. }
  161.  
  162.  
  163. void   endif_treat()
  164. {
  165.    ENTER("endif_treat");
  166.    vpopchk();
  167.    dpop();
  168.    LEAVE();
  169. }
  170.  
  171.  
  172. static void    ignore()
  173. {
  174.    extern word freshflag;
  175. #if LOCALDEBUG
  176.    register int   tok;
  177. #endif
  178.  
  179.    ENTER("ignore");
  180.    _in_if = 1;
  181.    for(;;)
  182.    {
  183. #if LOCALDEBUG
  184.       dump_stack();
  185.       tok = yylex();
  186.       prtname( tok);
  187.       switch( tok)
  188. #else
  189.       freshflag = 1;
  190.       switch( yylex())
  191. #endif
  192.       {
  193.          case 0    :
  194.             nwarning("Matching .ENDIF not encountered");
  195.             _in_if = 0;
  196.             LEAVE();
  197.             return;
  198.  
  199.          case T_EOL:
  200.             inc_line();
  201.             break;
  202.  
  203.          case T_IF :
  204.             vpush( 2);
  205.             break;
  206.  
  207.          case T_ELSE :
  208.             if( ismarked())
  209.                nwarning("Garbage .ELSE ignored");
  210.             else
  211.             {
  212.                if( look() != 2)
  213.                {
  214.                   mark();
  215.                   _in_if = 0;
  216.                   LEAVE();
  217.                   freshflag = 1;
  218.                   return;
  219.                }
  220.                mark();
  221.             }
  222.             break;
  223.  
  224.          case T_ENDIF :
  225.             vpopchk();
  226.             if( (pop() & 0x3) != 2)
  227.             {
  228.                _in_if = 0;
  229.                LEAVE();
  230.                return;
  231.             }
  232.       }
  233.    }
  234. }
  235.  
  236.