static int DoIf (int Skip) /* Process #if directive */ { ExprDesc Expr; /* We're about to abuse the compiler expression parser to evaluate the * #if expression. Save the current tokens to come back here later. * NOTE: Yes, this is a hack, but it saves a complete separate expression * evaluation for the preprocessor. */ Token SavedCurTok = CurTok; Token SavedNextTok = NextTok; /* Make sure the line infos for the tokens won't get removed */ if (SavedCurTok.LI) { UseLineInfo (SavedCurTok.LI); } if (SavedNextTok.LI) { UseLineInfo (SavedNextTok.LI); } /* Switch into special preprocessing mode */ Preprocessing = 1; /* Expand macros in this line */ PreprocessLine (); /* Add two semicolons as sentinels to the line, so the following * expression evaluation will eat these two tokens but nothing from * the following line. */ SB_AppendStr (Line, ";;"); SB_Terminate (Line); /* Load CurTok and NextTok with tokens from the new input */ NextToken (); NextToken (); /* Call the expression parser */ ConstExpr (hie1, &Expr); /* End preprocessing mode */ Preprocessing = 0; /* Reset the old tokens */ CurTok = SavedCurTok; NextTok = SavedNextTok; /* Set the #if condition according to the expression result */ return PushIf (Skip, 1, Expr.IVal != 0); }
CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo, LineInfo* LI) /* Create a new code entry, initialize and return it */ { /* Get the opcode description */ const OPCDesc* D = GetOPCDesc (OPC); /* Allocate memory */ CodeEntry* E = xmalloc (sizeof (CodeEntry)); /* Initialize the fields */ E->OPC = D->OPC; E->AM = AM; E->Size = GetInsnSize (E->OPC, E->AM); E->Arg = GetArgCopy (Arg); E->Flags = NumArg (E->Arg, &E->Num)? CEF_NUMARG : 0; /* Needs E->Arg */ E->Info = D->Info; E->JumpTo = JumpTo; E->LI = UseLineInfo (LI); E->RI = 0; SetUseChgInfo (E, D); InitCollection (&E->Labels); /* If we have a label given, add this entry to the label */ if (JumpTo) { CollAppend (&JumpTo->JumpFrom, E); } /* Return the initialized struct */ return E; }
void NextToken (void) /* Get next token from input stream */ { ident token; /* We have to skip white space here before shifting tokens, since the ** tokens and the current line info is invalid at startup and will get ** initialized by reading the first time from the file. Remember if ** we were at end of input and handle that later. */ int GotEOF = (SkipWhite() == 0); /* Current token is the lookahead token */ if (CurTok.LI) { ReleaseLineInfo (CurTok.LI); } CurTok = NextTok; /* When reading the first time from the file, the line info in NextTok, ** which was copied to CurTok is invalid. Since the information from ** the token is used for error messages, we must make it valid. */ if (CurTok.LI == 0) { CurTok.LI = UseLineInfo (GetCurLineInfo ()); } /* Remember the starting position of the next token */ NextTok.LI = UseLineInfo (GetCurLineInfo ()); /* Now handle end of input. */ if (GotEOF) { /* End of file reached */ NextTok.Tok = TOK_CEOF; return; } /* Determine the next token from the lookahead */ if (IsDigit (CurC) || (CurC == '.' && IsDigit (NextC))) { /* A number */ NumericConst (); return; } /* Check for wide character literals */ if (CurC == 'L' && NextC == '\"') { StringConst (); return; } /* Check for keywords and identifiers */ if (IsSym (token)) { /* Check for a keyword */ if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) { /* Reserved word found */ return; } /* No reserved word, check for special symbols */ if (token[0] == '_' && token[1] == '_') { /* Special symbols */ if (strcmp (token+2, "FILE__") == 0) { NextTok.SVal = AddLiteral (GetCurrentFile()); NextTok.Tok = TOK_SCONST; return; } else if (strcmp (token+2, "LINE__") == 0) { NextTok.Tok = TOK_ICONST; NextTok.IVal = GetCurrentLine(); NextTok.Type = type_int; return; } else if (strcmp (token+2, "func__") == 0) { /* __func__ is only defined in functions */ if (CurrentFunc) { NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc)); NextTok.Tok = TOK_SCONST; return; } } } /* No reserved word but identifier */ strcpy (NextTok.Ident, token); NextTok.Tok = TOK_IDENT; return; } /* Monstrous switch statement ahead... */ switch (CurC) { case '!': NextChar (); if (CurC == '=') { SetTok (TOK_NE); } else { NextTok.Tok = TOK_BOOL_NOT; } break; case '\"': StringConst (); break; case '%': NextChar (); if (CurC == '=') { SetTok (TOK_MOD_ASSIGN); } else { NextTok.Tok = TOK_MOD; } break; case '&': NextChar (); switch (CurC) { case '&': SetTok (TOK_BOOL_AND); break; case '=': SetTok (TOK_AND_ASSIGN); break; default: NextTok.Tok = TOK_AND; } break; case '\'': CharConst (); break; case '(': SetTok (TOK_LPAREN); break; case ')': SetTok (TOK_RPAREN); break; case '*': NextChar (); if (CurC == '=') { SetTok (TOK_MUL_ASSIGN); } else { NextTok.Tok = TOK_STAR; } break; case '+': NextChar (); switch (CurC) { case '+': SetTok (TOK_INC); break; case '=': SetTok (TOK_PLUS_ASSIGN); break; default: NextTok.Tok = TOK_PLUS; } break; case ',': SetTok (TOK_COMMA); break; case '-': NextChar (); switch (CurC) { case '-': SetTok (TOK_DEC); break; case '=': SetTok (TOK_MINUS_ASSIGN); break; case '>': SetTok (TOK_PTR_REF); break; default: NextTok.Tok = TOK_MINUS; } break; case '.': NextChar (); if (CurC == '.') { NextChar (); if (CurC == '.') { SetTok (TOK_ELLIPSIS); } else { UnknownChar (CurC); } } else { NextTok.Tok = TOK_DOT; } break; case '/': NextChar (); if (CurC == '=') { SetTok (TOK_DIV_ASSIGN); } else { NextTok.Tok = TOK_DIV; } break; case ':': SetTok (TOK_COLON); break; case ';': SetTok (TOK_SEMI); break; case '<': NextChar (); switch (CurC) { case '=': SetTok (TOK_LE); break; case '<': NextChar (); if (CurC == '=') { SetTok (TOK_SHL_ASSIGN); } else { NextTok.Tok = TOK_SHL; } break; default: NextTok.Tok = TOK_LT; } break; case '=': NextChar (); if (CurC == '=') { SetTok (TOK_EQ); } else { NextTok.Tok = TOK_ASSIGN; } break; case '>': NextChar (); switch (CurC) { case '=': SetTok (TOK_GE); break; case '>': NextChar (); if (CurC == '=') { SetTok (TOK_SHR_ASSIGN); } else { NextTok.Tok = TOK_SHR; } break; default: NextTok.Tok = TOK_GT; } break; case '?': SetTok (TOK_QUEST); break; case '[': SetTok (TOK_LBRACK); break; case ']': SetTok (TOK_RBRACK); break; case '^': NextChar (); if (CurC == '=') { SetTok (TOK_XOR_ASSIGN); } else { NextTok.Tok = TOK_XOR; } break; case '{': SetTok (TOK_LCURLY); break; case '|': NextChar (); switch (CurC) { case '|': SetTok (TOK_BOOL_OR); break; case '=': SetTok (TOK_OR_ASSIGN); break; default: NextTok.Tok = TOK_OR; } break; case '}': SetTok (TOK_RCURLY); break; case '~': SetTok (TOK_COMP); break; default: UnknownChar (CurC); } }