Handle simple type declarations.
This commit is contained in:
parent
30cfcbe2dc
commit
6268db6e68
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue