Ejemplo n.º 1
0
static void MacSkipDef (unsigned Style)
/* Skip a macro definition */
{
    if (Style == MAC_STYLE_CLASSIC) {
        /* Skip tokens until we reach the final .endmacro */
        while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
            NextTok ();
        }
        if (CurTok.Tok != TOK_EOF) {
            SkipUntilSep ();
        } else {
            Error ("`.ENDMACRO' expected");
        }
    } else {
        /* Skip until end of line */
        SkipUntilSep ();
    }
}
Ejemplo n.º 2
0
static int LookAtStrCon (void)
/* Make sure the next token is a string constant. If not, print an error
 * messages skip the remainder of the line and return false. Otherwise return
 * true.
 */
{
    if (CurTok.Tok != TOK_STRCON) {
        Error ("String constant expected");
        SkipUntilSep ();
        return 0;
    } else {
        return 1;
    }
}
Ejemplo n.º 3
0
void ErrorSkip (const char* Format, ...)
/* Print an error message and skip the rest of the line */
{
    va_list ap;
    Collection LineInfos = STATIC_COLLECTION_INITIALIZER;

    /* Get line infos for the current position */
    GetFullLineInfo (&LineInfos);

    /* Output the message */
    va_start (ap, Format);
    ErrorMsg (&LineInfos, Format, ap);
    va_end (ap);

    /* Free the line info list */
    ReleaseFullLineInfo (&LineInfos);
    DoneCollection (&LineInfos);

    /* Skip tokens until we reach the end of the line */
    SkipUntilSep ();
}
Ejemplo n.º 4
0
static void InvalidFormatString (void)
/* Print an error message and skip the remainder of the line */
{
    Error ("Invalid format string");
    SkipUntilSep ();
}
Ejemplo n.º 5
0
static void NoIdent (void)
/* Print an error message and skip the remainder of the line */
{
    Error ("Argument of .IDENT is not a valid identifier");
    SkipUntilSep ();
}
Ejemplo n.º 6
0
void DoConditionals (void)
/* Catch all for conditional directives */
{
    IfDesc* D;

    do {

        switch (CurTok.Tok) {

            case TOK_ELSE:
                D = GetCurrentIf ();

                /* Allow an .ELSE */
                ElseClause (D, ".ELSE");

                /* Remember the data for the .ELSE */
                if (D) {
                    ReleaseFullLineInfo (&D->LineInfos);
                    GetFullLineInfo (&D->LineInfos);
                    D->Name = ".ELSE";
                }

                /* Calculate the new overall condition */
                CalcOverallIfCond ();

                /* Skip .ELSE */
                NextTok ();
                ExpectSep ();
                break;

            case TOK_ELSEIF:
                D = GetCurrentIf ();
                /* Handle as if there was an .ELSE first */
                ElseClause (D, ".ELSEIF");

                /* Calculate the new overall if condition */
                CalcOverallIfCond ();

                /* Allocate and prepare a new descriptor */
                D = AllocIf (".ELSEIF", 0);
                NextTok ();

                /* Ignore the new condition if we are inside a false .ELSE
                ** branch. This way we won't get any errors about undefined
                ** symbols or similar...
                */
                if (IfCond) {
                    SetIfCond (D, ConstExpression ());
                    ExpectSep ();
                }

                /* Get the new overall condition */
                CalcOverallIfCond ();
                break;

            case TOK_ENDIF:
                /* We're done with this .IF.. - remove the descriptor(s) */
                FreeIf ();

                /* Be sure not to read the next token until the .IF stack
                ** has been cleanup up, since we may be at end of file.
                */
                NextTok ();
                ExpectSep ();

                /* Get the new overall condition */
                CalcOverallIfCond ();
                break;

            case TOK_IF:
                D = AllocIf (".IF", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, ConstExpression ());
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFBLANK:
                D = AllocIf (".IFBLANK", 1);
                NextTok ();
                if (IfCond) {
                    if (TokIsSep (CurTok.Tok)) {
                        SetIfCond (D, 1);
                    } else {
                        SetIfCond (D, 0);
                        SkipUntilSep ();
                    }
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFCONST:
                D = AllocIf (".IFCONST", 1);
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
                    SetIfCond (D, IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFDEF:
                D = AllocIf (".IFDEF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym != 0 && SymIsDef (Sym));
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNBLANK:
                D = AllocIf (".IFNBLANK", 1);
                NextTok ();
                if (IfCond) {
                    if (TokIsSep (CurTok.Tok)) {
                        SetIfCond (D, 0);
                    } else {
                        SetIfCond (D, 1);
                        SkipUntilSep ();
                    }
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNCONST:
                D = AllocIf (".IFNCONST", 1);
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
                    SetIfCond (D, !IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNDEF:
                D = AllocIf (".IFNDEF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym == 0 || !SymIsDef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFNREF:
                D = AllocIf (".IFNREF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym == 0 || !SymIsRef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            case TOK_IFP02:
                D = AllocIf (".IFP02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_6502);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFP4510:
                D = AllocIf (".IFP4510", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_4510);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFP816:
                D = AllocIf (".IFP816", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65816);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFPC02:
                D = AllocIf (".IFPC02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65C02);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFPSC02:
                D = AllocIf (".IFPSC02", 1);
                NextTok ();
                if (IfCond) {
                    SetIfCond (D, GetCPU() == CPU_65SC02);
                }
                ExpectSep ();
                CalcOverallIfCond ();
                break;

            case TOK_IFREF:
                D = AllocIf (".IFREF", 1);
                NextTok ();
                if (IfCond) {
                    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
                    SetIfCond (D, Sym != 0 && SymIsRef (Sym));
                    ExpectSep ();
                }
                CalcOverallIfCond ();
                break;

            default:
                /* Skip tokens */
                NextTok ();

        }

    } while (IfCond == 0 && CurTok.Tok != TOK_EOF);
}
Ejemplo n.º 7
0
void MacDef (unsigned Style)
/* Parse a macro definition */
{
    Macro* M;
    TokNode* N;
    int HaveParams;

    /* We expect a macro name here */
    if (CurTok.Tok != TOK_IDENT) {
        Error ("Identifier expected");
        MacSkipDef (Style);
        return;
    } else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) {
        /* The identifier is a name of a 6502 instruction, which is not
         * allowed if not explicitly enabled.
         */
        Error ("Cannot use an instruction as macro name");
        MacSkipDef (Style);
        return;
    }

    /* Did we already define that macro? */
    if (HT_Find (&MacroTab, &CurTok.SVal) != 0) {
        /* Macro is already defined */
        Error ("A macro named `%m%p' is already defined", &CurTok.SVal);
        /* Skip tokens until we reach the final .endmacro */
        MacSkipDef (Style);
        return;
    }

    /* Define the macro */
    M = NewMacro (&CurTok.SVal, Style);

    /* Switch to raw token mode and skip the macro name */
    EnterRawTokenMode ();
    NextTok ();

    /* If we have a DEFINE style macro, we may have parameters in braces,
     * otherwise we may have parameters without braces.
     */
    if (Style == MAC_STYLE_CLASSIC) {
        HaveParams = 1;
    } else {
        if (CurTok.Tok == TOK_LPAREN) {
            HaveParams = 1;
            NextTok ();
        } else {
            HaveParams = 0;
        }
    }

    /* Parse the parameter list */
    if (HaveParams) {

        while (CurTok.Tok == TOK_IDENT) {

            /* Create a struct holding the identifier */
            IdDesc* I = NewIdDesc (&CurTok.SVal);

            /* Insert the struct into the list, checking for duplicate idents */
            if (M->ParamCount == 0) {
                M->Params = I;
            } else {
                IdDesc* List = M->Params;
                while (1) {
                    if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
                        Error ("Duplicate symbol `%m%p'", &CurTok.SVal);
                    }
                    if (List->Next == 0) {
                        break;
                    } else {
                        List = List->Next;
                    }
                }
                List->Next = I;
            }
            ++M->ParamCount;

            /* Skip the name */
            NextTok ();

            /* Maybe there are more params... */
            if (CurTok.Tok == TOK_COMMA) {
                NextTok ();
            } else {
                break;
            }
        }
    }

    /* For class macros, we expect a separator token, for define style macros,
     * we expect the closing paren.
     */
    if (Style == MAC_STYLE_CLASSIC) {
        ConsumeSep ();
    } else if (HaveParams) {
        ConsumeRParen ();
    }

    /* Preparse the macro body. We will read the tokens until we reach end of
     * file, or a .endmacro (or end of line for DEFINE style macros) and store
     * them into an token list internal to the macro. For classic macros, there
     * the .LOCAL command is detected and removed at this time.
     */
    while (1) {

        /* Check for end of macro */
        if (Style == MAC_STYLE_CLASSIC) {
            /* In classic macros, only .endmacro is allowed */
            if (CurTok.Tok == TOK_ENDMACRO) {
                /* Done */
                break;
            }
            /* May not have end of file in a macro definition */
            if (CurTok.Tok == TOK_EOF) {
                Error ("`.ENDMACRO' expected");
                goto Done;
            }
        } else {
            /* Accept a newline or end of file for new style macros */
            if (TokIsSep (CurTok.Tok)) {
                break;
            }
        }

        /* Check for a .LOCAL declaration */
        if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) {

            while (1) {

                IdDesc* I;

                /* Skip .local or comma */
                NextTok ();

                /* Need an identifer */
                if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) {
                    Error ("Identifier expected");
                    SkipUntilSep ();
                    break;
                }

                /* Put the identifier into the locals list and skip it */
                I = NewIdDesc (&CurTok.SVal);
                I->Next = M->Locals;
                M->Locals = I;
                ++M->LocalCount;
                NextTok ();

                /* Check for end of list */
                if (CurTok.Tok != TOK_COMMA) {
                    break;
                }

            }

            /* We need end of line after the locals */
            ConsumeSep ();
            continue;
        }

        /* Create a token node for the current token */
        N = NewTokNode ();

        /* If the token is an identifier, check if it is a local parameter */
        if (CurTok.Tok == TOK_IDENT) {
            unsigned Count = 0;
            IdDesc* I = M->Params;
            while (I) {
                if (SB_Compare (&I->Id, &CurTok.SVal) == 0) {
                    /* Local param name, replace it */
                    N->T.Tok  = TOK_MACPARAM;
                    N->T.IVal = Count;
                    break;
                }
                ++Count;
                I = I->Next;
            }
        }

        /* Insert the new token in the list */
        if (M->TokCount == 0) {
            /* First token */
            M->TokRoot = M->TokLast = N;
        } else {
            /* We have already tokens */
            M->TokLast->Next = N;
            M->TokLast = N;
        }
        ++M->TokCount;

        /* Read the next token */
        NextTok ();
    }

    /* Skip the .endmacro for a classic macro */
    if (Style == MAC_STYLE_CLASSIC) {
        NextTok ();
    }

    /* Reset the Incomplete flag now that parsing is done */
    M->Incomplete = 0;

Done:
    /* Switch out of raw token mode */
    LeaveRawTokenMode ();
}