Esempio n. 1
0
void MacExpandStart (Macro* M)
/* Start expanding a macro */
{
    MacExp* E;

    /* Check the argument */
    PRECONDITION (M && (M->Style != MAC_STYLE_DEFINE || DisableDefines == 0));

    /* We cannot expand an incomplete macro */
    if (M->Incomplete) {
        Error ("Cannot expand an incomplete macro");
        return;
    }

    /* Don't allow too many nested macro expansions - otherwise it is possible
     * to force an endless loop and assembler crash.
     */
    if (MacExpansions >= MAX_MACEXPANSIONS) {
        Error ("Too many nested macro expansions");
        return;
    }

    /* Create a structure holding expansion data */
    E = NewMacExp (M);

    /* Call the apropriate subroutine */
    switch (M->Style) {
        case MAC_STYLE_CLASSIC: StartExpClassic (E);    break;
        case MAC_STYLE_DEFINE:  StartExpDefine (E);     break;
        default:                Internal ("Invalid macro style: %d", M->Style);
    }
}
Esempio n. 2
0
static void StartExpDefine (Macro* M)
/* Start expanding a DEFINE style macro */
{
    /* Create a structure holding expansion data */
    MacExp* E = NewMacExp (M);

    /* A define style macro must be called with as many actual parameters
     * as there are formal ones. Get the parameter count.
     */
    unsigned Count = M->ParamCount;

    /* Skip the current token */
    NextTok ();

    /* Read the actual parameters */
    while (Count--) {

       	TokNode*   Last;

        /* The macro may optionally be enclosed in curly braces */
        Token Term = GetTokListTerm (TOK_COMMA);

       	/* Check if there is really a parameter */
       	if (TokIsSep (Tok) || Tok == Term) {
            ErrorSkip ("Macro parameter #%u is empty", E->ParamCount+1);
            FreeMacExp (E);
            return;
        }

       	/* Read tokens for one parameter */
       	Last = 0;
       	do {

       	    TokNode* T;

       	    /* Get the next token in a node */
       	    T = NewTokNode ();

       	    /* Insert it into the list */
       	    if (Last == 0) {
       	    	E->Params [E->ParamCount] = T;
       	    } else {
       	    	Last->Next = T;
       	    }
       	    Last = T;

	    /* And skip it... */
	    NextTok ();

       	} while (Tok != Term && !TokIsSep (Tok));

	/* One parameter more */
	++E->ParamCount;

        /* If the macro argument was enclosed in curly braces, end-of-line
         * is an error. Skip the closing curly brace.
         */
        if (Term == TOK_RCURLY) {
            if (TokIsSep (Tok)) {
                Error ("End of line encountered within macro argument");
                break;
            }
            NextTok ();
        }

       	/* Check for a comma */
       	if (Count > 0) {
       	    if (Tok == TOK_COMMA) {
       	        NextTok ();
       	    } else {
       		Error ("`,' expected");
       	    }
       	}
    }

    /* Macro expansion will overwrite the current token. This is a problem
     * for define style macros since these are called from the scanner level.
     * To avoid it, remember the current token and re-insert it, once macro
     * expansion is done.
     */
    E->Final = NewTokNode ();

    /* Insert a new token input function */
    PushInput (MacExpand, E, ".DEFINE");
}
Esempio n. 3
0
static void StartExpClassic (Macro* M)
/* Start expanding the classic macro M */
{
    MacExp*     E;
    Token       Term;


    /* Skip the macro name */
    NextTok ();

    /* Create a structure holding expansion data */
    E = NewMacExp (M);

    /* Read the actual parameters */
    while (!TokIsSep (Tok)) {

	TokNode* Last;

       	/* Check for maximum parameter count */
	if (E->ParamCount >= M->ParamCount) {
       	    ErrorSkip ("Too many macro parameters");
	    break;
	}

        /* The macro may optionally be enclosed in curly braces */
        Term = GetTokListTerm (TOK_COMMA);

       	/* Read tokens for one parameter, accept empty params */
	Last = 0;
	while (Tok != Term && Tok != TOK_SEP) {

	    TokNode* T;

	    /* Check for end of file */
	    if (Tok == TOK_EOF) {
	     	Error ("Unexpected end of file");
                FreeMacExp (E);
	     	return;
	    }

	    /* Get the next token in a node */
	    T = NewTokNode ();

	    /* Insert it into the list */
	    if (Last == 0) {
	      	E->Params [E->ParamCount] = T;
	    } else {
	     	Last->Next = T;
	    }
	    Last = T;

	    /* And skip it... */
	    NextTok ();
	}

	/* One parameter more */
	++E->ParamCount;

        /* If the macro argument was enclosed in curly braces, end-of-line
         * is an error. Skip the closing curly brace.
         */
        if (Term == TOK_RCURLY) {
            if (Tok == TOK_SEP) {
                Error ("End of line encountered within macro argument");
                break;
            }
            NextTok ();
        }

	/* Check for a comma */
	if (Tok == TOK_COMMA) {
 	    NextTok ();
 	} else {
 	    break;
 	}
    }

    /* We must be at end of line now, otherwise something is wrong */
    ExpectSep ();

    /* Insert a new token input function */
    PushInput (MacExpand, E, ".MACRO");
}