home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- #define LOCALDEBUG 0
- #include "defines.h"
- #include "nasm.h"
- #include "labels.h"
- #include "y_tab.h"
- #include "debug.h"
- #include "buffer.h"
- #if LOCALDEBUG
- #include <stdio.h>
- #endif
-
- #define STKSIZE 1024 /* nesting depth */
-
- #if __NSTDC__
- static void ignore( void);
- #else
- static void ignore();
- #endif
-
- int _in_if;
- static char stack[ STKSIZE],
- *s = stack,
- nest[] = "Too many nested .IFs",
- spls[] = ".ELSE or .ENDIF w/o a leading .IF";
- extern buffer huge *bp;
-
- #if ! VERSION
- void vpushchk()
- {
- if( s == stack + STKSIZE)
- nferror( nest);
- }
-
- int push( v)
- int v;
- {
- ENTER("push");
- IMESS("Pushing %d", (lword) v, 2);
- LEAVE();
- return( (int) (*s++ = v));
- }
-
- #define vpush( v) vpushchk(); push( v)
-
- void vpopchk()
- {
- if( s == stack)
- {
- *(s = stack+1) = 1;
- nerror( spls);
- }
- }
-
- char pop()
- {
- ENTER("pop");
- IMESS("returning %d", (lword) s[-1], 2);
- LEAVE();
- return( *--s);
- }
-
- void dpop()
- {
- ENTER("dpop");
- MESS("just adjusting the stack");
- s--;
- LEAVE();
- }
-
- char look()
- {
- ENTER("look");
- IMESS("returning %d", (lword) s[-1], 2);
- LEAVE();
- return( s[-1]);
- }
-
- void mark()
- {
- ENTER("mark");
- s[-1] |= 0x80;
- LEAVE();
- }
-
- int ismarked()
- {
- ENTER("ismarked");
- IMESS("returning %d", (lword) s[-1] < 0, 2);
- LEAVE();
- return( s[-1] < 0);
- }
-
- #if LOCALDEBUG
- void dump_stack()
- {
- char *p = stack;
-
- if( p == s)
- fprintf( ESTREAM, "Stack empty\n");
- else
- {
- do
- putc( '0' + *p, ESTREAM);
- while( ++p < s);
- putc( '\n', ESTREAM);
- }
- }
- #endif
- # else
- #define vpushchk() if( s == stack + STKSIZE) nferror( nest)
- #define push( v) *s++ = v
- #define vpush( v) vpushchk(); push( v)
-
- #define vpopchk() if( s == stack) { *(s = stack+1) = 1; nerror( spls); return; }
- #define pop() *--s
- #define dpop() s--
-
- #define look() s[-1]
- #define mark() s[-1] |= 0x80
- #define ismarked() s[-1] < 0
-
- #define dump_stack()
- #endif
-
-
-
- void if_treat( e)
- register expr *e;
- {
- ENTER("if_treat");
- vpushchk();
- if( unvalued( e))
- {
- nerror("Forward ref in .IF <expression>");
- push( 0); /* for a following possible .ELSE */
- LEAVE();
- return;
- }
- if( ! (push( e->val ? 1 : 0)))
- ignore();
- LEAVE();
- }
-
- void else_treat()
- {
- ENTER("else_treat");
- if( ismarked())
- nerror(".ELSE belonging to noone found");
- else
- {
- mark();
- ignore();
- }
- LEAVE();
- }
-
-
- void endif_treat()
- {
- ENTER("endif_treat");
- vpopchk();
- dpop();
- LEAVE();
- }
-
-
- static void ignore()
- {
- extern word freshflag;
- #if LOCALDEBUG
- register int tok;
- #endif
-
- ENTER("ignore");
- _in_if = 1;
- for(;;)
- {
- #if LOCALDEBUG
- dump_stack();
- tok = yylex();
- prtname( tok);
- switch( tok)
- #else
- freshflag = 1;
- switch( yylex())
- #endif
- {
- case 0 :
- nwarning("Matching .ENDIF not encountered");
- _in_if = 0;
- LEAVE();
- return;
-
- case T_EOL:
- inc_line();
- break;
-
- case T_IF :
- vpush( 2);
- break;
-
- case T_ELSE :
- if( ismarked())
- nwarning("Garbage .ELSE ignored");
- else
- {
- if( look() != 2)
- {
- mark();
- _in_if = 0;
- LEAVE();
- freshflag = 1;
- return;
- }
- mark();
- }
- break;
-
- case T_ENDIF :
- vpopchk();
- if( (pop() & 0x3) != 2)
- {
- _in_if = 0;
- LEAVE();
- return;
- }
- }
- }
- }
-
-