llvm.org GIT mirror llvm / 5f9f9ba
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 David Greene 10 years ago
7 changed file(s) with 149 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
410410
For each member 'b' of dag or list 'a' apply operator 'c.' 'b' is a
411411 dummy variable that should be declared as a member variable of an instantiated
412412 class. This operation is analogous to $(foreach) in GNU make.
413
!car(a)
414
The first element of list 'a.'
415
!cdr(a)
416
The 2nd-N elements of list 'a.'
417
!null(a)
418
An integer {0,1} indicating whether list 'a' is empty.
413419
414420
415421

Note that all of the values have rules specifying how they convert to values

0 // RUN: tblgen %s | grep {}
1
2 class List n> {
3 list names = n;
4 }
5
6 class CAR {
7 string element = e;
8 }
9
10 class CDR r, int n> {
11 list rest = r;
12 int null = n;
13 }
14
15 class NameList Names> :
16 List, CAR, CDR;
17
18 def Three : NameList<["Tom", "Dick", "Harry"]>;
19
20 def One : NameList<["Jeffrey Sinclair"]>;
519519 }
520520 break;
521521 }
522 case CAR: {
523 ListInit *LHSl = dynamic_cast(LHS);
524 if (LHSl) {
525 if (LHSl->getSize() == 0) {
526 assert(0 && "Empty list in car");
527 return 0;
528 }
529 return LHSl->getElement(0);
530 }
531 break;
532 }
533 case CDR: {
534 ListInit *LHSl = dynamic_cast(LHS);
535 if (LHSl) {
536 if (LHSl->getSize() == 0) {
537 assert(0 && "Empty list in cdr");
538 return 0;
539 }
540 ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end());
541 return Result;
542 }
543 break;
544 }
545 case LNULL: {
546 ListInit *LHSl = dynamic_cast(LHS);
547 if (LHSl) {
548 if (LHSl->getSize() == 0) {
549 return new IntInit(1);
550 }
551 else {
552 return new IntInit(0);
553 }
554 }
555 break;
556 }
522557 }
523558 return this;
524559 }
535570 std::string Result;
536571 switch (Opc) {
537572 case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
573 case CAR: Result = "!car"; break;
574 case CDR: Result = "!cdr"; break;
575 case LNULL: Result = "!null"; break;
538576 }
539577 return Result + "(" + LHS->getAsString() + ")";
540578 }
689689 class ListInit : public Init {
690690 std::vector Values;
691691 public:
692 typedef std::vector::iterator iterator;
693 typedef std::vector::const_iterator const_iterator;
694
692695 explicit ListInit(std::vector &Vs) {
693696 Values.swap(Vs);
694697 }
698 explicit ListInit(iterator Start, iterator End)
699 : Values(Start, End) {}
695700
696701 unsigned getSize() const { return Values.size(); }
697702 Init *getElement(unsigned i) const {
716721
717722 virtual std::string getAsString() const;
718723
719 typedef std::vector::iterator iterator;
720 typedef std::vector::const_iterator const_iterator;
721
722724 inline iterator begin() { return Values.begin(); }
723725 inline const_iterator begin() const { return Values.begin(); }
724726 inline iterator end () { return Values.end(); }
760762 ///
761763 class UnOpInit : public OpInit {
762764 public:
763 enum UnaryOp { CAST };
765 enum UnaryOp { CAST, CAR, CDR, LNULL };
764766 private:
765767 UnaryOp Opc;
766768 Init *LHS;
449449 if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
450450 if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
451451 if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
452 if (Len == 3 && !memcmp(Start, "car", 3)) return tgtok::XCar;
453 if (Len == 3 && !memcmp(Start, "cdr", 3)) return tgtok::XCdr;
454 if (Len == 4 && !memcmp(Start, "null", 4)) return tgtok::XNull;
452455
453456 return ReturnError(Start-1, "Unknown operator");
454457 }
4545
4646 // !keywords.
4747 XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
48 XForEach,
48 XForEach, XCar, XCdr, XNull,
4949
5050 // Integer value.
5151 IntVal,
679679 TokError("unknown operation");
680680 return 0;
681681 break;
682 case tgtok::XCar:
683 case tgtok::XCdr:
684 case tgtok::XNull:
682685 case tgtok::XCast: { // Value ::= !unop '(' Value ')'
683686 UnOpInit::UnaryOp Code;
684687 RecTy *Type = 0;
692695 Type = ParseOperatorType();
693696
694697 if (Type == 0) {
695 TokError("did not get type for binary operator");
698 TokError("did not get type for unary operator");
696699 return 0;
697700 }
698701
702 break;
703 case tgtok::XCar:
704 Lex.Lex(); // eat the operation
705 Code = UnOpInit::CAR;
706 break;
707 case tgtok::XCdr:
708 Lex.Lex(); // eat the operation
709 Code = UnOpInit::CDR;
710 break;
711 case tgtok::XNull:
712 Lex.Lex(); // eat the operation
713 Code = UnOpInit::LNULL;
714 Type = new IntRecTy;
699715 break;
700716 }
701717 if (Lex.getCode() != tgtok::l_paren) {
706722
707723 Init *LHS = ParseValue(CurRec);
708724 if (LHS == 0) return 0;
725
726 if (Code == UnOpInit::CAR
727 || Code == UnOpInit::CDR
728 || Code == UnOpInit::LNULL) {
729 ListInit *LHSl = dynamic_cast(LHS);
730 TypedInit *LHSt = dynamic_cast(LHS);
731 if (LHSl == 0 && LHSt == 0) {
732 TokError("expected list type argument in unary operator");
733 return 0;
734 }
735 if (LHSt) {
736 ListRecTy *LType = dynamic_cast(LHSt->getType());
737 if (LType == 0) {
738 TokError("expected list type argumnet in unary operator");
739 return 0;
740 }
741 }
742
743 if (Code == UnOpInit::CAR
744 || Code == UnOpInit::CDR) {
745 if (LHSl && LHSl->getSize() == 0) {
746 TokError("empty list argument in unary operator");
747 return 0;
748 }
749 if (LHSl) {
750 Init *Item = LHSl->getElement(0);
751 TypedInit *Itemt = dynamic_cast(Item);
752 if (Itemt == 0) {
753 TokError("untyped list element in unary operator");
754 return 0;
755 }
756 if (Code == UnOpInit::CAR) {
757 Type = Itemt->getType();
758 }
759 else {
760 Type = new ListRecTy(Itemt->getType());
761 }
762 }
763 else {
764 assert(LHSt && "expected list type argument in unary operator");
765 ListRecTy *LType = dynamic_cast(LHSt->getType());
766 if (LType == 0) {
767 TokError("expected list type argumnet in unary operator");
768 return 0;
769 }
770 if (Code == UnOpInit::CAR) {
771 Type = LType->getElementType();
772 }
773 else {
774 Type = LType;
775 }
776 }
777 }
778 }
709779
710780 if (Lex.getCode() != tgtok::r_paren) {
711781 TokError("expected ')' in unary operator");
10711141 break;
10721142 }
10731143
1144 case tgtok::XCar:
1145 case tgtok::XCdr:
1146 case tgtok::XNull:
10741147 case tgtok::XCast: // Value ::= !unop '(' Value ')'
10751148 case tgtok::XConcat:
10761149 case tgtok::XSRA: