Parse generic clause in entity headers
The generic clause can create named generics in entities. This patch gets the parser support for them working, even though they cannot yet evaluate.
This commit is contained in:
parent
6268db6e68
commit
a6f63b8a54
|
|
@ -38,12 +38,19 @@ ComponentBase::~ComponentBase()
|
|||
delete *it;
|
||||
}
|
||||
|
||||
void ComponentBase::set_interface(std::list<InterfacePort*>*ports)
|
||||
void ComponentBase::set_interface(std::list<InterfacePort*>*parms,
|
||||
std::list<InterfacePort*>*ports)
|
||||
{
|
||||
while (! ports->empty()) {
|
||||
ports_.push_back(ports->front());
|
||||
ports->pop_front();
|
||||
}
|
||||
if (parms) {
|
||||
while (! parms->empty()) {
|
||||
parms_.push_back(parms->front());
|
||||
parms->pop_front();
|
||||
}
|
||||
}
|
||||
while (! ports->empty()) {
|
||||
ports_.push_back(ports->front());
|
||||
ports->pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
const InterfacePort* ComponentBase::find_port(perm_string my_name) const
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@
|
|||
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t;
|
||||
|
||||
class Architecture;
|
||||
class Expression;
|
||||
|
||||
class InterfacePort : public LineInfo {
|
||||
public:
|
||||
InterfacePort() { mode = PORT_NONE; type=0; }
|
||||
InterfacePort() { mode = PORT_NONE; type=0; expr=0; }
|
||||
|
||||
// Port direction from the source code.
|
||||
port_mode_t mode;
|
||||
|
|
@ -41,6 +42,8 @@ class InterfacePort : public LineInfo {
|
|||
perm_string name;
|
||||
// Name of interface type as given in the source code.
|
||||
const VType*type;
|
||||
// Default value expression (or nil)
|
||||
Expression*expr;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -63,7 +66,8 @@ class ComponentBase : public LineInfo {
|
|||
// method with a list of interface elements that were parsed
|
||||
// for the entity. This method collects those entities, and
|
||||
// empties the list in the process.
|
||||
void set_interface(std::list<InterfacePort*>*ports);
|
||||
void set_interface(std::list<InterfacePort*>*parms,
|
||||
std::list<InterfacePort*>*ports);
|
||||
|
||||
|
||||
void write_to_stream(std::ostream&fd) const;
|
||||
|
|
@ -77,6 +81,7 @@ class ComponentBase : public LineInfo {
|
|||
|
||||
private:
|
||||
perm_string name_;
|
||||
std::vector<InterfacePort*> parms_;
|
||||
std::vector<InterfacePort*> ports_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -408,10 +408,8 @@ bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
|
|||
Expression*exp;
|
||||
|
||||
bool rc = scope->find_constant(name_, type, exp);
|
||||
if (rc == false) {
|
||||
cerr << "XXXX Unable to evaluate name " << name_ << "." << endl;
|
||||
if (rc == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return exp->evaluate(scope, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,9 +224,10 @@ const VType*parse_type_by_name(perm_string name)
|
|||
|
||||
%type <flag> direction
|
||||
|
||||
%type <interface_list> interface_element interface_list entity_header
|
||||
%type <interface_list> interface_element interface_list
|
||||
%type <interface_list> port_clause port_clause_opt
|
||||
%type <port_mode> mode
|
||||
%type <interface_list> generic_clause generic_clause_opt
|
||||
%type <port_mode> mode mode_opt
|
||||
|
||||
%type <entity_aspect> entity_aspect entity_aspect_opt binding_indication binding_indication_semicolon_opt
|
||||
%type <instantiation_list> instantiation_list
|
||||
|
|
@ -246,6 +247,7 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <expr> expression_logical_xnor expression_logical_xor
|
||||
%type <expr> name
|
||||
%type <expr> shift_expression simple_expression term waveform_element
|
||||
%type <expr> interface_element_expression
|
||||
|
||||
%type <expr_list> waveform waveform_elements
|
||||
%type <expr_list> name_list expression_list
|
||||
|
|
@ -531,7 +533,7 @@ component_declaration
|
|||
|
||||
ComponentBase*comp = new ComponentBase(name);
|
||||
if ($4) {
|
||||
comp->set_interface($4);
|
||||
comp->set_interface(0, $4);
|
||||
delete $4;
|
||||
}
|
||||
active_scope->bind_name(name, comp);
|
||||
|
|
@ -753,23 +755,22 @@ entity_aspect_opt
|
|||
;
|
||||
|
||||
entity_declaration
|
||||
: K_entity IDENTIFIER K_is entity_header K_end K_entity_opt identifier_opt';'
|
||||
: K_entity IDENTIFIER
|
||||
K_is generic_clause_opt port_clause_opt
|
||||
K_end K_entity_opt identifier_opt';'
|
||||
{ Entity*tmp = new Entity(lex_strings.make($2));
|
||||
FILE_NAME(tmp, @1);
|
||||
// Transfer the ports
|
||||
std::list<InterfacePort*>*ports = $4;
|
||||
tmp->set_interface(ports);
|
||||
delete ports;
|
||||
tmp->set_interface($4, $5);
|
||||
delete $4;
|
||||
delete $5;
|
||||
// Save the entity in the entity map.
|
||||
design_entities[tmp->get_name()] = tmp;
|
||||
delete[]$2;
|
||||
if($7) {
|
||||
if(tmp->get_name() != $7) {
|
||||
errormsg(@1, "Syntax error in entity clause. Closing name doesn't match.\n");
|
||||
yyerrok;
|
||||
if($8 && tmp->get_name() != $8) {
|
||||
errormsg(@1, "Syntax error in entity clause. Closing name doesn't match.\n");
|
||||
}
|
||||
delete[]$7;
|
||||
}
|
||||
delete[]$8;
|
||||
}
|
||||
| K_entity error K_end K_entity_opt identifier_opt ';'
|
||||
{ errormsg(@1, "Too many errors, giving up on entity declaration.\n");
|
||||
|
|
@ -778,11 +779,6 @@ entity_declaration
|
|||
}
|
||||
;
|
||||
|
||||
entity_header
|
||||
: port_clause
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
enumeration_literal
|
||||
: IDENTIFIER
|
||||
{ list<perm_string>*tmp = new list<perm_string>;
|
||||
|
|
@ -942,6 +938,24 @@ factor
|
|||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
generic_clause_opt
|
||||
: generic_clause
|
||||
{ $$ = $1;}
|
||||
|
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
generic_clause
|
||||
: K_generic '(' interface_list ')' ';'
|
||||
{ $$ = $3; }
|
||||
| K_generic '(' error ')' ';'
|
||||
{ errormsg(@3, "Error in interface list for generic.\n");
|
||||
yyerrok;
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
generic_map_aspect_opt
|
||||
: generic_map_aspect
|
||||
|
|
||||
|
|
@ -1071,7 +1085,7 @@ instantiation_list
|
|||
|
||||
/* The interface_element is also an interface_declaration */
|
||||
interface_element
|
||||
: identifier_list ':' mode subtype_indication
|
||||
: identifier_list ':' mode_opt subtype_indication interface_element_expression
|
||||
{ std::list<InterfacePort*>*tmp = new std::list<InterfacePort*>;
|
||||
for (std::list<perm_string>::iterator cur = $1->begin()
|
||||
; cur != $1->end() ; ++cur) {
|
||||
|
|
@ -1080,6 +1094,7 @@ interface_element
|
|||
port->mode = $3;
|
||||
port->name = *(cur);
|
||||
port->type = $4;
|
||||
port->expr = $5;
|
||||
tmp->push_back(port);
|
||||
}
|
||||
delete $1;
|
||||
|
|
@ -1087,6 +1102,11 @@ interface_element
|
|||
}
|
||||
;
|
||||
|
||||
interface_element_expression
|
||||
: VASSIGN expression { $$ = $2; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
interface_list
|
||||
: interface_list ';' interface_element
|
||||
{ std::list<InterfacePort*>*tmp = $1;
|
||||
|
|
@ -1200,6 +1220,8 @@ mode
|
|||
| K_out { $$ = PORT_OUT; }
|
||||
;
|
||||
|
||||
mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ;
|
||||
|
||||
name
|
||||
: IDENTIFIER
|
||||
{ ExpName*tmp = new ExpName(lex_strings.make($1));
|
||||
|
|
|
|||
Loading…
Reference in New Issue