diff options
author | David Greene <greened@obbligato.org> | 2009-05-14 22:38:31 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2009-05-14 22:38:31 +0000 |
commit | 04c89a100940fa2649e4f8b1458a0e4a07e9d8ad (patch) | |
tree | bd237c2d0cb6a5ec6c114294dfdb5bd049d1501a /utils/TableGen | |
parent | 2c38321556ce9b0ec69d7c228fe6cb7b07b6fd1e (diff) | |
download | external_llvm-04c89a100940fa2649e4f8b1458a0e4a07e9d8ad.zip external_llvm-04c89a100940fa2649e4f8b1458a0e4a07e9d8ad.tar.gz external_llvm-04c89a100940fa2649e4f8b1458a0e4a07e9d8ad.tar.bz2 |
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
Diffstat (limited to 'utils/TableGen')
-rw-r--r-- | utils/TableGen/Record.cpp | 38 | ||||
-rw-r--r-- | utils/TableGen/Record.h | 10 | ||||
-rw-r--r-- | utils/TableGen/TGLexer.cpp | 3 | ||||
-rw-r--r-- | utils/TableGen/TGLexer.h | 2 | ||||
-rw-r--r-- | utils/TableGen/TGParser.cpp | 75 |
5 files changed, 122 insertions, 6 deletions
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index ade1702..ae2c2f3 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -520,6 +520,41 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { } break; } + case CAR: { + ListInit *LHSl = dynamic_cast<ListInit*>(LHS); + if (LHSl) { + if (LHSl->getSize() == 0) { + assert(0 && "Empty list in car"); + return 0; + } + return LHSl->getElement(0); + } + break; + } + case CDR: { + ListInit *LHSl = dynamic_cast<ListInit*>(LHS); + if (LHSl) { + if (LHSl->getSize() == 0) { + assert(0 && "Empty list in cdr"); + return 0; + } + ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end()); + return Result; + } + break; + } + case LNULL: { + ListInit *LHSl = dynamic_cast<ListInit*>(LHS); + if (LHSl) { + if (LHSl->getSize() == 0) { + return new IntInit(1); + } + else { + return new IntInit(0); + } + } + break; + } } return this; } @@ -536,6 +571,9 @@ std::string UnOpInit::getAsString() const { std::string Result; switch (Opc) { case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break; + case CAR: Result = "!car"; break; + case CDR: Result = "!cdr"; break; + case LNULL: Result = "!null"; break; } return Result + "(" + LHS->getAsString() + ")"; } diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index c37f6e6..c2549da 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -690,9 +690,14 @@ public: class ListInit : public Init { std::vector<Init*> Values; public: + typedef std::vector<Init*>::iterator iterator; + typedef std::vector<Init*>::const_iterator const_iterator; + explicit ListInit(std::vector<Init*> &Vs) { Values.swap(Vs); } + explicit ListInit(iterator Start, iterator End) + : Values(Start, End) {} unsigned getSize() const { return Values.size(); } Init *getElement(unsigned i) const { @@ -717,9 +722,6 @@ public: virtual std::string getAsString() const; - typedef std::vector<Init*>::iterator iterator; - typedef std::vector<Init*>::const_iterator const_iterator; - inline iterator begin() { return Values.begin(); } inline const_iterator begin() const { return Values.begin(); } inline iterator end () { return Values.end(); } @@ -761,7 +763,7 @@ public: /// class UnOpInit : public OpInit { public: - enum UnaryOp { CAST }; + enum UnaryOp { CAST, CAR, CDR, LNULL }; private: UnaryOp Opc; Init *LHS; diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp index 6215a72..faf1e75 100644 --- a/utils/TableGen/TGLexer.cpp +++ b/utils/TableGen/TGLexer.cpp @@ -450,6 +450,9 @@ tgtok::TokKind TGLexer::LexExclaim() { if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst; if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach; if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast; + if (Len == 3 && !memcmp(Start, "car", 3)) return tgtok::XCar; + if (Len == 3 && !memcmp(Start, "cdr", 3)) return tgtok::XCdr; + if (Len == 4 && !memcmp(Start, "null", 4)) return tgtok::XNull; return ReturnError(Start-1, "Unknown operator"); } diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h index 3993e89..3d27e5e 100644 --- a/utils/TableGen/TGLexer.h +++ b/utils/TableGen/TGLexer.h @@ -46,7 +46,7 @@ namespace tgtok { // !keywords. XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst, - XForEach, + XForEach, XCar, XCdr, XNull, // Integer value. IntVal, 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 @@ Init *TGParser::ParseOperation(Record *CurRec) { 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 @@ Init *TGParser::ParseOperation(Record *CurRec) { 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 *TGParser::ParseOperation(Record *CurRec) { 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 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { break; } + case tgtok::XCar: + case tgtok::XCdr: + case tgtok::XNull: case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XSRA: |