Ejemplo n.º 1
0
static int ReplayTokList (void* List)
/* Function that gets the next token from a token list and sets it. This
 * function may be used together with the PushInput function from the istack
 * module.
 */
{
    /* Cast the generic pointer to an actual list */
    TokList* L = List;

    /* Last may never be a NULL pointer, otherwise there's a bug in the code */
    CHECK (L->Last != 0);

    /* Set the next token from the list */
    TokSet (L->Last);

    /* If a check function is defined, call it, so it may look at the token
     * just set and changed it as apropriate.
     */
    if (L->Check) {
	L->Check (L);
    }

    /* Set the pointer to the next token */
    L->Last = L->Last->Next;

    /* If this was the last token, decrement the repeat counter. If it goes
     * zero, delete the list and remove the function from the stack.
     */
    if (L->Last == 0) {
	if (++L->RepCount >= L->RepMax) {
	    /* Done with this list */
	    FreeTokList (L);
	    PopInput ();
	} else {
	    /* Replay one more time */
	    L->Last = L->Root;
	}
    }

    /* We have a token */
    return 1;
}
Ejemplo n.º 2
0
static int MacExpand (void* Data)
/* If we're currently expanding a macro, set the the scanner token and
 * attribute to the next value and return true. If we are not expanding
 * a macro, return false.
 */
{
    /* Cast the Data pointer to the actual data structure */
    MacExp* Mac = (MacExp*) Data;

    /* Check if we should abort this macro */
    if (DoMacAbort) {

        /* Reset the flag */
        DoMacAbort = 0;

        /* Abort any open .IF statements in this macro expansion */
        CleanupIfStack (Mac->IfSP);

        /* Terminate macro expansion */
        goto MacEnd;
    }

    /* We're expanding a macro. Check if we are expanding one of the
     * macro parameters.
     */
ExpandParam:
    if (Mac->ParamExp) {

        /* Ok, use token from parameter list */
        TokSet (Mac->ParamExp);

        /* Create new line info for this parameter token */
        if (Mac->ParamLI) {
            EndLine (Mac->ParamLI);
        }
        Mac->ParamLI = StartLine (&CurTok.Pos, LI_TYPE_MACPARAM, Mac->MacExpansions);

        /* Set pointer to next token */
        Mac->ParamExp = Mac->ParamExp->Next;

        /* Done */
        return 1;

    } else if (Mac->ParamLI) {

        /* There's still line info open from the parameter expansion - end it */
        EndLine (Mac->ParamLI);
        Mac->ParamLI = 0;

    }

    /* We're not expanding macro parameters. Check if we have tokens left from
     * the macro itself.
     */
    if (Mac->Exp) {

        /* Use next macro token */
        TokSet (Mac->Exp);

        /* Create new line info for this token */
        if (Mac->LI) {
            EndLine (Mac->LI);
        }
        Mac->LI = StartLine (&CurTok.Pos, LI_TYPE_MACRO, Mac->MacExpansions);

        /* Set pointer to next token */
        Mac->Exp = Mac->Exp->Next;

        /* Is it a request for actual parameter count? */
        if (CurTok.Tok == TOK_PARAMCOUNT) {
            CurTok.Tok  = TOK_INTCON;
            CurTok.IVal = Mac->ParamCount;
            return 1;
        }

        /* Is it the name of a macro parameter? */
        if (CurTok.Tok == TOK_MACPARAM) {

            /* Start to expand the parameter token list */
            Mac->ParamExp = Mac->Params[CurTok.IVal];

            /* Go back and expand the parameter */
            goto ExpandParam;
        }

        /* If it's an identifier, it may in fact be a local symbol */
        if ((CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) &&
            Mac->M->LocalCount) {
            /* Search for the local symbol in the list */
            unsigned Index = 0;
            IdDesc* I = Mac->M->Locals;
            while (I) {
                if (SB_Compare (&CurTok.SVal, &I->Id) == 0) {
                    /* This is in fact a local symbol, change the name. Be sure
                     * to generate a local label name if the original name was
                     * a local label, and also generate a name that cannot be
                     * generated by a user.
                     */
                    if (SB_At (&I->Id, 0) == LocalStart) {
                        /* Must generate a local symbol */
                        SB_Printf (&CurTok.SVal, "%cLOCAL-MACRO_SYMBOL-%04X",
                                   LocalStart, Mac->LocalStart + Index);
                    } else {
                        /* Global symbol */
                        SB_Printf (&CurTok.SVal, "LOCAL-MACRO_SYMBOL-%04X",
                                   Mac->LocalStart + Index);
                    }
                    break;
                }
                /* Next symbol */
                ++Index;
                I = I->Next;
            }

            /* Done */
            return 1;
        }

        /* The token was successfully set */
        return 1;
    }

    /* No more macro tokens. Do we have a final token? */
    if (Mac->Final) {

        /* Set the final token and remove it */
        TokSet (Mac->Final);
        FreeTokNode (Mac->Final);
        Mac->Final = 0;

        /* Problem: When a .define style macro is expanded within the call
         * of a classic one, the latter may be terminated and removed while
         * the expansion of the .define style macro is still active. Because
         * line info slots are "stacked", this runs into a CHECK FAILED. For
         * now, we will fix that by removing the .define style macro expansion
         * immediately, once the final token is placed. The better solution
         * would probably be to not require AllocLineInfoSlot/FreeLineInfoSlot
         * to be called in FIFO order, but this is a bigger change.
         */
        /* End of macro expansion and pop the input function */
        FreeMacExp (Mac);
        PopInput ();

        /* The token was successfully set */
        return 1;
    }

MacEnd:
    /* End of macro expansion */
    FreeMacExp (Mac);

    /* Pop the input function */
    PopInput ();

    /* No token available */
    return 0;
}
Ejemplo n.º 3
0
static int MacExpand (void* Data)
/* If we're currently expanding a macro, set the the scanner token and
 * attribute to the next value and return true. If we are not expanding
 * a macro, return false.
 */
{
    /* Cast the Data pointer to the actual data structure */
    MacExp* Mac = (MacExp*) Data;

    /* Check if we should abort this macro */
    if (DoMacAbort) {

	/* Reset the flag */
	DoMacAbort = 0;

	/* Abort any open .IF statements in this macro expansion */
	CleanupIfStack (Mac->IfSP);

	/* Terminate macro expansion */
	goto MacEnd;
    }

    /* We're expanding a macro. Check if we are expanding one of the
     * macro parameters.
     */
    if (Mac->ParamExp) {

       	/* Ok, use token from parameter list */
       	TokSet (Mac->ParamExp);

       	/* Set pointer to next token */
       	Mac->ParamExp = Mac->ParamExp->Next;

       	/* Done */
       	return 1;

    }

    /* We're not expanding macro parameters. Check if we have tokens left from
     * the macro itself.
     */
    if (Mac->Exp) {

       	/* Use next macro token */
       	TokSet (Mac->Exp);

       	/* Set pointer to next token */
       	Mac->Exp = Mac->Exp->Next;

       	/* Is it a request for actual parameter count? */
       	if (Tok == TOK_PARAMCOUNT) {
       	    Tok  = TOK_INTCON;
       	    IVal = Mac->ParamCount;
       	    return 1;
       	}

       	/* Is it the name of a macro parameter? */
       	if (Tok == TOK_MACPARAM) {

       	    /* Start to expand the parameter token list */
       	    Mac->ParamExp = Mac->Params [IVal];

       	    /* Recursive call to expand the parameter */
       	    return MacExpand (Mac);
       	}

       	/* If it's an identifier, it may in fact be a local symbol */
       	if ((Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) && Mac->M->LocalCount) {
       	    /* Search for the local symbol in the list */
       	    unsigned Index = 0;
       	    IdDesc* I = Mac->M->Locals;
       	    while (I) {
       	       	if (SB_Compare (&SVal, &I->Id) == 0) {
       	       	    /* This is in fact a local symbol, change the name. Be sure
                     * to generate a local label name if the original name was
                     * a local label, and also generate a name that cannot be
                     * generated by a user.
                     */
                    if (SB_At (&I->Id, 0) == LocalStart) {
                        /* Must generate a local symbol */
                        SB_Printf (&SVal, "%cLOCAL-MACRO_SYMBOL-%04X",
                                   LocalStart, Mac->LocalStart + Index);
                    } else {
                        /* Global symbol */
                        SB_Printf (&SVal, "LOCAL-MACRO_SYMBOL-%04X",
                                   Mac->LocalStart + Index);
                    }
       	       	    break;
       	       	}
       	       	/* Next symbol */
       	       	++Index;
       	       	I = I->Next;
       	    }

       	    /* Done */
       	    return 1;
       	}

       	/* The token was successfully set */
       	return 1;

    }

    /* No more macro tokens. Do we have a final token? */
    if (Mac->Final) {

      	/* Set the final token and remove it */
      	TokSet (Mac->Final);
      	FreeTokNode (Mac->Final);
      	Mac->Final = 0;

       	/* The token was successfully set */
       	return 1;

    }

MacEnd:
    /* End of macro expansion */
    FreeMacExp (Mac);

    /* Pop the input function */
    PopInput ();

    /* No token available */
    return 0;
}