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" 15cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling#include "llvm/ADT/StringSwitch.h" 16cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling#include "llvm/ADT/Twine.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Config/config.h" // for strtoull()/strtoll() define 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/MemoryBuffer.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/SourceMgr.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/TableGen/Error.h" 21a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cctype> 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <cerrno> 234520dd2b7b20af07d5a3e4d06d964a532044eb10Duncan Sands#include <cstdio> 24ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstdlib> 25ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 268cc300cb3415d1d806e6f9e6ecb7c3d3f8341ad2Dylan Noblesmith 27a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerusing namespace llvm; 28a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 298070ea3f068980d08cc10381f4c9369d19a91353Chris LattnerTGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) { 30aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuffer = 0; 31aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); 32a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 3356a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner TokStart = 0; 34a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 35a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 361e3a8a492471f5dc3f50452af9eb9a2dfb1aeb39Chris LattnerSMLoc TGLexer::getLoc() const { 371e3a8a492471f5dc3f50452af9eb9a2dfb1aeb39Chris Lattner return SMLoc::getFromPointer(TokStart); 381c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner} 391c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner 40c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// ReturnError - Set the error to the specified string at the specified 41f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner/// location. This is defined to always return tgtok::Error. 42d1e1703c39742f3c9fc3d27a442ff59bbdbfb5aaBenjamin Kramertgtok::TokKind TGLexer::ReturnError(const char *Loc, const Twine &Msg) { 43c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner PrintError(Loc, Msg); 44f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::Error; 45a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 46a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 47a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerint TGLexer::getNextChar() { 48a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner char CurChar = *CurPtr++; 49a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 50a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner default: 51c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner return (unsigned char)CurChar; 52aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner case 0: { 53a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // A nul character in the stream is either the end of the current buffer or 54a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // a random nul in the file. Disambiguate that here. 55a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr-1 != CurBuf->getBufferEnd()) 56a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return 0; // Just whitespace. 57a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 58a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the end of an included file, pop the parent file off the 59a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // include stack. 601e3a8a492471f5dc3f50452af9eb9a2dfb1aeb39Chris Lattner SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 611e3a8a492471f5dc3f50452af9eb9a2dfb1aeb39Chris Lattner if (ParentIncludeLoc != SMLoc()) { 62aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); 63aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); 641c8ae59dfdc85d917db0333ae0b93e2be4ca6c36Chris Lattner CurPtr = ParentIncludeLoc.getPointer(); 65a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return getNextChar(); 66a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 67a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 68a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, return end of file. 69a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner --CurPtr; // Another call to lex will return EOF again. 70a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return EOF; 71aa739d26b1e65aec7f9afa1cde7e069c081ea355Chris Lattner } 72a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 73a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 74a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Handle the newline character by ignoring it and incrementing the line 75a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // count. However, be careful about 'dos style' files with \n\r in them. 76a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Only treat a \n\r or \r\n as a single line. 77a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if ((*CurPtr == '\n' || (*CurPtr == '\r')) && 78a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner *CurPtr != CurChar) 79c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner ++CurPtr; // Eat the two char newline sequence. 80a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return '\n'; 81a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 82a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 83a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 84a761f92cd38572dd65cc995c5f59b9c2c0f51068David Greeneint TGLexer::peekNextChar(int Index) { 85a761f92cd38572dd65cc995c5f59b9c2c0f51068David Greene return *(CurPtr + Index); 86a761f92cd38572dd65cc995c5f59b9c2c0f51068David Greene} 87a761f92cd38572dd65cc995c5f59b9c2c0f51068David Greene 88f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexToken() { 8956a9fcfd1e19c7adfcc4c948e2f5e471ca8ed241Chris Lattner TokStart = CurPtr; 90a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // This always consumes at least one character. 91a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 92a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 93a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 94a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner default: 95d3d1cad535d1c88e13e8e082c136260ee624967fDavid Greene // Handle letters: [a-zA-Z_] 96d3d1cad535d1c88e13e8e082c136260ee624967fDavid Greene if (isalpha(CurChar) || CurChar == '_') 97a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexIdentifier(); 98d3d1cad535d1c88e13e8e082c136260ee624967fDavid Greene 99f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner // Unknown character, emit an error. 100f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Unexpected character"); 101f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case EOF: return tgtok::Eof; 102f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ':': return tgtok::colon; 103f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ';': return tgtok::semi; 104f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '.': return tgtok::period; 105f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ',': return tgtok::comma; 106f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '<': return tgtok::less; 107f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '>': return tgtok::greater; 108f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ']': return tgtok::r_square; 109f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '{': return tgtok::l_brace; 110f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '}': return tgtok::r_brace; 111f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '(': return tgtok::l_paren; 112f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case ')': return tgtok::r_paren; 113f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '=': return tgtok::equal; 114f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner case '?': return tgtok::question; 115d3d1cad535d1c88e13e8e082c136260ee624967fDavid Greene case '#': return tgtok::paste; 116f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner 117a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 118a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ' ': 119a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\t': 120a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 121a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 122a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Ignore whitespace. 123a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 124a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 125a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the start of a // comment, skip until the end of the line or 126a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // the end of the buffer. 127a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (*CurPtr == '/') 128a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner SkipBCPLComment(); 129a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner else if (*CurPtr == '*') { 130a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (SkipCComment()) 131f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::Error; 132f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner } else // Otherwise, this is an error. 133f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Unexpected character"); 134a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 135a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '-': case '+': 136a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '0': case '1': case '2': case '3': case '4': case '5': case '6': 1377efe93625183a52733c23adc02c5c9c4337a7970David Greene case '7': case '8': case '9': { 1387efe93625183a52733c23adc02c5c9c4337a7970David Greene int NextChar = 0; 1397efe93625183a52733c23adc02c5c9c4337a7970David Greene if (isdigit(CurChar)) { 1407efe93625183a52733c23adc02c5c9c4337a7970David Greene // Allow identifiers to start with a number if it is followed by 1417efe93625183a52733c23adc02c5c9c4337a7970David Greene // an identifier. This can happen with paste operations like 1427efe93625183a52733c23adc02c5c9c4337a7970David Greene // foo#8i. 1437efe93625183a52733c23adc02c5c9c4337a7970David Greene int i = 0; 1447efe93625183a52733c23adc02c5c9c4337a7970David Greene do { 1457efe93625183a52733c23adc02c5c9c4337a7970David Greene NextChar = peekNextChar(i++); 1467efe93625183a52733c23adc02c5c9c4337a7970David Greene } while (isdigit(NextChar)); 1477efe93625183a52733c23adc02c5c9c4337a7970David Greene 1487efe93625183a52733c23adc02c5c9c4337a7970David Greene if (NextChar == 'x' || NextChar == 'b') { 1497efe93625183a52733c23adc02c5c9c4337a7970David Greene // If this is [0-9]b[01] or [0-9]x[0-9A-fa-f] this is most 1507efe93625183a52733c23adc02c5c9c4337a7970David Greene // likely a number. 1517efe93625183a52733c23adc02c5c9c4337a7970David Greene int NextNextChar = peekNextChar(i); 1527efe93625183a52733c23adc02c5c9c4337a7970David Greene switch (NextNextChar) { 1537efe93625183a52733c23adc02c5c9c4337a7970David Greene default: 1547efe93625183a52733c23adc02c5c9c4337a7970David Greene break; 1557efe93625183a52733c23adc02c5c9c4337a7970David Greene case '0': case '1': 1567efe93625183a52733c23adc02c5c9c4337a7970David Greene if (NextChar == 'b') 1577efe93625183a52733c23adc02c5c9c4337a7970David Greene return LexNumber(); 1587efe93625183a52733c23adc02c5c9c4337a7970David Greene // Fallthrough 1597efe93625183a52733c23adc02c5c9c4337a7970David Greene case '2': case '3': case '4': case '5': 1607efe93625183a52733c23adc02c5c9c4337a7970David Greene case '6': case '7': case '8': case '9': 1617efe93625183a52733c23adc02c5c9c4337a7970David Greene case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 1627efe93625183a52733c23adc02c5c9c4337a7970David Greene case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 1637efe93625183a52733c23adc02c5c9c4337a7970David Greene if (NextChar == 'x') 1647efe93625183a52733c23adc02c5c9c4337a7970David Greene return LexNumber(); 1657efe93625183a52733c23adc02c5c9c4337a7970David Greene break; 1667efe93625183a52733c23adc02c5c9c4337a7970David Greene } 1677efe93625183a52733c23adc02c5c9c4337a7970David Greene } 1687efe93625183a52733c23adc02c5c9c4337a7970David Greene } 1697efe93625183a52733c23adc02c5c9c4337a7970David Greene 1707efe93625183a52733c23adc02c5c9c4337a7970David Greene if (isalpha(NextChar) || NextChar == '_') 1717efe93625183a52733c23adc02c5c9c4337a7970David Greene return LexIdentifier(); 1727efe93625183a52733c23adc02c5c9c4337a7970David Greene 173a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexNumber(); 1747efe93625183a52733c23adc02c5c9c4337a7970David Greene } 175a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '"': return LexString(); 176a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '$': return LexVarName(); 177a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '[': return LexBracket(); 178a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '!': return LexExclaim(); 179a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 180a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 181a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 182a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexString - Lex "[^"]*" 183f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexString() { 184a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *StrStart = CurPtr; 185a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 186ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal = ""; 187ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 188a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (*CurPtr != '"') { 189a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If we hit the end of the buffer, report an error. 190c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) 191c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(StrStart, "End of file in string literal"); 192c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 193c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (*CurPtr == '\n' || *CurPtr == '\r') 194c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(StrStart, "End of line in string literal"); 195a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 196ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner if (*CurPtr != '\\') { 197ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal += *CurPtr++; 198ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner continue; 199ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner } 200ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 201a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 202ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 203ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner switch (*CurPtr) { 204ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\\': case '\'': case '"': 205ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // These turn into their literal character. 206ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner CurStrVal += *CurPtr++; 207ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner break; 208e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner case 't': 2097f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner CurStrVal += '\t'; 210e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner ++CurPtr; 211e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner break; 212e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner case 'n': 2137f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner CurStrVal += '\n'; 214e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner ++CurPtr; 215e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner break; 216e023bb693605f0354bba176f7d87a21cc7aa3785Chris Lattner 217ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\n': 218ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\r': 219ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(CurPtr, "escaped newlines not supported in tblgen"); 220ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner 221ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // If we hit the end of the buffer, report an error. 222ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner case '\0': 223ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner if (CurPtr == CurBuf->getBufferEnd()) 224ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(StrStart, "End of file in string literal"); 225ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner // FALL THROUGH 226ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner default: 227ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner return ReturnError(CurPtr, "invalid escape in string literal"); 228ea9f4df616995a70fff368c2cc0cf69df636aeafChris Lattner } 229a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 230a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 231a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 232f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::StrVal; 233a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 234a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 235f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexVarName() { 236a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(CurPtr[0]) && CurPtr[0] != '_') 237f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return ReturnError(TokStart, "Invalid variable name"); 238a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 239a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, we're ok, consume the rest of the characters. 240a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *VarNameStart = CurPtr++; 241a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 242a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 243a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 244a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 245f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurStrVal.assign(VarNameStart, CurPtr); 246f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::VarName; 247a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 248a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 249a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 250f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexIdentifier() { 251c2b0875b8d9e08a19f9ed9fae02fb121e4fc4a1fChris Lattner // The first letter is [a-zA-Z_#]. 252f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *IdentStart = TokStart; 25337d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer 254c2b0875b8d9e08a19f9ed9fae02fb121e4fc4a1fChris Lattner // Match the rest of the identifier regex: [0-9a-zA-Z_#]* 255d3d1cad535d1c88e13e8e082c136260ee624967fDavid Greene while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 256c2b0875b8d9e08a19f9ed9fae02fb121e4fc4a1fChris Lattner ++CurPtr; 25737d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer 258a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see if this identifier is a keyword. 25937d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer StringRef Str(IdentStart, CurPtr-IdentStart); 26037d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer 26137d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer if (Str == "include") { 262f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (LexInclude()) return tgtok::Error; 263f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return Lex(); 264a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 26537d42af584f07c78d990a8f1bb128046aab2182dBenjamin Kramer 266ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer tgtok::TokKind Kind = StringSwitch<tgtok::TokKind>(Str) 267ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("int", tgtok::Int) 268ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("bit", tgtok::Bit) 269ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("bits", tgtok::Bits) 270ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("string", tgtok::String) 271ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("list", tgtok::List) 272ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("code", tgtok::Code) 273ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("dag", tgtok::Dag) 274ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("class", tgtok::Class) 275ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("def", tgtok::Def) 276cebb4ee93a0064e4a2cb1fd1da7455b01e5655cbDavid Greene .Case("foreach", tgtok::Foreach) 277ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("defm", tgtok::Defm) 278ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("multiclass", tgtok::MultiClass) 279ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("field", tgtok::Field) 280ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("let", tgtok::Let) 281ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Case("in", tgtok::In) 282ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer .Default(tgtok::Id); 283ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer 284ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer if (Kind == tgtok::Id) 285ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer CurStrVal.assign(Str.begin(), Str.end()); 286ee573189c653c3261102ccd627bb571ab7535034Benjamin Kramer return Kind; 287a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 288a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 289a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexInclude - We just read the "include" token. Get the string token that 290a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// comes next and enter the include. 291a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::LexInclude() { 292a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // The token after the include must be a string. 293f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner tgtok::TokKind Tok = LexToken(); 294f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Tok == tgtok::Error) return true; 295f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (Tok != tgtok::StrVal) { 296f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(getLoc(), "Expected filename after include"); 297a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 298a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 299a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 300a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Get the string. 301f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner std::string Filename = CurStrVal; 302dd137903e47fdb5822724baaddae88f119badc86Joerg Sonnenberger std::string IncludedFile; 303a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 3047ee5d5f97b3fa709038ff7fd640dc775efaadc26Chris Lattner 305dd137903e47fdb5822724baaddae88f119badc86Joerg Sonnenberger CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr), 306dd137903e47fdb5822724baaddae88f119badc86Joerg Sonnenberger IncludedFile); 307d926e048c1409d3105e1ccd166e9369ab454a81dChris Lattner if (CurBuffer == -1) { 308f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(getLoc(), "Could not find include file '" + Filename + "'"); 309a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 310a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 311a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 312a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile); 313a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva if (Found != Dependencies.end()) { 314a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva PrintError(getLoc(), 315a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva "File '" + IncludedFile + "' has already been included."); 316a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva SrcMgr.PrintMessage(Found->second, SourceMgr::DK_Note, 317a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva "previously included here"); 318a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva return true; 319a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva } 320a170f520a990a50c35f72d81b4415dc4c3ec50deSean Silva Dependencies.insert(std::make_pair(IncludedFile, getLoc())); 321a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Save the line number and lex buffer of the includer. 3227ee5d5f97b3fa709038ff7fd640dc775efaadc26Chris Lattner CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); 323a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 324a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 325a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 326a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 327a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::SkipBCPLComment() { 328a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the second slash. 329a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 330a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (*CurPtr) { 331a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 332a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 333a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; // Newline is end of comment. 334a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 335a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the end of the buffer, end the comment. 336a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr == CurBuf->getBufferEnd()) 337a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; 338a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 339a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 340a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, skip the character. 341a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 342a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 343a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 344a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 345a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// SkipCComment - This skips C-style /**/ comments. The only difference from C 346a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// is that we allow nesting. 347a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::SkipCComment() { 348a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the star. 349a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned CommentDepth = 1; 350a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 351a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 352a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 353a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 354a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case EOF: 355f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner PrintError(TokStart, "Unterminated comment!"); 356a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 357a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '*': 358a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // End of the comment? 359a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '/') break; 360a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 361a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // End the */. 362a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (--CommentDepth == 0) 363a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 364a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 365a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 366a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Start of a nested comment? 367a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '*') break; 368a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 369a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CommentDepth; 370a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 371a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 372a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 373a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 374a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 375a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexNumber - Lex: 376a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// [-+]?[0-9]+ 377a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0x[0-9a-fA-F]+ 378a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0b[01]+ 379f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexNumber() { 380a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[-1] == '0') { 381a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] == 'x') { 382a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 383f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *NumStart = CurPtr; 384a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isxdigit(CurPtr[0])) 385a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 386a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 387c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Requires at least one hex digit. 388c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (CurPtr == NumStart) 3894226bb02fb623e2aa39cad819140df541f95bd8bChris Lattner return ReturnError(TokStart, "Invalid hexadecimal number"); 390c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 39163f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman errno = 0; 392f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(NumStart, 0, 16); 39363f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == EINVAL) 3944226bb02fb623e2aa39cad819140df541f95bd8bChris Lattner return ReturnError(TokStart, "Invalid hexadecimal number"); 39563f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == ERANGE) { 39663f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman errno = 0; 39763f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman CurIntVal = (int64_t)strtoull(NumStart, 0, 16); 39863f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == EINVAL) 3994226bb02fb623e2aa39cad819140df541f95bd8bChris Lattner return ReturnError(TokStart, "Invalid hexadecimal number"); 40063f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman if (errno == ERANGE) 4014226bb02fb623e2aa39cad819140df541f95bd8bChris Lattner return ReturnError(TokStart, "Hexadecimal number out of range"); 40263f97201dc9dcebbe84d1b73113166c64212b4b8Dan Gohman } 403f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 404a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } else if (CurPtr[0] == 'b') { 405a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 406f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner const char *NumStart = CurPtr; 407a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (CurPtr[0] == '0' || CurPtr[0] == '1') 408a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 409c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 410c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Requires at least one binary digit. 411c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (CurPtr == NumStart) 412c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CurPtr-2, "Invalid binary number"); 413f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(NumStart, 0, 2); 414f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 415a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 416a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 417a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 418a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check for a sign without a digit. 419f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (!isdigit(CurPtr[0])) { 420f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner if (CurPtr[-1] == '-') 421f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::minus; 422f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner else if (CurPtr[-1] == '+') 423f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::plus; 424a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 425a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 426a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isdigit(CurPtr[0])) 427a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 428f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurIntVal = strtoll(TokStart, 0, 10); 429f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::IntVal; 430a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 431a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 432a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexBracket - We just read '['. If this is a code block, return it, 433a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// otherwise return the bracket. Match: '[' and '[{ ( [^}]+ | }[^]] )* }]' 434f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexBracket() { 435a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '{') 436f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::l_square; 437a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 438a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *CodeStart = CurPtr; 439a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 440a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int Char = getNextChar(); 441a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 442a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 443a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char != '}') continue; 444a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 445a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner Char = getNextChar(); 446a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 447a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == ']') { 448f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner CurStrVal.assign(CodeStart, CurPtr-2); 449f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattner return tgtok::CodeFragment; 450a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 451a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 452a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 453c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CodeStart-2, "Unterminated Code Block"); 454a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 455a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 456a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexExclaim - Lex '!' and '![a-zA-Z]+'. 457f460165a4c1bf4bc762f9b3f12b9ed284b89cc99Chris Lattnertgtok::TokKind TGLexer::LexExclaim() { 458a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(*CurPtr)) 459dd2b6cbb624691fcdfda2f7e962789417b04b16bBill Wendling return ReturnError(CurPtr - 1, "Invalid \"!operator\""); 460a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 461a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *Start = CurPtr++; 462a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr)) 463a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 464a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 465a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see which operator this is. 466cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling tgtok::TokKind Kind = 467cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling StringSwitch<tgtok::TokKind>(StringRef(Start, CurPtr - Start)) 468cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("eq", tgtok::XEq) 469cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("if", tgtok::XIf) 4701434f66b2e132a707e2c8ccb3350ea13fb5aa051David Greene .Case("head", tgtok::XHead) 4711434f66b2e132a707e2c8ccb3350ea13fb5aa051David Greene .Case("tail", tgtok::XTail) 472cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("con", tgtok::XConcat) 473d23a41c153712b929bd84f5e713bda5db5d6e66dHal Finkel .Case("add", tgtok::XADD) 474cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("shl", tgtok::XSHL) 475cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("sra", tgtok::XSRA) 476cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("srl", tgtok::XSRL) 477cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("cast", tgtok::XCast) 4781434f66b2e132a707e2c8ccb3350ea13fb5aa051David Greene .Case("empty", tgtok::XEmpty) 479cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("subst", tgtok::XSubst) 480cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("foreach", tgtok::XForEach) 481cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Case("strconcat", tgtok::XStrConcat) 482cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling .Default(tgtok::Error); 483cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling 484cd466f582aa83074294ab1a31b26eedd5a2fd025Bill Wendling return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); 485a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 486a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 487