Handle simple type declarations.

This commit is contained in:
Stephen Williams 2011-10-09 15:25:35 -07:00
parent 30cfcbe2dc
commit 6268db6e68
5 changed files with 160 additions and 23 deletions

View File

@ -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<perm_string,const VType*>::iterator cur = old_types_.begin()
; cur != old_types_.end() ; ++cur) {
const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second);
if (def == 0)
continue;
errors += def->emit_typedef(out);
}
for (map<perm_string,struct const_t*>::iterator cur = old_constants_.begin()
; cur != old_constants_.end() ; ++cur) {

View File

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

View File

@ -120,3 +120,22 @@ VTypeEnum::VTypeEnum(const std::list<perm_string>*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()
{
}

View File

@ -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<perm_string>*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::vector<perm_string>names_;
};
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

View File

@ -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<const VTypePrimitive*> (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<const VTypePrimitive*> (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;
}