diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index edcabea3d..a4b2965db 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -128,6 +128,9 @@ const VType*parse_type_by_name(perm_string name) IfSequential::Elsif*elsif; std::list*elsif_list; + + CaseSeqStmt::CaseStmtAlternative* case_alt; + std::list* case_alt_list; named_expr_t*named_expr; std::list*named_expr_list; @@ -192,10 +195,10 @@ const VType*parse_type_by_name(perm_string name) %type process_statement %type architecture_statement_part -%type expression factor primary relation +%type choice expression factor primary relation %type expression_logical expression_logical_and expression_logical_or %type expression_logical_xnor expression_logical_xor -%type name +%type name %type shift_expression simple_expression term waveform_element %type waveform waveform_elements @@ -215,6 +218,10 @@ const VType*parse_type_by_name(perm_string name) %type sequence_of_statements if_statement_else %type sequential_statement if_statement signal_assignment_statement +%type case_statement + +%type case_statement_alternative +%type case_statement_alternative_list %type if_statement_elsif %type 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* tmp = $1; + tmp->push_back($2); + $$ = tmp; + } + | case_statement_alternative + { + std::list*tmp = + new std::list(); + 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; } ; diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index 4d04ea757..e879568d8 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -101,3 +101,35 @@ SignalSeqAssignment::~SignalSeqAssignment() { delete lval_; } + +CaseSeqStmt::CaseSeqStmt(Expression*cond, list* 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* stmts) + : exp_(exp) +{ + if (stmts) stmts_.splice(stmts_.end(), *stmts); +} diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index 5799a5ea4..cccaca9d5 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -102,4 +102,36 @@ class SignalSeqAssignment : public SequentialStmt { std::list waveform_; }; +class CaseSeqStmt : public SequentialStmt { + public: + class CaseStmtAlternative : public LineInfo { + public: + CaseStmtAlternative(Expression* exp, list* 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 stmts_; + private: // not implemented + CaseStmtAlternative(const CaseStmtAlternative&); + CaseStmtAlternative& operator =(const CaseStmtAlternative&); + }; + CaseSeqStmt(Expression*cond, + list*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 alt_; +}; #endif diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index e8434b2ef..703c7c6c9 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -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::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::const_iterator cur = stmts_.begin() + ; cur != stmts_.end(); ++cur) + (*cur)->dump(out, indent+1); +}