diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index feeddd88e..f0e7ee25b 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -423,3 +423,13 @@ ExpUNot::ExpUNot(Expression*op1) ExpUNot::~ExpUNot() { } + +ExpCast::ExpCast(Expression*base, const VType*type) : + base_(base), type_(type) +{ +} + +ExpCast::~ExpCast() +{ +} + diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index b791f9a21..28ab2b16f 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -674,4 +674,25 @@ class ExpUNot : public ExpUnary { void dump(ostream&out, int indent = 0) const; }; +/* + * Class that wraps other expressions to cast them to other types. + */ +class ExpCast : public Expression { + + public: + ExpCast(Expression*base, const VType*type); + ~ExpCast(); + + inline int elaborate_expr(Entity*ent, Architecture*arc, const VType*) { + return base_->elaborate_expr(ent, arc, type_); + } + void write_to_stream(std::ostream&fd); + int emit(ostream&out, Entity*ent, Architecture*arc); + void dump(ostream&out, int indent = 0) const; + + private: + Expression*base_; + const VType*type_; +}; + #endif /* IVL_expression_H */ diff --git a/vhdlpp/expression_debug.cc b/vhdlpp/expression_debug.cc index befd6ea84..da5e25385 100644 --- a/vhdlpp/expression_debug.cc +++ b/vhdlpp/expression_debug.cc @@ -68,3 +68,11 @@ void ExpConcat::dump(ostream&out, int indent) const operand1_->dump(out, indent); operand2_->dump(out, indent); } + +void ExpCast::dump(ostream&out, int indent) const +{ + out << "Casting "; + base_->dump(out, indent+4); + out << " to "; + type_->emit_def(out, empty_perm_string); +} diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 2c1e510e5..122962868 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -860,3 +860,13 @@ int ExpUNot::emit(ostream&out, Entity*ent, Architecture*arc) out << ")"; return errors; } + +int ExpCast::emit(ostream&out, Entity*ent, Architecture*arc) +{ + int errors = 0; + errors += type_->emit_def(out, empty_perm_string); + out << "'("; + errors += base_->emit(out, ent, arc); + out << ")"; + return errors; +} diff --git a/vhdlpp/expression_stream.cc b/vhdlpp/expression_stream.cc index 103e210ae..80864265e 100644 --- a/vhdlpp/expression_stream.cc +++ b/vhdlpp/expression_stream.cc @@ -230,3 +230,9 @@ void ExpUNot::write_to_stream(ostream&fd) write_to_stream_operand1(fd); } +void ExpCast::write_to_stream(ostream&fd) +{ + // Type casting is introduced only for a few specific cases in + // SystemVerilog, so no need to use it here + base_->write_to_stream(fd); +}