Add parser support for vhdl's case-when
Case-when statements are now recognized and turned into corresponding objects. Elaboration and emission is still not done.
This commit is contained in:
parent
bdb851428a
commit
5934dcc17c
|
|
@ -128,6 +128,9 @@ const VType*parse_type_by_name(perm_string name)
|
|||
|
||||
IfSequential::Elsif*elsif;
|
||||
std::list<IfSequential::Elsif*>*elsif_list;
|
||||
|
||||
CaseSeqStmt::CaseStmtAlternative* case_alt;
|
||||
std::list<CaseSeqStmt::CaseStmtAlternative*>* case_alt_list;
|
||||
|
||||
named_expr_t*named_expr;
|
||||
std::list<named_expr_t*>*named_expr_list;
|
||||
|
|
@ -192,10 +195,10 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <arch_statement> process_statement
|
||||
%type <arch_statement_list> architecture_statement_part
|
||||
|
||||
%type <expr> expression factor primary relation
|
||||
%type <expr> choice expression factor primary relation
|
||||
%type <expr> expression_logical expression_logical_and expression_logical_or
|
||||
%type <expr> expression_logical_xnor expression_logical_xor
|
||||
%type <expr> name
|
||||
%type <expr> name
|
||||
%type <expr> shift_expression simple_expression term waveform_element
|
||||
|
||||
%type <expr_list> waveform waveform_elements
|
||||
|
|
@ -215,6 +218,10 @@ const VType*parse_type_by_name(perm_string name)
|
|||
|
||||
%type <sequ_list> sequence_of_statements if_statement_else
|
||||
%type <sequ> sequential_statement if_statement signal_assignment_statement
|
||||
%type <sequ> case_statement
|
||||
|
||||
%type <case_alt> case_statement_alternative
|
||||
%type <case_alt_list> case_statement_alternative_list
|
||||
|
||||
%type <elsif> if_statement_elsif
|
||||
%type <elsif_list> if_statement_elsif_list if_statement_elsif_list_opt
|
||||
|
|
@ -379,6 +386,50 @@ block_declarative_items_opt
|
|||
: block_declarative_items
|
||||
|
|
||||
;
|
||||
case_statement
|
||||
: K_case expression K_is
|
||||
case_statement_alternative_list
|
||||
K_end K_case
|
||||
{
|
||||
sorrymsg(@1, "Case statement is not yet supported");
|
||||
CaseSeqStmt* tmp = new CaseSeqStmt($2, $4);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
case_statement_alternative_list
|
||||
: case_statement_alternative_list case_statement_alternative
|
||||
{ std::list<CaseSeqStmt::CaseStmtAlternative*>* tmp = $1;
|
||||
tmp->push_back($2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| case_statement_alternative
|
||||
{
|
||||
std::list<CaseSeqStmt::CaseStmtAlternative*>*tmp =
|
||||
new std::list<CaseSeqStmt::CaseStmtAlternative*>();
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
case_statement_alternative
|
||||
: K_when choice ARROW sequence_of_statements
|
||||
{
|
||||
CaseSeqStmt::CaseStmtAlternative* tmp =
|
||||
new CaseSeqStmt::CaseStmtAlternative($2, $4);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete $4;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
choice
|
||||
: expression
|
||||
{ $$ = $1;}
|
||||
| K_others
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
component_configuration
|
||||
: K_for component_specification
|
||||
|
|
@ -1305,6 +1356,7 @@ sequence_of_statements
|
|||
sequential_statement
|
||||
: if_statement { $$ = $1; }
|
||||
| signal_assignment_statement { $$ = $1; }
|
||||
| case_statement { $$ = $1; }
|
||||
;
|
||||
|
||||
shift_expression : simple_expression { $$ = $1; } ;
|
||||
|
|
|
|||
|
|
@ -101,3 +101,35 @@ SignalSeqAssignment::~SignalSeqAssignment()
|
|||
{
|
||||
delete lval_;
|
||||
}
|
||||
|
||||
CaseSeqStmt::CaseSeqStmt(Expression*cond, list<CaseSeqStmt::CaseStmtAlternative*>* ap)
|
||||
: cond_(cond)
|
||||
{
|
||||
|
||||
if (ap) alt_.splice(alt_.end(), *ap);
|
||||
}
|
||||
|
||||
CaseSeqStmt::~CaseSeqStmt()
|
||||
{
|
||||
delete cond_;
|
||||
while(alt_.size() > 0) {
|
||||
CaseSeqStmt::CaseStmtAlternative* cur = alt_.front();
|
||||
alt_.pop_front();
|
||||
delete cur;
|
||||
}
|
||||
}
|
||||
|
||||
CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative() {
|
||||
delete exp_;
|
||||
while(stmts_.size() > 0) {
|
||||
SequentialStmt* cur = stmts_.front();
|
||||
stmts_.pop_front();
|
||||
delete cur;
|
||||
}
|
||||
}
|
||||
|
||||
CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts)
|
||||
: exp_(exp)
|
||||
{
|
||||
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,4 +102,36 @@ class SignalSeqAssignment : public SequentialStmt {
|
|||
std::list<Expression*> waveform_;
|
||||
};
|
||||
|
||||
class CaseSeqStmt : public SequentialStmt {
|
||||
public:
|
||||
class CaseStmtAlternative : public LineInfo {
|
||||
public:
|
||||
CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts);
|
||||
~CaseStmtAlternative();
|
||||
void dump(ostream& out, int indent) const;
|
||||
|
||||
//TODO: implement the following:
|
||||
//int elaborate(Entity*ent, Architecture*arc);
|
||||
//int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
private:
|
||||
Expression* exp_;
|
||||
list<SequentialStmt*> stmts_;
|
||||
private: // not implemented
|
||||
CaseStmtAlternative(const CaseStmtAlternative&);
|
||||
CaseStmtAlternative& operator =(const CaseStmtAlternative&);
|
||||
};
|
||||
CaseSeqStmt(Expression*cond,
|
||||
list<CaseStmtAlternative*>*sp);
|
||||
~CaseSeqStmt();
|
||||
|
||||
public:
|
||||
void dump(ostream&out, int indent) const;
|
||||
//TODO: implement the following:
|
||||
//int elaborate(Entity*ent, Architecture*arc);
|
||||
//int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
|
||||
private:
|
||||
Expression* cond_;
|
||||
std::list<CaseStmtAlternative*> alt_;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -77,3 +77,25 @@ void SignalSeqAssignment::dump(ostream&out, int indent) const
|
|||
; cur != waveform_.end() ; ++cur)
|
||||
(*cur)->dump(out, indent+4);
|
||||
}
|
||||
|
||||
void CaseSeqStmt::dump(ostream& out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "CaseSeqStmt at file=" << get_fileline() << endl;
|
||||
|
||||
out << setw(indent+3) << "" << "Case: " << endl;
|
||||
cond_->dump(out, indent+4);
|
||||
|
||||
for (list<CaseSeqStmt::CaseStmtAlternative*>::const_iterator cur = alt_.begin()
|
||||
; cur != alt_.end() ; ++cur)
|
||||
(*cur)->dump(out, indent+4);
|
||||
}
|
||||
|
||||
void CaseSeqStmt::CaseStmtAlternative::dump(ostream& out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "CaseStmtAlternative at file=" << get_fileline() << endl;
|
||||
out << setw(indent) << "" << "when ";
|
||||
exp_->dump(out, 0);
|
||||
for (std::list<SequentialStmt*>::const_iterator cur = stmts_.begin()
|
||||
; cur != stmts_.end(); ++cur)
|
||||
(*cur)->dump(out, indent+1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue