diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 628f234ab..0271abe37 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -218,6 +218,7 @@ class ExpAggregate : public Expression { // Return prange_t if this represents a range_expression prange_t*range_expressions(void); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; private: @@ -246,6 +247,7 @@ class ExpAggregate : public Expression { void map_choices(choice_element*dst); inline Expression* extract_expression() { return val_; } + void write_to_stream(std::ostream&fd) const; void dump(ostream&out, int indent) const; diff --git a/vhdlpp/expression_stream.cc b/vhdlpp/expression_stream.cc index bf4e41aba..b8da43179 100644 --- a/vhdlpp/expression_stream.cc +++ b/vhdlpp/expression_stream.cc @@ -18,14 +18,55 @@ */ # include "expression.h" +# include "parse_types.h" # include # include using namespace std; -void ExpAggregate::write_to_stream(ostream&) +void ExpAggregate::write_to_stream(ostream&fd) { - ivl_assert(*this, !"Not supported"); + fd << "("; + for (vector::const_iterator cur = elements_.begin() + ; cur != elements_.end() ; ++cur) { + (*cur)->write_to_stream(fd); + } + fd << ")"; +} + +void ExpAggregate::element_t::write_to_stream(ostream&fd) const +{ + for (vector::const_iterator cur = fields_.begin() + ; cur != fields_.end() ; ++cur) { + (*cur)->write_to_stream(fd); + } + + fd << "=>"; + val_->write_to_stream(fd); +} + +void ExpAggregate::choice_t::write_to_stream(ostream&fd) +{ + if (others()) { + fd << "others"; + return; + } + + if (Expression*sim = simple_expression()) { + sim->write_to_stream(fd); + return; + } + + if (prange_t*rp = range_expressions()) { + rp->msb()->write_to_stream(fd); + if (rp->is_downto()) + fd << " downto "; + else + fd << " to "; + rp->msb()->write_to_stream(fd); + } + + fd << "/* ERROR */"; } void ExpArithmetic::write_to_stream(ostream&out) @@ -76,9 +117,14 @@ void ExpBitstring::write_to_stream(ostream&) ivl_assert(*this, !"Not supported"); } -void ExpCharacter::write_to_stream(ostream&) +void ExpCharacter::write_to_stream(ostream&fd) { - ivl_assert(*this, !"Not supported"); + char buf[4]; + buf[0] = '\''; + buf[1] = value_; + buf[2] = '\''; + buf[3] = 0; + fd << buf; } void ExpConcat::write_to_stream(ostream&fd) @@ -100,9 +146,17 @@ void ExpEdge::write_to_stream(ostream&) ivl_assert(*this, !"Not supported"); } -void ExpFunc::write_to_stream(ostream&) +void ExpFunc::write_to_stream(ostream&fd) { - ivl_assert(*this, !"Not supported"); + const char*comma = ""; + fd << name_ << "("; + for (vector::iterator cur = argv_.begin() + ; cur != argv_.end() ; ++cur) { + fd << comma; + (*cur)->write_to_stream(fd); + comma = ", "; + } + fd << ")"; } void ExpInteger::write_to_stream(ostream&fd) diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index b711e6673..a897ef15e 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -1140,6 +1140,10 @@ for_generate_statement } ; +function_specification /* IEEE 1076-2008 P4.2.1 */ + : K_function IDENTIFIER '(' interface_list ')' K_return IDENTIFIER + ; + generate_statement /* IEEE 1076-2008 P11.8 */ : if_generate_statement | for_generate_statement @@ -1304,6 +1308,10 @@ if_statement_else index_constraint : '(' range_list ')' { $$ = $2; } + | '(' error ')' + { errormsg(@2, "Errors in the index constraint.\n"); + $$ = new list; + } ; instantiation_list @@ -1336,7 +1344,6 @@ interface_element port->name = *(cur); port->type = $4; port->expr = $5; - ivl_assert(*port, port->type); tmp->push_back(port); } delete $1; @@ -1569,6 +1576,7 @@ package_body_declarative_part_opt package_declarative_item : component_declaration | constant_declaration + | subprogram_declaration | subtype_declaration | type_declaration | use_clause @@ -2019,6 +2027,16 @@ signal_assignment_statement } ; +subprogram_declaration + : subprogram_specification ';' + { sorrymsg(@1, "Subprogram specifications not supported.\n"); + } + ; + +subprogram_specification + : function_specification + ; + subtype_declaration : K_subtype IDENTIFIER K_is subtype_indication ';' { perm_string name = lex_strings.make($2); @@ -2035,6 +2053,7 @@ subtype_indication { const VType*tmp = parse_type_by_name(lex_strings.make($1)); if (tmp == 0) { errormsg(@1, "Can't find type name `%s'\n", $1); + tmp = new VTypeERROR; } delete[]$1; $$ = tmp; @@ -2056,8 +2075,8 @@ subtype_indication $$ = tmp; } | IDENTIFIER '(' error ')' - { - errormsg(@1, "Syntax error in subtype indication.\n"); + { errormsg(@1, "Syntax error in subtype indication.\n"); + $$ = new VTypeERROR; } ; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 047b89528..4da22363d 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -97,6 +97,14 @@ inline std::ostream&operator << (std::ostream&out, const VType&item) extern void preload_global_types(void); +/* + * This type is a placeholder for ERROR types. + */ +class VTypeERROR : public VType { + public: + int emit_def(std::ostream&out) const; +}; + /* * This class represents the primitive types that are available to the * type subsystem. diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index f5ca68883..a3ca1add5 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -51,6 +51,12 @@ int VType::emit_typedef(std::ostream&, typedef_context_t&) const return 0; } +int VTypeERROR::emit_def(ostream&out) const +{ + out << "/* ERROR */"; + return 1; +} + int VTypeArray::emit_def(ostream&out) const { int errors = 0; @@ -93,7 +99,7 @@ int VTypeArray::emit_def(ostream&out) const int VTypeArray::emit_typedef(std::ostream&out, typedef_context_t&ctx) const { - etype_->emit_typedef(out, ctx); + return etype_->emit_typedef(out, ctx); } int VTypeEnum::emit_def(ostream&out) const