typedef std::pair<Record*, std::vector<Init*>*> SubClassRefTy;
-static std::vector<std::pair<std::pair<std::string, std::vector<unsigned>*>,
- Init*> > SetStack;
+struct LetRecord {
+ std::string Name;
+ std::vector<unsigned> Bits;
+ Init *Value;
+ bool HasBits;
+ LetRecord(const std::string &N, std::vector<unsigned> *B, Init *V)
+ : Name(N), Value(V), HasBits(B != 0) {
+ if (HasBits) Bits = *B;
+ }
+};
+
+static std::vector<std::vector<LetRecord> > LetStack;
+
extern std::ostream &err();
static void addValue(const RecordVal &RV) {
- if (CurRec->getValue(RV.getName())) {
- err() << "Value '" << RV.getName() << "' multiply defined!\n";
- abort();
+ if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
+ // The value already exists in the class, treat this as a set...
+ if (ERV->setValue(RV.getValue())) {
+ err() << "New definition of '" << RV.getName() << "' of type '"
+ << *RV.getType() << "' is incompatible with previous "
+ << "definition of type '" << *ERV->getType() << "'!\n";
+ abort();
+ }
+ } else {
+ CurRec->addValue(RV);
}
-
- CurRec->addValue(RV);
}
static void addSuperClass(Record *SC) {
RecTy *Ty;
Init *Initializer;
std::vector<Init*> *FieldList;
- std::vector<Record*> *RecPtr;
std::vector<unsigned>*BitList;
Record *Rec;
SubClassRefTy *SubClassRef;
std::vector<SubClassRefTy> *SubClassList;
};
-%token INT BIT STRING BITS LIST CODE CLASS DEF FIELD SET IN
+%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN
%token <IntVal> INTVAL
-%token <StrVal> ID STRVAL
+%token <StrVal> ID STRVAL CODEFRAGMENT
%type <Ty> Type
-%type <RecPtr> DefList DefListNE
-%type <Rec> ClassInst DefInst Object ObjectBody ClassID DefID
+%type <Rec> ClassInst DefInst Object ObjectBody ClassID
%type <SubClassRef> SubClassRef
%type <SubClassList> ClassList ClassListNE
delete $1;
};
-DefID : ID {
- $$ = Records.getDef(*$1);
- if ($$ == 0) {
- err() << "Couldn't find def '" << *$1 << "'!\n";
- abort();
- }
- delete $1;
- };
-
// TableGen types...
Type : STRING { // string type
$$ = new BitsRecTy($3);
} | INT { // int type
$$ = new IntRecTy();
- } | LIST '<' ClassID '>' { // list<x> type
+ } | LIST '<' Type '>' { // list<x> type
$$ = new ListRecTy($3);
} | CODE { // code type
$$ = new CodeRecTy();
+ } | DAG { // dag type
+ $$ = new DagRecTy();
} | ClassID { // Record Type
$$ = new RecordRecTy($1);
};
} | STRVAL {
$$ = new StringInit(*$1);
delete $1;
+ } | CODEFRAGMENT {
+ $$ = new CodeInit(*$1);
+ delete $1;
} | '?' {
$$ = new UnsetInit();
} | '{' ValueList '}' {
$$ = Init;
delete $2;
} | ID {
- if (CurRec == 0) {
- err() << "Def/Class name '" << *$1 << "' not allowed here!\n";
- abort();
- }
- if (const RecordVal *RV = CurRec->getValue(*$1)) {
+ if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) {
$$ = new VarInit(*$1, RV->getType());
} else if (Record *D = Records.getDef(*$1)) {
$$ = new DefInit(D);
abort();
}
delete $3;
- } | '[' DefList ']' {
+ } | '[' ValueList ']' {
$$ = new ListInit(*$2);
delete $2;
} | Value '.' ID {
delete $3;
};
-DefList : /*empty */ {
- $$ = new std::vector<Record*>();
- } | DefListNE {
- $$ = $1;
- };
-DefListNE : DefID {
- $$ = new std::vector<Record*>();
- $$->push_back($1);
- } | DefListNE ',' DefID {
- ($$=$1)->push_back($3);
- };
-
-
RBitList : INTVAL {
$$ = new std::vector<unsigned>();
$$->push_back($1);
BodyItem : Declaration ';' {
delete $1;
-} | SET ID OptBitList '=' Value ';' {
+} | LET ID OptBitList '=' Value ';' {
setValue(*$2, $3, $5);
delete $2;
delete $3;
}
// Process any variables on the set stack...
- for (unsigned i = 0, e = SetStack.size(); i != e; ++i)
- setValue(SetStack[i].first.first, SetStack[i].first.second,
- SetStack[i].second);
+ for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+ for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+ setValue(LetStack[i][j].Name,
+ LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0,
+ LetStack[i][j].Value);
} Body {
CurRec->resolveReferences();
Object : ClassInst | DefInst;
-// SETCommand - A 'SET' statement start...
-SETCommand : SET ID OptBitList '=' Value IN {
- SetStack.push_back(std::make_pair(std::make_pair(*$2, $3), $5));
- delete $2;
+LETItem : ID OptBitList '=' Value {
+ LetStack.back().push_back(LetRecord(*$1, $2, $4));
+ delete $1; delete $2;
};
+LETList : LETItem | LETList ',' LETItem;
+
+// LETCommand - A 'LET' statement start...
+LETCommand : LET { LetStack.push_back(std::vector<LetRecord>()); } LETList IN;
+
// Support Set commands wrapping objects... both with and without braces.
-Object : SETCommand '{' ObjectList '}' {
- delete SetStack.back().first.second; // Delete OptBitList
- SetStack.pop_back();
+Object : LETCommand '{' ObjectList '}' {
+ LetStack.pop_back();
}
- | SETCommand Object {
- delete SetStack.back().first.second; // Delete OptBitList
- SetStack.pop_back();
+ | LETCommand Object {
+ LetStack.pop_back();
};
ObjectList : Object {} | ObjectList Object {};