From 6268db6e68cac0067815ecbaeb3d60351cbd47c8 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 9 Oct 2011 15:25:35 -0700 Subject: [PATCH] Handle simple type declarations. --- vhdlpp/architec_emit.cc | 13 ++++++ vhdlpp/parse.y | 10 ++++- vhdlpp/vtype.cc | 19 +++++++++ vhdlpp/vtype.h | 46 ++++++++++++++++---- vhdlpp/vtype_emit.cc | 95 +++++++++++++++++++++++++++++++++++------ 5 files changed, 160 insertions(+), 23 deletions(-) diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index 34e71ca8a..893877451 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -64,6 +64,19 @@ int Architecture::emit(ostream&out, Entity*entity) { int errors = 0; + // Find typedefs that are present in the architecture body and + // emit them, so that following code can use the name instead + // of the full definition. + for (map::iterator cur = old_types_.begin() + ; cur != old_types_.end() ; ++cur) { + + const VTypeDef*def = dynamic_cast(cur->second); + if (def == 0) + continue; + + errors += def->emit_typedef(out); + } + for (map::iterator cur = old_constants_.begin() ; cur != old_constants_.end() ; ++cur) { diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index ad6b57c44..c419e1878 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -1792,7 +1792,15 @@ term type_declaration : K_type IDENTIFIER K_is type_definition ';' - { sorrymsg(@1, "type_declaration not supported.\n"); } + { perm_string name = lex_strings.make($2); + if ($4 == 0) { + errormsg(@1, "Failed to declare type name %s.\n", name.str()); + } else { + //VTypeDef*tmp = new VTypeDef(name, $4); + //active_scope->bind_name(name, tmp); + active_scope->bind_name(name, $4); + } + } ; type_definition diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 4be70e401..3ced96dcb 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -120,3 +120,22 @@ VTypeEnum::VTypeEnum(const std::list*names) VTypeEnum::~VTypeEnum() { } + +void VTypeEnum::show(ostream&out) const +{ + out << "("; + if (names_.size() >= 1) + out << names_[0]; + for (size_t idx = 1 ; idx < names_.size() ; idx += 1) + out << ", " << names_[idx]; + out << ")"; +} + +VTypeDef::VTypeDef(perm_string nam, const VType*typ) +: name_(nam), type_(typ) +{ +} + +VTypeDef::~VTypeDef() +{ +} diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 0be59e975..0fe6e835a 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -47,6 +47,16 @@ class VType { // really necessary given the write_to_stream method?) virtual void show(std::ostream&) const; + // This virtual method emits a definition for the specific + // type. It is used to emit typedef's. + virtual int emit_def(std::ostream&out, perm_string name) const =0; + + private: + friend class decl_t; + // This virtual method is called to emit the declaration. This + // is used by the decl_t object to emit variable/wire/port declarations. + virtual int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const =0; + public: // A couple places use the VType along with a few // per-declaration details, so provide a common structure for @@ -59,10 +69,6 @@ class VType { bool reg_flag; }; - private: - friend class decl_t; - // This virtual method is called to emit the declaration. - virtual int emit(std::ostream&out, perm_string name, bool reg_flag) const =0; }; inline std::ostream&operator << (std::ostream&out, const VType&item) @@ -93,8 +99,9 @@ class VTypePrimitive : public VType { int emit_primitive_type(std::ostream&fd) const; + int emit_def(std::ostream&out, perm_string name) const; private: - int emit(std::ostream&out, perm_string name, bool reg_flag) const; + int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; private: type_t type_; @@ -144,8 +151,10 @@ class VTypeArray : public VType { const VType* element_type() const; + int emit_def(std::ostream&out, perm_string name) const; + private: - int emit(std::ostream&out, perm_string name, bool reg_flag) const; + int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; private: const VType*etype_; @@ -160,8 +169,9 @@ class VTypeRange : public VType { VTypeRange(const VType*base, int64_t max_val, int64_t min_val); ~VTypeRange(); + int emit_def(std::ostream&out, perm_string name) const; private: - int emit(std::ostream&out, perm_string name, bool reg_flag) const; + int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; private: const VType*base_; @@ -174,11 +184,31 @@ class VTypeEnum : public VType { VTypeEnum(const std::list*names); ~VTypeEnum(); + void show(std::ostream&) const; + + int emit_def(std::ostream&out, perm_string name) const; private: - int emit(std::ostream&out, perm_string name, bool reg_flag) const; + int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; private: std::vectornames_; }; +class VTypeDef : public VType { + + public: + VTypeDef(perm_string name, const VType*is); + ~VTypeDef(); + + int emit_typedef(std::ostream&out) 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: + perm_string name_; + const VType*type_; +}; + #endif diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index f65506a86..d661bc689 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -28,22 +28,17 @@ using namespace std; int VType::decl_t::emit(ostream&out, perm_string name) const { - return type->emit(out, name, reg_flag); + return type->emit_decl(out, name, reg_flag); } -int VTypeArray::emit(ostream&out, perm_string name, bool reg_flag) const +int VTypeArray::emit_def(ostream&out, perm_string name) const { int errors = 0; const VTypePrimitive*base = dynamic_cast (etype_); assert(base != 0); assert(dimensions() == 1); - if (reg_flag) - out << "reg "; - else - out << "wire "; - base->emit_primitive_type(out); if (signed_flag_) out << "signed "; @@ -55,10 +50,41 @@ int VTypeArray::emit(ostream&out, perm_string name, bool reg_flag) const return errors; } -int VTypeEnum::emit(ostream&out, perm_string name, bool reg_flag) const +int VTypeArray::emit_decl(ostream&out, perm_string name, bool reg_flag) const { int errors = 0; - assert(0); + const VTypePrimitive*base = dynamic_cast (etype_); + assert(base != 0); + assert(dimensions() == 1); + + if (reg_flag) + out << "reg "; + else + out << "wire "; + + errors += emit_def(out, name); + + return errors; +} + +int VTypeEnum::emit_def(ostream&out, perm_string name) const +{ + int errors = 0; + out << "enum {"; + assert(names_.size() >= 1); + out << "\\" << names_[0] << " "; + for (size_t idx = 1 ; idx < names_.size() ; idx += 1) + out << ", \\" << names_[idx] << " "; + + out << "} \\" << name << " "; + + return errors; +} + +int VTypeEnum::emit_decl(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + errors += emit_def(out, name); return errors; } @@ -83,7 +109,15 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const return errors; } -int VTypePrimitive::emit(ostream&out, perm_string name, bool reg_flag) const +int VTypePrimitive::emit_def(ostream&out, perm_string name) const +{ + int errors = 0; + errors += emit_primitive_type(out); + out << "\\" << name << " "; + return errors; +} + +int VTypePrimitive::emit_decl(ostream&out, perm_string name, bool reg_flag) const { int errors = 0; if (reg_flag) @@ -91,16 +125,49 @@ int VTypePrimitive::emit(ostream&out, perm_string name, bool reg_flag) const else out << "wire "; - errors += emit_primitive_type(out); - - out << "\\" << name << " "; + errors += emit_def(out, name); return errors; } -int VTypeRange::emit(ostream&out, perm_string name, bool reg_flag) const +int VTypeRange::emit_def(ostream&out, perm_string name) const { int errors = 0; assert(0); return errors; } + +int VTypeRange::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; + assert(0); + return errors; +} + +int VTypeDef::emit_decl(ostream&out, perm_string name, bool reg_flag) const +{ + int errors = 0; + if (reg_flag) + out << "reg "; + else + out << "wire "; + + out << "\\" << name_ << " \\" << name << " "; + return errors; +} + +int VTypeDef::emit_typedef(ostream&out) const +{ + int errors = 0; + out << "typedef "; + errors += type_->emit_def(out, name_); + out << ";" << endl; + return errors; +}