Ejemplo n.º 1
0
void InsertMacro(CMacro* Macro, std::wstring& Args)
{
	tTextData Text;
	ArgumentList Arguments;

	splitArguments(Arguments,Args);

	if ((int)Arguments.size() != Macro->getArgumentCount())
	{
		Logger::printError(Logger::Error,L"%s macro arguments (%d vs %d)",
			(int)Arguments.size() > Macro->getArgumentCount() ? L"Too many" : L"Not enough",
			Arguments.size(),Macro->getArgumentCount());
		return;
	}

	Global.MacroNestingLevel++;
	if (Global.MacroNestingLevel == ASSEMBLER_MACRO_NESTING_LEVEL)
	{
		Logger::printError(Logger::Error,L"Maximum macro nesting level reached");
		return;
	}

	int MacroCounter = Macro->getIncreaseCounter();

	for (int i = 0; i < Macro->getLineCount(); i++)
	{
		Text.buffer = Macro->getLine(i,Arguments,MacroCounter);
		Text.buffer = Global.symbolTable.insertEquations(Text.buffer,Global.FileInfo.FileNum,Global.Section);

		if (CheckEquLabel(Text.buffer) == false)
		{
			Text.buffer = checkLabel(Text.buffer,false);
			splitLine(Text.buffer,Text.name,Text.params);
			if (Text.name.size() == 0) continue;

			bool macro = false;
			for (size_t i = 0; i < Global.Macros.size(); i++)
			{
				if (Text.name.compare(Global.Macros[i]->getName()) == 0)
				{
					InsertMacro(Global.Macros[i],Text.params);
					macro = true;
				}
			}
			if (macro == true) continue;

			if (Arch->AssembleDirective(Text.name,Text.params) == false)
			{
				Arch->AssembleOpcode(Text.name,Text.params);
			}
		}
	}
	Global.MacroNestingLevel--;
}
Ejemplo n.º 2
0
bool ParseMacro(TextFile& Input, std::wstring& opcodeName, std::wstring& Args)
{
	if (opcodeName.compare(L".macro") == 0)
	{
		parseMacroDefinition(Input,Args);
		return true;
	}

	for (size_t i = 0; i < Global.Macros.size(); i++)
	{
		if (opcodeName.compare(Global.Macros[i]->getName()) == 0)
		{
			Global.MacroNestingLevel = 0;
			InsertMacro(Global.Macros[i],Args);
			return true;
		}
	}
	return false;
}
Ejemplo n.º 3
0
static void DefineMacro (void)
/* Handle a macro definition. */
{
    ident       Ident;
    Macro*      M;
    Macro*      Existing;
    int         C89;

    /* Read the macro name */
    SkipWhitespace (0);
    if (!MacName (Ident)) {
        return;
    }

    /* Remember if we're in C89 mode */
    C89 = (IS_Get (&Standard) == STD_C89);

    /* Get an existing macro definition with this name */
    Existing = FindMacro (Ident);

    /* Create a new macro definition */
    M = NewMacro (Ident);

    /* Check if this is a function like macro */
    if (CurC == '(') {

        /* Skip the left paren */
        NextChar ();

        /* Set the marker that this is a function like macro */
        M->ArgCount = 0;

        /* Read the formal parameter list */
        while (1) {

            /* Skip white space and check for end of parameter list */
            SkipWhitespace (0);
            if (CurC == ')') {
                break;
            }

            /* The next token must be either an identifier, or - if not in
             * C89 mode - the ellipsis.
             */
            if (!C89 && CurC == '.') {
                /* Ellipsis */
                NextChar ();
                if (CurC != '.' || NextC != '.') {
                    PPError ("`...' expected");
                    ClearLine ();
                    return;
                }
                NextChar ();
                NextChar ();

                /* Remember that the macro is variadic and use __VA_ARGS__ as
                 * the argument name.
                 */
                AddMacroArg (M, "__VA_ARGS__");
                M->Variadic = 1;

            } else {
                /* Must be macro argument name */
                if (MacName (Ident) == 0) {
                    return;
                }

                /* __VA_ARGS__ is only allowed in C89 mode */
                if (!C89 && strcmp (Ident, "__VA_ARGS__") == 0) {
                    PPWarning ("`__VA_ARGS__' can only appear in the expansion "
                               "of a C99 variadic macro");
                }

                /* Add the macro argument */
                AddMacroArg (M, Ident);
            }

            /* If we had an ellipsis, or the next char is not a comma, we've
             * reached the end of the macro argument list.
             */
            SkipWhitespace (0);
            if (M->Variadic || CurC != ',') {
                break;
            }
            NextChar ();
        }

        /* Check for a right paren and eat it if we find one */
        if (CurC != ')') {
            PPError ("`)' expected");
            ClearLine ();
            return;
        }
        NextChar ();
    }

    /* Skip whitespace before the macro replacement */
    SkipWhitespace (0);

    /* Insert the macro into the macro table and allocate the ActualArgs array */
    InsertMacro (M);

    /* Remove whitespace and comments from the line, store the preprocessed
     * line into the macro replacement buffer.
     */
    Pass1 (Line, &M->Replacement);

    /* Remove whitespace from the end of the line */
    while (IsSpace (SB_LookAtLast (&M->Replacement))) {
        SB_Drop (&M->Replacement, 1);
    }
#if 0
    printf ("%s: <%.*s>\n", M->Name, SB_GetLen (&M->Replacement), SB_GetConstBuf (&M->Replacement));
#endif

    /* If we have an existing macro, check if the redefinition is identical.
     * Print a diagnostic if not.
     */
    if (Existing && MacroCmp (M, Existing) != 0) {
        PPError ("Macro redefinition is not identical");
    }
}