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(); }
void map_choices(choice_element*dst);
inline Expression* extract_expression() { return val_; }
void dump(ostream&out, int indent) const;
private:

View File

@ -139,6 +139,47 @@ const VType*parse_type_by_name(perm_string 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;
std::list<ExpAggregate::element_t*>*element_list;
std::list<VTypeRecord::element_t*>*record_elements;
std::list<InterfacePort*>* interface_list;
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> generic_map_aspect generic_map_aspect_opt
%type <vtype> composite_type_definition record_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> identifier_opt identifier_colon_opt logical_name suffix
%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
: name LEQ waveform ';'
{ ExpName*name = dynamic_cast<ExpName*> ($1);
@ -699,6 +756,19 @@ constant_declaration
{ sorrymsg(@1, "Deferred constant declarations not supported\n");
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 | ;
@ -732,6 +802,10 @@ element_association
{ ExpAggregate::element_t*tmp = new ExpAggregate::element_t($1, $3);
$$ = tmp;
}
| expression
{ ExpAggregate::element_t*tmp = new ExpAggregate::element_t(0, $1);
$$ = tmp;
}
;
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. */
entity_aspect
: K_entity name
@ -1372,7 +1461,12 @@ package_declarative_item
: component_declaration
| constant_declaration
| subtype_declaration
| type_declaration
| use_clause
| error ';'
{ errormsg(@1, "Syntax error in package declarative item.\n");
yyerrok;
}
;
package_declarative_items
@ -1479,7 +1573,10 @@ primary
delete[]$1;
$$ = tmp;
}
/*XXXX Caught up in element_association_list?
| '(' expression ')'
{ $$ = $2; }
*/
/* This catches function calls that use association lists for the
argument list. The position argument list is discovered elsewhere
and must be discovered by elaboration (thanks to the ambiguity of
@ -1489,11 +1586,10 @@ primary
$$ = 0;
}
| '(' expression ')'
{ $$ = $2; }
/* Aggregates */
| '(' element_association_list ')'
{ ExpAggregate*tmp = new ExpAggregate($2);
FILE_NAME(tmp,@1);
{ Expression*tmp = aggregate_or_primary(@1, $2);
$$ = 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
: shift_expression
{ $$ = $1; }
@ -1911,12 +2014,9 @@ type_definition
delete $2;
$$ = tmp;
}
/* constrained_array_definition */
| K_array index_constraint K_of subtype_indication
{ VTypeArray*tmp = new VTypeArray($4, $2);
delete $2;
$$ = tmp;
}
| composite_type_definition
{ $$ = $1; }
;
use_clause

View File

@ -162,6 +162,43 @@ void VTypeEnum::show(ostream&out) const
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)
: name_(nam), type_(typ)
{

View File

@ -198,6 +198,38 @@ class VTypeEnum : public VType {
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 {
public:

View File

@ -159,6 +159,20 @@ int VTypeRange::emit_decl(ostream&out, perm_string name, bool reg_flag) const
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 errors = 0;