Rework elaborate/emit of types.

This rework is needed to reasonably handle new types, like enums.
This commit is contained in:
Stephen Williams 2011-10-02 10:56:00 -07:00
parent 271aaf6376
commit 30cfcbe2dc
7 changed files with 99 additions and 107 deletions

View File

@ -62,7 +62,7 @@ M = StringHeap.o LineInfo.o
O = main.o architec.o compiler.o entity.o \
expression.o package.o scope.o sequential.o vsignal.o vtype.o \
architec_elaborate.o entity_elaborate.o expression_elaborate.o \
sequential_elaborate.o vtype_elaborate.o \
sequential_elaborate.o \
entity_stream.o vtype_stream.o \
lexor.o lexor_keyword.o parse.o \
parse_misc.o library.o vhdlreal.o vhdlint.o \

View File

@ -23,9 +23,9 @@
# include <list>
# include <vector>
# include <iostream>
# include "vtype.h"
# include "StringHeap.h"
# include "LineInfo.h"
# include "vtype.h"
typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT } port_mode_t;

View File

@ -93,7 +93,6 @@ int Entity::elaborate_ports_(void)
; cur != ports.end() ; ++cur) {
InterfacePort*cur_port = *cur;
VType::decl_t cur_decl;
const VType*type = cur_port->type;
if (type == 0) {
@ -104,8 +103,8 @@ int Entity::elaborate_ports_(void)
continue;
}
type->elaborate(cur_decl);
VType::decl_t cur_decl;
cur_decl.type = type;
declarations_[cur_port->name] = cur_decl;
}

View File

@ -34,7 +34,7 @@ SigVarBase::~SigVarBase()
void SigVarBase::type_elaborate_(VType::decl_t&decl)
{
type_->elaborate(decl);
decl.type = type_;
}
int Signal::emit(ostream&out, Entity*, Architecture*)

View File

@ -48,18 +48,21 @@ class VType {
virtual void show(std::ostream&) const;
public:
enum vtype_t { VNONE, VBOOL, VLOGIC };
// A couple places use the VType along with a few
// per-declaration details, so provide a common structure for
// holding that stuff together.
struct decl_t {
public:
decl_t() : reg_flag(false), signed_flag(false), type(VNONE), msb(0), lsb(0) { }
decl_t() : type(0), reg_flag(false) { }
int emit(std::ostream&out, perm_string name) const;
public:
const VType*type;
bool reg_flag;
bool signed_flag;
vtype_t type;
long msb, lsb;
};
virtual void elaborate(decl_t&decl) const =0;
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)
@ -85,10 +88,14 @@ class VTypePrimitive : public VType {
void write_to_stream(std::ostream&fd) const;
void show(std::ostream&) const;
void elaborate(decl_t&decl) const;
type_t type() const { return type_; }
int emit_primitive_type(std::ostream&fd) const;
private:
int emit(std::ostream&out, perm_string name, bool reg_flag) const;
private:
type_t type_;
};
@ -128,7 +135,6 @@ class VTypeArray : public VType {
void write_to_stream(std::ostream&fd) const;
void show(std::ostream&) const;
void elaborate(decl_t&decl) const;
size_t dimensions() const;
const range_t&dimension(size_t idx) const
@ -138,6 +144,9 @@ class VTypeArray : public VType {
const VType* element_type() const;
private:
int emit(std::ostream&out, perm_string name, bool reg_flag) const;
private:
const VType*etype_;
@ -151,7 +160,8 @@ class VTypeRange : public VType {
VTypeRange(const VType*base, int64_t max_val, int64_t min_val);
~VTypeRange();
virtual void elaborate(decl_t&decl) const;
private:
int emit(std::ostream&out, perm_string name, bool reg_flag) const;
private:
const VType*base_;
@ -164,7 +174,8 @@ class VTypeEnum : public VType {
VTypeEnum(const std::list<perm_string>*names);
~VTypeEnum();
virtual void elaborate(decl_t&decl) const;
private:
int emit(std::ostream&out, perm_string name, bool reg_flag) const;
private:
std::vector<perm_string>names_;

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "vtype.h"
# include <typeinfo>
# include <cassert>
using namespace std;
void VTypeArray::elaborate(VType::decl_t&decl) const
{
const VTypePrimitive*base = dynamic_cast<const VTypePrimitive*>(etype_);
assert(base != 0);
base->elaborate(decl);
//assert(decl.msb == decl.lsb == 0);
decl.msb = dimension(0).msb();
decl.lsb = dimension(0).lsb();
decl.signed_flag = signed_flag_;
}
void VTypePrimitive::elaborate(VType::decl_t&decl) const
{
decl.type = VNONE;
decl.signed_flag = false;
decl.msb = 0;
decl.lsb = 0;
switch (type_) {
case BOOLEAN:
case BIT:
decl.type = VBOOL;
break;
case STDLOGIC:
decl.type = VLOGIC;
break;
case INTEGER:
decl.type = VBOOL;
decl.msb = 31;
decl.lsb = 0;
break;
}
}
void VTypeRange::elaborate(VType::decl_t&decl) const
{
base_->elaborate(decl);
}
void VTypeEnum::elaborate(decl_t&) const
{
}

View File

@ -25,31 +25,82 @@
using namespace std;
int VType::decl_t::emit(ostream&out, perm_string name) const
{
const char*wire = reg_flag? "reg" : "wire";
return type->emit(out, name, reg_flag);
}
switch (type) {
case VType::VNONE:
out << "// N type for " << name << endl;
int VTypeArray::emit(ostream&out, perm_string name, bool reg_flag) 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 ";
out << "[" << dimension(0).msb() << ":" << dimension(0).lsb() << "] ";
out << "\\" << name << " ";
return errors;
}
int VTypeEnum::emit(ostream&out, perm_string name, bool reg_flag) const
{
int errors = 0;
assert(0);
return errors;
}
int VTypePrimitive::emit_primitive_type(ostream&out) const
{
int errors = 0;
switch (type_) {
case BOOLEAN:
case BIT:
out << "bool ";
break;
case VType::VLOGIC:
out << wire<< " logic ";
if (signed_flag)
out << "signed ";
if (msb != lsb)
out << "[" << msb << ":" << lsb << "] ";
out << "\\" << name << " ";
case STDLOGIC:
out << "logic ";
break;
case VType::VBOOL:
out << wire << " bool ";
if (signed_flag)
out << "signed ";
if (msb != lsb)
out << "[" << msb << ":" << lsb << "] ";
out << "\\" << name << " ";
case INTEGER:
out << "bool [31:0] ";
break;
default:
assert(0);
break;
}
return 0;
return errors;
}
int VTypePrimitive::emit(ostream&out, perm_string name, bool reg_flag) const
{
int errors = 0;
if (reg_flag)
out << "reg ";
else
out << "wire ";
errors += emit_primitive_type(out);
out << "\\" << name << " ";
return errors;
}
int VTypeRange::emit(ostream&out, perm_string name, bool reg_flag) const
{
int errors = 0;
assert(0);
return errors;
}