/// <summary> /// Lex a hex literal optionally followed by an integer suffix. Asserts the current /// character is a hex digit. /// </summary> private Token LexHexInt() { Contracts.Assert(LexCharUtils.IsHexDigit(ChCur)); ulong u = 0; bool fOverflow = false; do { if ((u & 0xF000000000000000) != 0 && !fOverflow) { ReportError(ErrId.IntOverflow); fOverflow = true; } u = (u << 4) + (ulong)LexCharUtils.GetHexVal(ChCur); } while (LexCharUtils.IsHexDigit(ChNext())); if (fOverflow) { u = ulong.MaxValue; } return(new IntLitToken(GetSpan(), u, LexIntSuffix() | IntLitKind.Hex)); }
/// <summary> /// Lex a character escape. Returns true if successful (ch is valid). /// </summary> private bool FLexEscChar(bool fUniOnly, out uint u) { Contracts.Assert(ChCur == '\\'); int ichErr = _cursor.IchCur; bool fUni; int cchHex; switch (ChNext()) { case 'u': fUni = true; cchHex = 4; goto LHex; case 'U': fUni = true; cchHex = 8; goto LHex; default: if (!fUniOnly) { switch (ChCur) { default: goto LBad; case 'x': case 'X': fUni = false; cchHex = 4; goto LHex; case '\'': u = 0x0027; break; case '"': u = 0x0022; break; case '\\': u = 0x005C; break; case '0': u = 0x0000; break; case 'a': u = 0x0007; break; case 'b': u = 0x0008; break; case 'f': u = 0x000C; break; case 'n': u = 0x000A; break; case 'r': u = 0x000D; break; case 't': u = 0x0009; break; case 'v': u = 0x000B; break; } ChNext(); return(true); } LBad: ReportError(ichErr, _cursor.IchCur, ErrId.BadEscape); u = 0; return(false); } LHex: bool fRet = true; ChNext(); u = 0; for (int ich = 0; ich < cchHex; ich++) { if (!LexCharUtils.IsHexDigit(ChCur)) { fRet = (ich > 0); if (fUni || !fRet) { ReportError(ichErr, _cursor.IchCur, ErrId.BadEscape); } break; } u = (u << 4) + (uint)LexCharUtils.GetHexVal(ChCur); ChNext(); } return(fRet); }