diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 8f8eafb08..0847f11a3 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -346,3 +346,10 @@ void named_expr_t::dump(ostream&out, int indent) const out << setw(indent) << "" << name_ << "=>"; expr_->dump(out, indent); } + +void range_t::dump(ostream&out, int indent) const +{ + left_->dump(out, indent); + out << setw(indent) << "" << (direction_ ? "downto" : "to"); + right_->dump(out, indent); +} diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index c61b3d984..655b26a1f 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -140,6 +140,8 @@ const VType*parse_type_by_name(perm_string name) const VType* vtype; + range_t* range; + std::list* interface_list; Architecture::Statement* arch_statement; @@ -211,7 +213,7 @@ const VType*parse_type_by_name(perm_string name) %type subtype_indication %type architecture_body_start package_declaration_start -%type identifier_opt logical_name suffix +%type identifier_opt identifier_colon_opt logical_name suffix %type logical_name_list identifier_list %type prefix selected_name %type selected_names use_clause @@ -219,6 +221,9 @@ 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 procedure_call procedure_call_statement +%type loop_statement + +%type range %type case_statement_alternative %type case_statement_alternative_list @@ -832,6 +837,7 @@ identifier_list identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ; +identifier_colon_opt : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; }; if_statement : K_if expression K_then sequence_of_statements @@ -993,6 +999,60 @@ logical_name_list } ; +loop_statement + : identifier_colon_opt + K_while expression_logical K_loop + sequence_of_statements + K_end K_loop identifier_opt ';' + { + if($1 && strcmp($1, $8)) + errormsg(@1, "Loop statement name doesn't match closing name.\n"); + if($1) delete[]$1; + if($8) delete[]$8; + + ExpLogical* cond = dynamic_cast($3); + if(!cond) { + errormsg(@3, "Iteration condition is not a correct logical expression"); + } + WhileLoopStatement* tmp = new WhileLoopStatement(cond, $5); + FILE_NAME(tmp, @1); + + sorrymsg(@1, "Loop statements are not supported"); + $$ = tmp; + } + | identifier_colon_opt K_for + IDENTIFIER K_in range K_loop + sequence_of_statements + K_end K_loop identifier_opt ';' + { + if($1 && strcmp($1, $10)) + errormsg(@1, "Loop statement name doesn't match closing name.\n"); + if($1) delete[] $1; + if($10) delete[] $10; + + ForLoopStatement* tmp = new ForLoopStatement(lex_strings.make($3), $5, $7); + delete[]$3; + FILE_NAME(tmp, @1); + + sorrymsg(@1, "Loop statements are not supported"); + $$ = tmp; + } + | identifier_colon_opt K_loop + sequence_of_statements + K_end K_loop identifier_opt ';' + { + if($1 && strcmp($1, $6)) + errormsg(@1, "Loop statement name doesn't match closing name.\n"); + if($1) delete[]$1; + if($6) delete[]$6; + + BasicLoopStatement* tmp = new BasicLoopStatement($3); + FILE_NAME(tmp, @1); + + sorrymsg(@1, "Loop statements are not supported"); + $$ = tmp; + }; + mode : K_in { $$ = PORT_IN; } | K_out { $$ = PORT_OUT; } @@ -1278,6 +1338,13 @@ process_sensitivity_list | name_list { $$ = $1; } ; +range + : simple_expression direction simple_expression + { + range_t* tmp = new range_t($1, $3, $2); + $$ = tmp; + } + ; relation : shift_expression @@ -1392,6 +1459,7 @@ sequential_statement | signal_assignment_statement { $$ = $1; } | case_statement { $$ = $1; } | procedure_call_statement { $$ = $1; } + | loop_statement { $$ = $1; } | K_null ';' { $$ = 0; } ; diff --git a/vhdlpp/parse_types.h b/vhdlpp/parse_types.h index 74c1e8ff1..c3695947a 100644 --- a/vhdlpp/parse_types.h +++ b/vhdlpp/parse_types.h @@ -66,4 +66,19 @@ class instant_list_t { application_domain_t domain_; std::list* labels_; }; + +class range_t { + public: + range_t(Expression* left, Expression* right, bool dir) + : left_(left), right_(right), direction_(dir) {} + ~range_t() { delete left_; delete right_; } + void dump(ostream&out, int indent) const; + + private: + Expression *left_, *right_; + bool direction_; + private: //not implemented + range_t(const range_t&); + range_t operator=(const range_t&); +}; #endif diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index b5c6b0a96..870ac6512 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -152,3 +152,46 @@ ProcedureCall::~ProcedureCall() delete cur; } } + +LoopStatement::LoopStatement(list* stmts) +{ + if (stmts) stmts_.splice(stmts_.end(), *stmts); +} + +LoopStatement::~LoopStatement() +{ + while(stmts_.size() > 0) { + SequentialStmt* cur = stmts_.front(); + stmts_.pop_front(); + delete cur; + } +} + +ForLoopStatement::ForLoopStatement(perm_string it, range_t* range, list* stmts) +: LoopStatement(stmts), it_(it), range_(range) +{ +} + +ForLoopStatement::~ForLoopStatement() +{ + delete range_; +} + +WhileLoopStatement::WhileLoopStatement(ExpLogical* cond, list* stmts) +: LoopStatement(stmts), cond_(cond) +{ +} + +WhileLoopStatement::~WhileLoopStatement() +{ + delete cond_; +} + +BasicLoopStatement::BasicLoopStatement(list* stmts) +: LoopStatement(stmts) +{ +} + +BasicLoopStatement::~BasicLoopStatement() +{ +} diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index 3b5caab0c..afefeb9e9 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -145,8 +145,60 @@ class ProcedureCall : public SequentialStmt { int elaborate(Entity*ent, Architecture*arc); int emit(ostream&out, Entity*entity, Architecture*arc); void dump(ostream&out, int indent) const; + private: perm_string name_; std::list* param_list_; }; + +class LoopStatement : public SequentialStmt { + public: + LoopStatement(list*); + virtual ~LoopStatement(); + + int elaborate(Entity*ent, Architecture*arc) = 0; + int emit(ostream&out, Entity*entity, Architecture*arc); + void dump(ostream&out, int indent) const; + + protected: + std::list stmts_; +}; + +class WhileLoopStatement : public LoopStatement { + public: + WhileLoopStatement(ExpLogical*, list*); + ~WhileLoopStatement(); + + int elaborate(Entity*ent, Architecture*arc); + int emit(ostream&out, Entity*entity, Architecture*arc); + void dump(ostream&out, int indent) const; + + private: + ExpLogical* cond_; +}; + +class ForLoopStatement : public LoopStatement { + public: + ForLoopStatement(perm_string, range_t*, list*); + ~ForLoopStatement(); + + int elaborate(Entity*ent, Architecture*arc); + int emit(ostream&out, Entity*entity, Architecture*arc); + void dump(ostream&out, int indent) const; + + private: + perm_string it_; + range_t* range_; +}; + +class BasicLoopStatement : public LoopStatement { + public: + BasicLoopStatement(list*); + ~BasicLoopStatement(); + + int elaborate(Entity*ent, Architecture*arc); + int emit(ostream&out, Entity*entity, Architecture*arc); + void dump(ostream&out, int indent) const; + +}; #endif diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index fe78df513..688497aa0 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -109,3 +109,32 @@ void ProcedureCall::dump(ostream& out, int indent) const (*it)->dump(out, indent); out << ")" << endl; } + +void LoopStatement::dump(ostream&out, int indent) const +{ + for(list::const_iterator it = stmts_.begin(); + it != stmts_.end(); ++it) + (*it)->dump(out, indent); +} + +void ForLoopStatement::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "ForLoopStatement at file=" << get_fileline() << endl; + out << setw(indent) << "" << it_ << " in "; + range_->dump(out, indent); + LoopStatement::dump(out, indent+2); +} + +void WhileLoopStatement::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "WhileLoopStatement at file=" << get_fileline() << endl; + out << setw(indent) << "" << "condition: "; + cond_->dump(out, indent); + LoopStatement::dump(out, indent+2); +} + +void BasicLoopStatement::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "BasicLoopStatement at file=" << get_fileline() << endl; + LoopStatement::dump(out, indent+2); +} diff --git a/vhdlpp/sequential_elaborate.cc b/vhdlpp/sequential_elaborate.cc index 9fdb48647..9c7a04506 100644 --- a/vhdlpp/sequential_elaborate.cc +++ b/vhdlpp/sequential_elaborate.cc @@ -93,3 +93,19 @@ int ProcedureCall::elaborate(Entity*, Architecture*) { return 0; } + +int ForLoopStatement::elaborate(Entity*entity, Architecture*arc) +{ + return 0; +} + +int WhileLoopStatement::elaborate(Entity*entity, Architecture*arc) +{ + //TODO:check whether there is any wait statement in the statements (there should be) + return 0; +} + +int BasicLoopStatement::elaborate(Entity*entity, Architecture*arc) +{ + return 0; +} diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 97761b56d..20aa5adc7 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -106,3 +106,35 @@ int ProcedureCall::emit(ostream&out, Entity*, Architecture*) << "type=" << typeid(*this).name() << endl; return 1; } + +int LoopStatement::emit(ostream&out, Entity*entity, Architecture*arc) +{ + out << " // " << get_fileline() << ": internal error: " + << "I don't know how to emit this sequential statement! " + << "type=" << typeid(*this).name() << endl; + return 1; +} + +int ForLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc) +{ + out << " // " << get_fileline() << ": internal error: " + << "I don't know how to emit this sequential statement! " + << "type=" << typeid(*this).name() << endl; + return 1; +} + +int WhileLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc) +{ + out << " // " << get_fileline() << ": internal error: " + << "I don't know how to emit this sequential statement! " + << "type=" << typeid(*this).name() << endl; + return 1; +} + +int BasicLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc) +{ + out << " // " << get_fileline() << ": internal error: " + << "I don't know how to emit this sequential statement! " + << "type=" << typeid(*this).name() << endl; + return 1; +}