Parse record types, and some new aggregate types.
This commit is contained in:
parent
f7ba954ef7
commit
9ed56a6354
|
|
@ -215,6 +215,8 @@ class ExpAggregate : public Expression {
|
||||||
size_t count_choices() const { return fields_.size(); }
|
size_t count_choices() const { return fields_.size(); }
|
||||||
void map_choices(choice_element*dst);
|
void map_choices(choice_element*dst);
|
||||||
|
|
||||||
|
inline Expression* extract_expression() { return val_; }
|
||||||
|
|
||||||
void dump(ostream&out, int indent) const;
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
122
vhdlpp/parse.y
122
vhdlpp/parse.y
|
|
@ -139,6 +139,47 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
return active_scope->find_type(name);
|
return active_scope->find_type(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This funciton is called when an aggregate expression is detected by
|
||||||
|
// the parser. It makes the ExpAggregate. It also tries to detect the
|
||||||
|
// special case that the aggregate is really a primary. The problem is
|
||||||
|
// that this:
|
||||||
|
// ( <expression> )
|
||||||
|
// also matches the pattern:
|
||||||
|
// ( [ choices => ] <expression> ... )
|
||||||
|
// so try to assume that a single expression in parentheses is a
|
||||||
|
// primary and fix the parse by returning an Expression instead of an
|
||||||
|
// ExpAggregate.
|
||||||
|
static Expression*aggregate_or_primary(const YYLTYPE&loc, std::list<ExpAggregate::element_t*>*el)
|
||||||
|
{
|
||||||
|
if (el->size() != 1) {
|
||||||
|
ExpAggregate*tmp = new ExpAggregate(el);
|
||||||
|
FILE_NAME(tmp,loc);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpAggregate::element_t*el1 = el->front();
|
||||||
|
if (el1->count_choices() > 0) {
|
||||||
|
ExpAggregate*tmp = new ExpAggregate(el);
|
||||||
|
FILE_NAME(tmp,loc);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return el1->extract_expression();
|
||||||
|
}
|
||||||
|
|
||||||
|
static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
|
||||||
|
const VType*type)
|
||||||
|
{
|
||||||
|
list<VTypeRecord::element_t*>*res = new list<VTypeRecord::element_t*>;
|
||||||
|
|
||||||
|
for (list<perm_string>::iterator cur = names->begin()
|
||||||
|
; cur != names->end() ; ++cur) {
|
||||||
|
res->push_back(new VTypeRecord::element_t(*cur, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -185,6 +226,8 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
ExpAggregate::element_t*element;
|
ExpAggregate::element_t*element;
|
||||||
std::list<ExpAggregate::element_t*>*element_list;
|
std::list<ExpAggregate::element_t*>*element_list;
|
||||||
|
|
||||||
|
std::list<VTypeRecord::element_t*>*record_elements;
|
||||||
|
|
||||||
std::list<InterfacePort*>* interface_list;
|
std::list<InterfacePort*>* interface_list;
|
||||||
|
|
||||||
Architecture::Statement* arch_statement;
|
Architecture::Statement* arch_statement;
|
||||||
|
|
@ -264,8 +307,11 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
%type <named_expr_list> association_list port_map_aspect port_map_aspect_opt
|
%type <named_expr_list> association_list port_map_aspect port_map_aspect_opt
|
||||||
%type <named_expr_list> generic_map_aspect generic_map_aspect_opt
|
%type <named_expr_list> generic_map_aspect generic_map_aspect_opt
|
||||||
|
|
||||||
|
%type <vtype> composite_type_definition record_type_definition
|
||||||
%type <vtype> subtype_indication type_definition
|
%type <vtype> subtype_indication type_definition
|
||||||
|
|
||||||
|
%type <record_elements> element_declaration element_declaration_list
|
||||||
|
|
||||||
%type <text> architecture_body_start package_declaration_start
|
%type <text> architecture_body_start package_declaration_start
|
||||||
%type <text> identifier_opt identifier_colon_opt logical_name suffix
|
%type <text> identifier_opt identifier_colon_opt logical_name suffix
|
||||||
%type <name_list> logical_name_list identifier_list
|
%type <name_list> logical_name_list identifier_list
|
||||||
|
|
@ -595,6 +641,17 @@ component_specification
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
composite_type_definition
|
||||||
|
/* constrained_array_definition */
|
||||||
|
: K_array index_constraint K_of subtype_indication
|
||||||
|
{ VTypeArray*tmp = new VTypeArray($4, $2);
|
||||||
|
delete $2;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| record_type_definition
|
||||||
|
{ $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
concurrent_signal_assignment_statement
|
concurrent_signal_assignment_statement
|
||||||
: name LEQ waveform ';'
|
: name LEQ waveform ';'
|
||||||
{ ExpName*name = dynamic_cast<ExpName*> ($1);
|
{ ExpName*name = dynamic_cast<ExpName*> ($1);
|
||||||
|
|
@ -699,6 +756,19 @@ constant_declaration
|
||||||
{ sorrymsg(@1, "Deferred constant declarations not supported\n");
|
{ sorrymsg(@1, "Deferred constant declarations not supported\n");
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some error handling... */
|
||||||
|
|
||||||
|
| K_constant identifier_list ':' subtype_indication VASSIGN error ';'
|
||||||
|
{ // The syntax allows mutliple names to have the same type/value.
|
||||||
|
errormsg(@6, "Error in value expression for constants.\n");
|
||||||
|
yyerrok;
|
||||||
|
for (std::list<perm_string>::iterator cur = $2->begin()
|
||||||
|
; cur != $2->end() ; ++cur) {
|
||||||
|
active_scope->bind_name(*cur, $4, 0);
|
||||||
|
}
|
||||||
|
delete $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
context_clause : context_items | ;
|
context_clause : context_items | ;
|
||||||
|
|
@ -732,6 +802,10 @@ element_association
|
||||||
{ ExpAggregate::element_t*tmp = new ExpAggregate::element_t($1, $3);
|
{ ExpAggregate::element_t*tmp = new ExpAggregate::element_t($1, $3);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| expression
|
||||||
|
{ ExpAggregate::element_t*tmp = new ExpAggregate::element_t(0, $1);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
element_association_list
|
element_association_list
|
||||||
|
|
@ -747,6 +821,21 @@ element_association_list
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
element_declaration
|
||||||
|
: identifier_list ':' subtype_indication ';'
|
||||||
|
{ $$ = record_elements($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
element_declaration_list
|
||||||
|
: element_declaration_list element_declaration
|
||||||
|
{ $$ = $1;
|
||||||
|
$$->splice($$->end(), *$2);
|
||||||
|
delete $2;
|
||||||
|
}
|
||||||
|
| element_declaration
|
||||||
|
{ $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
/* As an entity is declared, add it to the map of design entities. */
|
/* As an entity is declared, add it to the map of design entities. */
|
||||||
entity_aspect
|
entity_aspect
|
||||||
: K_entity name
|
: K_entity name
|
||||||
|
|
@ -1372,7 +1461,12 @@ package_declarative_item
|
||||||
: component_declaration
|
: component_declaration
|
||||||
| constant_declaration
|
| constant_declaration
|
||||||
| subtype_declaration
|
| subtype_declaration
|
||||||
|
| type_declaration
|
||||||
| use_clause
|
| use_clause
|
||||||
|
| error ';'
|
||||||
|
{ errormsg(@1, "Syntax error in package declarative item.\n");
|
||||||
|
yyerrok;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
package_declarative_items
|
package_declarative_items
|
||||||
|
|
@ -1479,7 +1573,10 @@ primary
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
/*XXXX Caught up in element_association_list?
|
||||||
|
| '(' expression ')'
|
||||||
|
{ $$ = $2; }
|
||||||
|
*/
|
||||||
/* This catches function calls that use association lists for the
|
/* This catches function calls that use association lists for the
|
||||||
argument list. The position argument list is discovered elsewhere
|
argument list. The position argument list is discovered elsewhere
|
||||||
and must be discovered by elaboration (thanks to the ambiguity of
|
and must be discovered by elaboration (thanks to the ambiguity of
|
||||||
|
|
@ -1489,11 +1586,10 @@ primary
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
| '(' expression ')'
|
/* Aggregates */
|
||||||
{ $$ = $2; }
|
|
||||||
| '(' element_association_list ')'
|
| '(' element_association_list ')'
|
||||||
{ ExpAggregate*tmp = new ExpAggregate($2);
|
{ Expression*tmp = aggregate_or_primary(@1, $2);
|
||||||
FILE_NAME(tmp,@1);
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -1638,6 +1734,13 @@ range_list
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
record_type_definition
|
||||||
|
: K_record element_declaration_list K_end K_record
|
||||||
|
{ VTypeRecord*tmp = new VTypeRecord($2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
relation
|
relation
|
||||||
: shift_expression
|
: shift_expression
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
|
|
@ -1911,12 +2014,9 @@ type_definition
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
/* constrained_array_definition */
|
| composite_type_definition
|
||||||
| K_array index_constraint K_of subtype_indication
|
{ $$ = $1; }
|
||||||
{ VTypeArray*tmp = new VTypeArray($4, $2);
|
|
||||||
delete $2;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
use_clause
|
use_clause
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,43 @@ void VTypeEnum::show(ostream&out) const
|
||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTypeRecord::VTypeRecord(std::list<element_t*>*elements)
|
||||||
|
: elements_(elements->size())
|
||||||
|
{
|
||||||
|
for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) {
|
||||||
|
elements_[idx] = elements->front();
|
||||||
|
elements->pop_front();
|
||||||
|
}
|
||||||
|
delete elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTypeRecord::~VTypeRecord()
|
||||||
|
{
|
||||||
|
for (size_t idx = 0 ; idx < elements_.size() ; idx += 1)
|
||||||
|
delete elements_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void VTypeRecord::show(ostream&out) const
|
||||||
|
{
|
||||||
|
out << "record ";
|
||||||
|
for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) {
|
||||||
|
elements_[idx]->show(out);
|
||||||
|
out << "; ";
|
||||||
|
}
|
||||||
|
out << "endrecord";
|
||||||
|
}
|
||||||
|
|
||||||
|
VTypeRecord::element_t::element_t(perm_string name, const VType*typ)
|
||||||
|
: name_(name), type_(typ)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void VTypeRecord::element_t::show(ostream&out) const
|
||||||
|
{
|
||||||
|
out << name_ << ":";
|
||||||
|
type_->show(out);
|
||||||
|
}
|
||||||
|
|
||||||
VTypeDef::VTypeDef(perm_string nam, const VType*typ)
|
VTypeDef::VTypeDef(perm_string nam, const VType*typ)
|
||||||
: name_(nam), type_(typ)
|
: name_(nam), type_(typ)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,38 @@ class VTypeEnum : public VType {
|
||||||
std::vector<perm_string>names_;
|
std::vector<perm_string>names_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VTypeRecord : public VType {
|
||||||
|
|
||||||
|
public:
|
||||||
|
class element_t {
|
||||||
|
public:
|
||||||
|
element_t(perm_string name, const VType*type);
|
||||||
|
|
||||||
|
void show(std::ostream&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string name_;
|
||||||
|
const VType*type_;
|
||||||
|
|
||||||
|
private:// Not implement
|
||||||
|
element_t(const element_t&);
|
||||||
|
element_t& operator= (const element_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VTypeRecord(std::list<element_t*>*elements);
|
||||||
|
~VTypeRecord();
|
||||||
|
|
||||||
|
void show(std::ostream&) const;
|
||||||
|
|
||||||
|
int emit_def(std::ostream&out, perm_string name) const;
|
||||||
|
private:
|
||||||
|
int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<element_t*> elements_;
|
||||||
|
};
|
||||||
|
|
||||||
class VTypeDef : public VType {
|
class VTypeDef : public VType {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,20 @@ int VTypeRange::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VTypeRecord::emit_def(ostream&out, perm_string name) const
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
assert(0);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VTypeRecord::emit_decl(ostream&out, perm_string name, bool reg_flag) const
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
assert(0);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int VTypeDef::emit_def(ostream&out, perm_string name) const
|
int VTypeDef::emit_def(ostream&out, perm_string name) const
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue