TGLexer.cpp revision e023bb693605f0354bba176f7d87a21cc7aa3785
1a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===- TGLexer.cpp - Lexer for TableGen -----------------------------------===// 2a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 3a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// The LLVM Compiler Infrastructure 4a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details. 7a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 8a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===// 9a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 10a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// Implement the Lexer for TableGen. 11a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 12a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===// 13a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 146aaca046d2896d8396314f4b1b6ad7a000034330Chris Lattner#include "TGLexer.h" 15aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner#include "TGSourceMgr.h" 16a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/Streams.h" 17a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/MemoryBuffer.h" 18f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner#include <ostream> 198b0ec6440083261418b400e024f15b66d4ce44dbChuck Rose III#include "llvm/Config/config.h" 20a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cctype> 214520dd2b7b20af07d5a3e4d06d964a532044eb10Duncan Sands#include <cstdio> 22ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstdlib> 23ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 2463f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman#include <cerrno> 25a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerusing namespace llvm; 26a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 27aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris LattnerTGLexer::TGLexer(TGSourceMgr &SM) : SrcMgr(SM) { 28aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuffer = 0; 29aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); 30a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 3156a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner TokStart = 0; 32a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 33a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 341c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris LattnerTGLoc TGLexer::getLoc() const { 351c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner return TGLoc::getFromPointer(TokStart); 361c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner} 371c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner 38a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 39c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// ReturnError - Set the error to the specified string at the specified 40f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner/// location. This is defined to always return tgtok::Error. 41f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) { 42c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner PrintError(Loc, Msg); 43f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::Error; 44a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 45a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 46a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 471c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattnervoid TGLexer::PrintError(const char *Loc, const std::string &Msg) const { 481c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner SrcMgr.PrintError(TGLoc::getFromPointer(Loc), Msg); 491c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner} 501c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner 511c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattnervoid TGLexer::PrintError(TGLoc Loc, const std::string &Msg) const { 52aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner SrcMgr.PrintError(Loc, Msg); 53c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner} 54c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 551c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner 56a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::getNextChar() { 57a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner char CurChar = *CurPtr++; 58a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 59a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner default: 60c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner return (unsigned char)CurChar; 61aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner case 0: { 62a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // A nul character in the stream is either the end of the current buffer or 63a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // a random nul in the file. Disambiguate that here. 64a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr-1 != CurBuf->getBufferEnd()) 65a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return 0; // Just whitespace. 66a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 67a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the end of an included file, pop the parent file off the 68a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // include stack. 691c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner TGLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 701c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner if (ParentIncludeLoc != TGLoc()) { 71aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); 72aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); 731c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner CurPtr = ParentIncludeLoc.getPointer(); 74a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return getNextChar(); 75a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 76a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 77a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, return end of file. 78a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner --CurPtr; // Another call to lex will return EOF again. 79a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return EOF; 80aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner } 81a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 82a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 83a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Handle the newline character by ignoring it and incrementing the line 84a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // count. However, be careful about 'dos style' files with \n\r in them. 85a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Only treat a \n\r or \r\n as a single line. 86a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if ((*CurPtr == '\n' || (*CurPtr == '\r')) && 87a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner *CurPtr != CurChar) 88c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner ++CurPtr; // Eat the two char newline sequence. 89a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return '\n'; 90a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 91a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 92a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 93f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexToken() { 9456a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner TokStart = CurPtr; 95a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // This always consumes at least one character. 96a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 97a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 98a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 99a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner default: 100a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Handle letters: [a-zA-Z_] 101a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (isalpha(CurChar) || CurChar == '_') 102a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexIdentifier(); 103a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 104f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner // Unknown character, emit an error. 105f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Unexpected character"); 106f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case EOF: return tgtok::Eof; 107f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ':': return tgtok::colon; 108f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ';': return tgtok::semi; 109f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '.': return tgtok::period; 110f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ',': return tgtok::comma; 111f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '<': return tgtok::less; 112f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '>': return tgtok::greater; 113f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ']': return tgtok::r_square; 114f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '{': return tgtok::l_brace; 115f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '}': return tgtok::r_brace; 116f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '(': return tgtok::l_paren; 117f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ')': return tgtok::r_paren; 118f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '=': return tgtok::equal; 119f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '?': return tgtok::question; 120f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner 121a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 122a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ' ': 123a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\t': 124a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 125a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 126a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Ignore whitespace. 127a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 128a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 129a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the start of a // comment, skip until the end of the line or 130a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // the end of the buffer. 131a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (*CurPtr == '/') 132a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner SkipBCPLComment(); 133a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner else if (*CurPtr == '*') { 134a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (SkipCComment()) 135f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::Error; 136f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner } else // Otherwise, this is an error. 137f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Unexpected character"); 138a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 139a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '-': case '+': 140a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '0': case '1': case '2': case '3': case '4': case '5': case '6': 141a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '7': case '8': case '9': 142a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexNumber(); 143a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '"': return LexString(); 144a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '$': return LexVarName(); 145a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '[': return LexBracket(); 146a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '!': return LexExclaim(); 147a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 148a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 149a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 150a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexString - Lex "[^"]*" 151f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexString() { 152a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *StrStart = CurPtr; 153a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 154ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal = ""; 155ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 156a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (*CurPtr != '"') { 157a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If we hit the end of the buffer, report an error. 158c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) 159c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(StrStart, "End of file in string literal"); 160c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 161c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (*CurPtr == '\n' || *CurPtr == '\r') 162c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(StrStart, "End of line in string literal"); 163a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 164ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner if (*CurPtr != '\\') { 165ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal += *CurPtr++; 166ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner continue; 167ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner } 168ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 169a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 170ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 171ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner switch (*CurPtr) { 172ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\\': case '\'': case '"': 173ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // These turn into their literal character. 174ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal += *CurPtr++; 175ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner break; 176e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner case 't': 177e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner CurStrVal += "\\t"; 178e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner ++CurPtr; 179e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner break; 180e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner case 'n': 181e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner CurStrVal += "\\n"; 182e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner ++CurPtr; 183e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner break; 184e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner 185ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\n': 186ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\r': 187ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(CurPtr, "escaped newlines not supported in tblgen"); 188ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 189ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // If we hit the end of the buffer, report an error. 190ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\0': 191ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner if (CurPtr == CurBuf->getBufferEnd()) 192ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(StrStart, "End of file in string literal"); 193ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // FALL THROUGH 194ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner default: 195ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(CurPtr, "invalid escape in string literal"); 196ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner } 197a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 198a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 199a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 200f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::StrVal; 201a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 202a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 203f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexVarName() { 204a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(CurPtr[0]) && CurPtr[0] != '_') 205f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Invalid variable name"); 206a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 207a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, we're ok, consume the rest of the characters. 208a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *VarNameStart = CurPtr++; 209a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 210a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 211a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 212a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 213f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurStrVal.assign(VarNameStart, CurPtr); 214f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::VarName; 215a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 216a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 217a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 218f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexIdentifier() { 219a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // The first letter is [a-zA-Z_]. 220f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *IdentStart = TokStart; 221a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 222a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Match the rest of the identifier regex: [0-9a-zA-Z_]* 223a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 224a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 225a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 226a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see if this identifier is a keyword. 227a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned Len = CurPtr-IdentStart; 228a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 229f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int; 230f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit; 231f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits; 232f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String; 233f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List; 234f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code; 235f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag; 236a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 237f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class; 238f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def; 239f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm; 240f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) 241f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::MultiClass; 242f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field; 243f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let; 244f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In; 245a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 246a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 7 && !memcmp(IdentStart, "include", 7)) { 247f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (LexInclude()) return tgtok::Error; 248f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return Lex(); 249a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 250a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 251f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurStrVal.assign(IdentStart, CurPtr); 252f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::Id; 253a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 254a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 255a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexInclude - We just read the "include" token. Get the string token that 256a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// comes next and enter the include. 257a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::LexInclude() { 258a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // The token after the include must be a string. 259f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner tgtok::TokKind Tok = LexToken(); 260f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Tok == tgtok::Error) return true; 261f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Tok != tgtok::StrVal) { 262f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(getLoc(), "Expected filename after include"); 263a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 264a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 265a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 266a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Get the string. 267f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner std::string Filename = CurStrVal; 268a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 269a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Try to find the file. 270038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner MemoryBuffer *NewBuf = MemoryBuffer::getFile(Filename.c_str()); 271a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 272a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If the file didn't exist directly, see if it's in an include path. 273a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) { 274a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner std::string IncFile = IncludeDirectories[i] + "/" + Filename; 275038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner NewBuf = MemoryBuffer::getFile(IncFile.c_str()); 276a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 277a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 278a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (NewBuf == 0) { 279f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(getLoc(), "Could not find include file '" + Filename + "'"); 280a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 281a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 282a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 283a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Save the line number and lex buffer of the includer. 2841c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner CurBuffer = SrcMgr.AddNewSourceBuffer(NewBuf, TGLoc::getFromPointer(CurPtr)); 285a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 286a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurBuf = NewBuf; 287a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 288a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 289a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 290a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 291a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::SkipBCPLComment() { 292a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the second slash. 293a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 294a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (*CurPtr) { 295a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 296a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 297a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; // Newline is end of comment. 298a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 299a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the end of the buffer, end the comment. 300a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr == CurBuf->getBufferEnd()) 301a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; 302a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 303a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 304a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, skip the character. 305a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 306a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 307a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 308a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 309a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// SkipCComment - This skips C-style /**/ comments. The only difference from C 310a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// is that we allow nesting. 311a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::SkipCComment() { 312a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the star. 313a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned CommentDepth = 1; 314a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 315a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 316a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 317a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 318a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case EOF: 319f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(TokStart, "Unterminated comment!"); 320a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 321a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '*': 322a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // End of the comment? 323a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '/') break; 324a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 325a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // End the */. 326a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (--CommentDepth == 0) 327a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 328a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 329a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 330a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Start of a nested comment? 331a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '*') break; 332a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 333a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CommentDepth; 334a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 335a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 336a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 337a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 338a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 339a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexNumber - Lex: 340a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// [-+]?[0-9]+ 341a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0x[0-9a-fA-F]+ 342a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0b[01]+ 343f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexNumber() { 344a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[-1] == '0') { 345a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] == 'x') { 346a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 347f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *NumStart = CurPtr; 348a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isxdigit(CurPtr[0])) 349a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 350a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 351c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Requires at least one hex digit. 352c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (CurPtr == NumStart) 353c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 354c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 35563f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman errno = 0; 356f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(NumStart, 0, 16); 35763f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == EINVAL) 35863f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 35963f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == ERANGE) { 36063f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman errno = 0; 36163f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman CurIntVal = (int64_t)strtoull(NumStart, 0, 16); 36263f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == EINVAL) 36363f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 36463f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == ERANGE) 36563f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman return ReturnError(CurPtr-2, "Hexadecimal number out of range"); 36663f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman } 367f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 368a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } else if (CurPtr[0] == 'b') { 369a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 370f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *NumStart = CurPtr; 371a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (CurPtr[0] == '0' || CurPtr[0] == '1') 372a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 373c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 374c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Requires at least one binary digit. 375c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (CurPtr == NumStart) 376c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CurPtr-2, "Invalid binary number"); 377f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(NumStart, 0, 2); 378f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 379a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 380a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 381a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 382a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check for a sign without a digit. 383f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (!isdigit(CurPtr[0])) { 384f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (CurPtr[-1] == '-') 385f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::minus; 386f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner else if (CurPtr[-1] == '+') 387f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::plus; 388a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 389a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 390a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isdigit(CurPtr[0])) 391a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 392f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(TokStart, 0, 10); 393f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 394a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 395a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 396a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexBracket - We just read '['. If this is a code block, return it, 397a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// otherwise return the bracket. Match: '[' and '[{ ( [^}]+ | }[^]] )* }]' 398f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexBracket() { 399a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '{') 400f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::l_square; 401a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 402a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *CodeStart = CurPtr; 403a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 404a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int Char = getNextChar(); 405a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 406a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 407a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char != '}') continue; 408a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 409a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner Char = getNextChar(); 410a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 411a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == ']') { 412f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurStrVal.assign(CodeStart, CurPtr-2); 413f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::CodeFragment; 414a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 415a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 416a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 417c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CodeStart-2, "Unterminated Code Block"); 418a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 419a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 420a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexExclaim - Lex '!' and '![a-zA-Z]+'. 421f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexExclaim() { 422a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(*CurPtr)) 423f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(CurPtr-1, "Invalid \"!operator\""); 424a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 425a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *Start = CurPtr++; 426a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr)) 427a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 428a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 429a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see which operator this is. 430a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned Len = CurPtr-Start; 431a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 432f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; 433f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; 434f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; 435f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; 436f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; 437a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 438c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(Start-1, "Unknown operator"); 439a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 440a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 441