/* ---------------------------------------------------------------------- */ /* 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 #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 "); 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; } } } }