Graduate LLVM to the big leagues by embedding a LISP processor into TableGen.

Ok, not really, but do support some common LISP functions:

* car
* cdr
* null


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71805 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index bc5d65e..8ff25a6 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -680,6 +680,9 @@
     TokError("unknown operation");
     return 0;
     break;
+  case tgtok::XCar:
+  case tgtok::XCdr:
+  case tgtok::XNull:
   case tgtok::XCast: {  // Value ::= !unop '(' Value ')'
     UnOpInit::UnaryOp Code;
     RecTy *Type = 0;
@@ -693,11 +696,24 @@
       Type = ParseOperatorType();
 
       if (Type == 0) {
-        TokError("did not get type for binary operator");
+        TokError("did not get type for unary operator");
         return 0;
       }
 
       break;
+    case tgtok::XCar:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CAR;
+      break;
+    case tgtok::XCdr:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CDR;
+      break;
+    case tgtok::XNull:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::LNULL;
+      Type = new IntRecTy;
+      break;
     }
     if (Lex.getCode() != tgtok::l_paren) {
       TokError("expected '(' after unary operator");
@@ -708,6 +724,60 @@
     Init *LHS = ParseValue(CurRec);
     if (LHS == 0) return 0;
 
+    if (Code == UnOpInit::CAR
+        || Code == UnOpInit::CDR
+        || Code == UnOpInit::LNULL) {
+      ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+      TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
+      if (LHSl == 0 && LHSt == 0) {
+        TokError("expected list type argument in unary operator");
+        return 0;
+      }
+      if (LHSt) {
+        ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
+        if (LType == 0) {
+          TokError("expected list type argumnet in unary operator");
+          return 0;
+        }
+      }
+
+      if (Code == UnOpInit::CAR
+          || Code == UnOpInit::CDR) {
+        if (LHSl && LHSl->getSize() == 0) {
+          TokError("empty list argument in unary operator");
+          return 0;
+        }
+        if (LHSl) {
+          Init *Item = LHSl->getElement(0);
+          TypedInit *Itemt = dynamic_cast<TypedInit*>(Item);
+          if (Itemt == 0) {
+            TokError("untyped list element in unary operator");
+            return 0;
+          }
+          if (Code == UnOpInit::CAR) {
+            Type = Itemt->getType();
+          }
+          else {
+            Type = new ListRecTy(Itemt->getType());
+          }
+        }
+        else {
+          assert(LHSt && "expected list type argument in unary operator");
+          ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
+          if (LType == 0) {
+            TokError("expected list type argumnet in unary operator");
+            return 0;
+          }
+          if (Code == UnOpInit::CAR) {
+            Type = LType->getElementType();
+          }
+          else {
+            Type = LType;
+          }
+        }
+      }
+    }
+
     if (Lex.getCode() != tgtok::r_paren) {
       TokError("expected ')' in unary operator");
       return 0;
@@ -1072,6 +1142,9 @@
     break;
   }
  
+  case tgtok::XCar:
+  case tgtok::XCdr:
+  case tgtok::XNull:
   case tgtok::XCast:  // Value ::= !unop '(' Value ')'
   case tgtok::XConcat:
   case tgtok::XSRA: