[llvm-commits] [llvm] r142525 - in /llvm/trunk/lib/TableGen: TGLexer.cpp TGLexer.h TGParser.cpp
David Greene
greened at obbligato.org
Wed Oct 19 06:04:43 PDT 2011
Author: greened
Date: Wed Oct 19 08:04:43 2011
New Revision: 142525
URL: http://llvm.org/viewvc/llvm-project?rev=142525&view=rev
Log:
Implement Paste
Add a paste operator '#' to take two identifier-like strings and joint
them. Internally paste gets represented as a !strconcat() with any
necessary casts to string added.
This will be used to implement basic for loop functionality as in:
for i = [0, 1, 2, 3, 4, 5, 6, 7] {
def R#i : Register<...>
}
Modified:
llvm/trunk/lib/TableGen/TGLexer.cpp
llvm/trunk/lib/TableGen/TGLexer.h
llvm/trunk/lib/TableGen/TGParser.cpp
Modified: llvm/trunk/lib/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.cpp?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/lib/TableGen/TGLexer.cpp Wed Oct 19 08:04:43 2011
@@ -91,10 +91,10 @@
switch (CurChar) {
default:
- // Handle letters: [a-zA-Z_#]
- if (isalpha(CurChar) || CurChar == '_' || CurChar == '#')
+ // Handle letters: [a-zA-Z_]
+ if (isalpha(CurChar) || CurChar == '_')
return LexIdentifier();
-
+
// Unknown character, emit an error.
return ReturnError(TokStart, "Unexpected character");
case EOF: return tgtok::Eof;
@@ -111,6 +111,7 @@
case ')': return tgtok::r_paren;
case '=': return tgtok::equal;
case '?': return tgtok::question;
+ case '#': return tgtok::paste;
case 0:
case ' ':
@@ -250,8 +251,7 @@
const char *IdentStart = TokStart;
// Match the rest of the identifier regex: [0-9a-zA-Z_#]*
- while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' ||
- *CurPtr == '#')
+ while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
++CurPtr;
// Check to see if this identifier is a keyword.
Modified: llvm/trunk/lib/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGLexer.h?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGLexer.h (original)
+++ llvm/trunk/lib/TableGen/TGLexer.h Wed Oct 19 08:04:43 2011
@@ -39,7 +39,8 @@
colon, semi, // : ;
comma, period, // , .
equal, question, // = ?
-
+ paste, // #
+
// Keywords.
Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
MultiClass, String,
Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=142525&r1=142524&r2=142525&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed Oct 19 08:04:43 2011
@@ -1083,6 +1083,12 @@
Init *R = 0;
switch (Lex.getCode()) {
default: TokError("Unknown token when parsing a value"); break;
+ case tgtok::paste:
+ // This is a leading paste operation. This is deprecated but
+ // still exists in some .td files. Ignore it.
+ Lex.Lex(); // Skip '#'.
+ return ParseSimpleValue(CurRec, ItemType, Mode);
+ break;
case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break;
case tgtok::StrVal: {
std::string Val = Lex.getCurStrVal();
@@ -1410,6 +1416,56 @@
Result = FieldInit::get(Result, Lex.getCurStrVal());
Lex.Lex(); // eat field name
break;
+
+ case tgtok::paste:
+ SMLoc PasteLoc = Lex.getLoc();
+
+ // Create a !strconcat() operation, first casting each operand to
+ // a string if necessary.
+
+ TypedInit *LHS = dynamic_cast<TypedInit *>(Result);
+ if (!LHS) {
+ Error(PasteLoc, "LHS of paste is not typed!");
+ return 0;
+ }
+
+ if (LHS->getType() != StringRecTy::get()) {
+ LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get());
+ }
+
+ TypedInit *RHS = 0;
+
+ Lex.Lex(); // Eat the '#'.
+ switch (Lex.getCode()) {
+ case tgtok::colon:
+ case tgtok::semi:
+ case tgtok::l_brace:
+ // These are all of the tokens that can begin an object body.
+ // Some of these can also begin values but we disallow those cases
+ // because they are unlikely to be useful.
+
+ // Trailing paste, concat with an empty string.
+ RHS = StringInit::get("");
+ break;
+
+ default:
+ Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode);
+ RHS = dynamic_cast<TypedInit *>(RHSResult);
+ if (!RHS) {
+ Error(PasteLoc, "RHS of paste is not typed!");
+ return 0;
+ }
+
+ if (RHS->getType() != StringRecTy::get()) {
+ RHS = UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get());
+ }
+
+ break;
+ }
+
+ Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS,
+ StringRecTy::get())->Fold(CurRec, CurMultiClass);
+ break;
}
}
}
@@ -1979,41 +2035,23 @@
// instantiated def a unique name. Otherwise, if "#NAME#" exists in the
// name, substitute the prefix for #NAME#. Otherwise, use the defm name
// as a prefix.
- StringInit *DefNameString =
- dynamic_cast<StringInit *>(DefProto->getNameInit());
-
- if (DefNameString == 0) {
- Error(DefmPrefixLoc, "Def name is not a string");
- return 0;
- }
if (DefmPrefix == 0)
DefmPrefix = StringInit::get(GetNewAnonymousName());
Init *DefName = DefProto->getNameInit();
- // See if we can substitute #NAME#.
- Init *NewDefName =
- TernOpInit::get(TernOpInit::SUBST,
- StringInit::get("#NAME#"),
- DefmPrefix,
- DefName,
- StringRecTy::get())->Fold(DefProto, &MC);
-
- if (NewDefName == DefName) {
- // We did't do any substitution. We should concatenate the given
- // prefix and name.
- if (DefmPrefix == 0)
- DefmPrefix = StringInit::get(GetNewAnonymousName());
+ StringInit *DefNameString = dynamic_cast<StringInit *>(DefName);
+ if (DefNameString != 0) {
+ // We have a fully expanded string so there are no operators to
+ // resolve. We should concatenate the given prefix and name.
DefName =
BinOpInit::get(BinOpInit::STRCONCAT,
UnOpInit::get(UnOpInit::CAST, DefmPrefix,
StringRecTy::get())->Fold(DefProto, &MC),
DefName, StringRecTy::get())->Fold(DefProto, &MC);
}
- else
- DefName = NewDefName;
Record *CurRec = new Record(DefName, DefmPrefixLoc, Records);
More information about the llvm-commits
mailing list