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(); }
|
||||
void map_choices(choice_element*dst);
|
||||
|
||||
inline Expression* extract_expression() { return val_; }
|
||||
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue