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 | d571b3c94b087e8560a14a427d623d70b1a9011c (patch) | |
tree | 3d92bb86774ee7720f0541312ba042b8c6b3f9b8 /llvm/utils/TableGen/TGParser.cpp | |
parent | e917fff30f9bb8c24a656492449d72d8262c7d7f (diff) | |
download | bcm5719-llvm-d571b3c94b087e8560a14a427d623d70b1a9011c.tar.gz bcm5719-llvm-d571b3c94b087e8560a14a427d623d70b1a9011c.zip |
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
llvm-svn: 71805
Diffstat (limited to 'llvm/utils/TableGen/TGParser.cpp')
-rw-r--r-- | llvm/utils/TableGen/TGParser.cpp | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/llvm/utils/TableGen/TGParser.cpp b/llvm/utils/TableGen/TGParser.cpp index bc5d65eea59..8ff25a6186b 100644 --- a/llvm/utils/TableGen/TGParser.cpp +++ b/llvm/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: |