[llvm-commits] [llvm] r71805 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/lisp.td utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGLexer.cpp utils/TableGen/TGLexer.h utils/TableGen/TGParser.cpp

Gabor Greif ggreif at gmail.com
Fri May 15 03:27:19 PDT 2009


David,

did you consider adding the (more modern) Scheme
equivalents of these primitives instead:

car --> head
cdr --> tail
(and possibly: null --> empty)

Car and Cdr have some very specific historical baggage added,
an I do not think TG should willingly ingherit this legacy.

Just my 2 cents,

cheers,

    Gabor


On May 15, 12:38 am, David Greene <gree... at obbligato.org> wrote:
> Author: greened
> Date: Thu May 14 17:38:31 2009
> New Revision: 71805
>
> URL:http://llvm.org/viewvc/llvm-project?rev=71805&view=rev
> Log:
>
> 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
>
> Added:
>     llvm/trunk/test/TableGen/lisp.td
> Modified:
>     llvm/trunk/docs/TableGenFundamentals.html
>     llvm/trunk/utils/TableGen/Record.cpp
>     llvm/trunk/utils/TableGen/Record.h
>     llvm/trunk/utils/TableGen/TGLexer.cpp
>     llvm/trunk/utils/TableGen/TGLexer.h
>     llvm/trunk/utils/TableGen/TGParser.cpp
>
> Modified: llvm/trunk/docs/TableGenFundamentals.html
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundament...
>
> ==============================================================================
> --- llvm/trunk/docs/TableGenFundamentals.html (original)
> +++ llvm/trunk/docs/TableGenFundamentals.html Thu May 14 17:38:31 2009
> @@ -411,6 +411,12 @@
>    <dd>For each member 'b' of dag or list 'a' apply operator 'c.'  'b' is a
>  dummy variable that should be declared as a member variable of an instantiated
>  class.  This operation is analogous to $(foreach) in GNU make.</dd>
> +<dt><tt>!car(a)</tt></dt>
> +  <dd>The first element of list 'a.'</dd>
> +<dt><tt>!cdr(a)</tt></dt>
> +  <dd>The 2nd-N elements of list 'a.'</dd>
> +<dt><tt>!null(a)</tt></dt>
> +  <dd>An integer {0,1} indicating whether list 'a' is empty.</dd>
>  </dl>
>
>  <p>Note that all of the values have rules specifying how they convert to values
>
> Added: llvm/trunk/test/TableGen/lisp.td
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/lisp.td?...
>
> ==============================================================================
> --- llvm/trunk/test/TableGen/lisp.td (added)
> +++ llvm/trunk/test/TableGen/lisp.td Thu May 14 17:38:31 2009
> @@ -0,0 +1,21 @@
> +// RUN: tblgen %s | grep {}
> +
> +class List<list<string> n> {
> +  list<string> names = n;
> +}
> +
> +class CAR<string e> {
> +  string element = e;
> +}
> +
> +class CDR<list<string> r, int n> {
> +  list<string> rest = r;
> +  int null = n;
> +}
> +
> +class NameList<list<string> Names> :
> +  List<Names>, CAR<!car(Names)>, CDR<!cdr(Names), !null(!cdr(Names))>;
> +
> +def Three : NameList<["Tom", "Dick", "Harry"]>;
> +
> +def One : NameList<["Jeffrey Sinclair"]>;
>
> Modified: llvm/trunk/utils/TableGen/Record.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record....
>
> ==============================================================================
> --- llvm/trunk/utils/TableGen/Record.cpp (original)
> +++ llvm/trunk/utils/TableGen/Record.cpp Thu May 14 17:38:31 2009
> @@ -520,6 +520,41 @@
>      }
>      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 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() + ")";
>  }
>
> Modified: llvm/trunk/utils/TableGen/Record.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record....
>
> ==============================================================================
> --- llvm/trunk/utils/TableGen/Record.h (original)
> +++ llvm/trunk/utils/TableGen/Record.h Thu May 14 17:38:31 2009
> @@ -690,9 +690,14 @@
>  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 @@
>
>    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 @@
>  ///
>  class UnOpInit : public OpInit {
>  public:
> -  enum UnaryOp { CAST };
> +  enum UnaryOp { CAST, CAR, CDR, LNULL };
>  private:
>    UnaryOp Opc;
>    Init *LHS;
>
> Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer...
>
> ==============================================================================
> --- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
> +++ llvm/trunk/utils/TableGen/TGLexer.cpp Thu May 14 17:38:31 2009
> @@ -450,6 +450,9 @@
>    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");
>  }
>
> Modified: llvm/trunk/utils/TableGen/TGLexer.h
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer...
>
> ==============================================================================
> --- llvm/trunk/utils/TableGen/TGLexer.h (original)
> +++ llvm/trunk/utils/TableGen/TGLexer.h Thu May 14 17:38:31 2009
> @@ -46,7 +46,7 @@
>
>      // !keywords.
>      XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
> -    XForEach,
> +    XForEach, XCar, XCdr, XNull,
>
>      // Integer value.
>      IntVal,
>
> Modified: llvm/trunk/utils/TableGen/TGParser.cpp
> URL:http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParse...
>
> ==============================================================================
> --- llvm/trunk/utils/TableGen/TGParser.cpp (original)
> +++ llvm/trunk/utils/TableGen/TGParser.cpp Thu May 14 17:38:31 2009
> @@ -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:
>
> _______________________________________________
> llvm-commits mailing list
> llvm-comm... at cs.uiuc.eduhttp://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list