Parse record types, and some new aggregate types.

This commit is contained in:
Stephen Williams 2012-03-17 15:03:19 -07:00
parent f7ba954ef7
commit 9ed56a6354
5 changed files with 196 additions and 11 deletions

View File

@ -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:

View File

@ -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

View File

@ -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)
{ {

View File

@ -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:

View File

@ -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;