From 2063c5ee9d9ea240bddb26384856110dc4ea6db2 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 5 Nov 2011 15:55:17 -0700 Subject: [PATCH] Support VHDL user defined array types. --- vhdlpp/architec.cc | 2 +- vhdlpp/architec.h | 4 ++-- vhdlpp/debug.cc | 2 +- vhdlpp/parse.y | 36 ++++++++++++++++++++++++++++++++++-- vhdlpp/parse_types.h | 10 +++++----- vhdlpp/sequential.cc | 2 +- vhdlpp/sequential.h | 4 ++-- vhdlpp/vtype.cc | 21 +++++++++++++++++++++ vhdlpp/vtype.h | 2 ++ 9 files changed, 69 insertions(+), 14 deletions(-) diff --git a/vhdlpp/architec.cc b/vhdlpp/architec.cc index ea60fe801..05a31809b 100644 --- a/vhdlpp/architec.cc +++ b/vhdlpp/architec.cc @@ -59,7 +59,7 @@ GenerateStatement::~GenerateStatement() } ForGenerate::ForGenerate(perm_string gname, perm_string genvar, - range_t*rang, std::list&s) + prange_t*rang, std::list&s) : GenerateStatement(gname, s), genvar_(genvar), lsb_(rang->lsb()), msb_(rang->msb()) { diff --git a/vhdlpp/architec.h b/vhdlpp/architec.h index af23766c6..2a40189ef 100644 --- a/vhdlpp/architec.h +++ b/vhdlpp/architec.h @@ -32,7 +32,7 @@ class ExpName; class SequentialStmt; class Signal; class named_expr_t; -class range_t; +class prange_t; /* * The Architecture class carries the contents (name, statements, @@ -114,7 +114,7 @@ class ForGenerate : public GenerateStatement { public: ForGenerate(perm_string gname, perm_string genvar, - range_t*rang, std::list&s); + prange_t*rang, std::list&s); ~ForGenerate(); int elaborate(Entity*ent, Architecture*arc); diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 7d72dd0b5..1c2569139 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -435,7 +435,7 @@ void named_expr_t::dump(ostream&out, int indent) const expr_->dump(out, indent); } -void range_t::dump(ostream&out, int indent) const +void prange_t::dump(ostream&out, int indent) const { left_->dump(out, indent); out << setw(indent) << "" << (direction_ ? "downto" : "to"); diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 6b2386357..9fcada854 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -175,7 +175,8 @@ const VType*parse_type_by_name(perm_string name) const VType* vtype; - range_t* range; + prange_t* range; + std::list*range_list; ExpArithmetic::fun_t arithmetic_op; @@ -278,6 +279,7 @@ const VType*parse_type_by_name(perm_string name) %type loop_statement variable_assignment_statement %type range +%type range_list index_constraint %type case_statement_alternative %type case_statement_alternative_list @@ -1110,6 +1112,11 @@ if_statement_else { $$ = 0; } ; +index_constraint + : '(' range_list ')' + { $$ = $2; } + ; + instantiation_list : identifier_list { @@ -1613,7 +1620,20 @@ process_sensitivity_list range : simple_expression direction simple_expression - { range_t* tmp = new range_t($1, $3, $2); + { prange_t* tmp = new prange_t($1, $3, $2); + $$ = tmp; + } + ; + +range_list + : range + { list*tmp = new list; + tmp->push_back($1); + $$ = tmp; + } + | range_list ',' range + { list*tmp = $1; + tmp->push_back($3); $$ = tmp; } ; @@ -1876,6 +1896,12 @@ type_declaration //active_scope->bind_name(name, tmp); active_scope->bind_name(name, $4); } + delete[]$2; + } + | K_type IDENTIFIER K_is error ';' + { errormsg(@4, "Error in type definition for %s\n", $2); + yyerrok; + delete[]$2; } ; @@ -1885,6 +1911,12 @@ 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; + } ; use_clause diff --git a/vhdlpp/parse_types.h b/vhdlpp/parse_types.h index b4909c9f5..7f24a0025 100644 --- a/vhdlpp/parse_types.h +++ b/vhdlpp/parse_types.h @@ -67,11 +67,11 @@ class instant_list_t { std::list* labels_; }; -class range_t { +class prange_t { public: - range_t(Expression* left, Expression* right, bool dir) + prange_t(Expression* left, Expression* right, bool dir) : left_(left), right_(right), direction_(dir) {} - ~range_t() { delete left_; delete right_; } + ~prange_t() { delete left_; delete right_; } void dump(ostream&out, int indent) const; Expression*msb() { return direction_? left_ : right_; } @@ -84,7 +84,7 @@ class range_t { bool direction_; private: //not implemented - range_t(const range_t&); - range_t operator=(const range_t&); + prange_t(const prange_t&); + prange_t operator=(const prange_t&); }; #endif diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index 2038dbbdc..894f0b667 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -168,7 +168,7 @@ LoopStatement::~LoopStatement() } } -ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, range_t* range, list* stmts) +ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, prange_t* range, list* stmts) : LoopStatement(scope_name, stmts), it_(it), range_(range) { } diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index ad43d3158..4f7b4ae68 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -205,7 +205,7 @@ class WhileLoopStatement : public LoopStatement { class ForLoopStatement : public LoopStatement { public: ForLoopStatement(perm_string loop_name, - perm_string index, range_t*, list*); + perm_string index, prange_t*, list*); ~ForLoopStatement(); int elaborate(Entity*ent, Architecture*arc); @@ -214,7 +214,7 @@ class ForLoopStatement : public LoopStatement { private: perm_string it_; - range_t* range_; + prange_t* range_; }; class BasicLoopStatement : public LoopStatement { diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 3ced96dcb..10230a48a 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -18,6 +18,7 @@ */ # include "vtype.h" +# include "parse_types.h" # include # include @@ -65,6 +66,26 @@ VTypeArray::VTypeArray(const VType*element, const vector&r, { } +/* + * Create a VTypeArray range set from a list of parsed ranges. + * FIXME: We are copying pointers from the prange_t object into the + * range_t. This means that we cannot delete the prange_t object + * unless we invent a way to remove the pointers from that object. So + * this is a memory leak. Something to fix. + */ +VTypeArray::VTypeArray(const VType*element, std::list*r, bool sv) +: etype_(element), ranges_(r->size()), signed_flag_(sv) +{ + for (size_t idx = 0 ; idx < ranges_.size() ; idx += 1) { + prange_t*curp = r->front(); + r->pop_front(); + Expression*msb = curp->msb(); + Expression*lsb = curp->lsb(); + ranges_[idx] = range_t(msb, lsb); + } +} + + VTypeArray::~VTypeArray() { } diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index c315de95f..bd3ffb788 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -27,6 +27,7 @@ # include "StringHeap.h" class Expression; +class prange_t; /* * A description of a VHDL type consists of a graph of VType @@ -140,6 +141,7 @@ class VTypeArray : public VType { public: VTypeArray(const VType*etype, const std::vector&r, bool signed_vector =false); + VTypeArray(const VType*etype, std::list*r, bool signed_vector =false); ~VTypeArray(); void write_to_stream(std::ostream&fd) const;