Implement simple typedefs, and parse type identifiers.

This gets me to the point where the parser stashes a defined type,
and the lexical analyzer uses the type names to differentiate
IDENTIFIER and TYPE_IDENTIFIER.
This commit is contained in:
Stephen Williams 2012-01-08 17:51:18 -08:00
parent e14628193a
commit 42b3e6f268
8 changed files with 75 additions and 4 deletions

View File

@ -83,6 +83,9 @@ class LexicalScope {
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
// Defined types in the scope.
map<perm_string,data_type_t*>typedefs;
// Named events in the scope.
map<perm_string,PEvent*>events;
@ -105,6 +108,8 @@ class LexicalScope {
LexicalScope* parent_scope() const { return parent_; }
protected:
void dump_typedefs_(ostream&out, unsigned indent) const;
void dump_parameters_(ostream&out, unsigned indent) const;
void dump_localparams_(ostream&out, unsigned indent) const;

View File

@ -308,6 +308,13 @@ TU [munpf]
}
}
/* If this identifer names a previously declared type, then
return this as a TYPE_IDENTIFIER instead. */
if (rc == IDENTIFIER && gn_system_verilog()) {
if (pform_test_type_identifier(yylval.text))
rc = TYPE_IDENTIFIER;
}
return rc;
}

16
parse.y
View File

@ -347,7 +347,7 @@ static void current_task_set_statement(vector<Statement*>*s)
list<index_component_t> *dimensions;
};
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
%token <text> IDENTIFIER SYSTEM_IDENTIFIER TYPE_IDENTIFIER STRING TIME_LITERAL
%token <discipline> DISCIPLINE_IDENTIFIER
%token <text> PATHPULSE_IDENTIFIER
%token <number> BASED_NUMBER DEC_NUMBER
@ -706,10 +706,11 @@ block_item_decl
if ($1) delete $1;
}
/* variable declarations */
/* variable declarations. Note that data_type can be 0 if we are
recovering from an error. */
| attribute_list_opt data_type register_variable_list ';'
{ pform_set_data_type(@2, $2, $3);
{ if ($2) pform_set_data_type(@2, $2, $3);
if ($1) delete $1;
}
@ -784,11 +785,18 @@ data_type
{ $$ = $1; }
| enum_data_type
{ $$ = $1; }
| TYPE_IDENTIFIER
{ yyerror(@1, "sorry: Named types not supported here");
$$ = 0;
}
;
type_declaration
: K_typedef data_type IDENTIFIER ';'
{ yyerror(@1, "sorry: typedef not yet supported."); }
{ perm_string name = lex_strings.make($3);
pform_set_typedef(name, $2);
delete[]$3;
}
;
/* The structure for an enumeration data type is the keyword "enum",

View File

@ -77,6 +77,14 @@ extern UCDriveType uc_drive;
extern bool have_timeunit_decl;
extern bool have_timeprec_decl;
/*
* Test if this identifier is a type identifier in the current
* context. The pform code needs to help the lexor here because the
* parser detects typedefs and marks the typedef'ed identifiers as
* type names.
*/
extern bool pform_test_type_identifier(const char*txt);
/*
* Export these functions because we have to generate PENumber class
* in pform.cc for user defparam definition from command file.

View File

@ -401,6 +401,28 @@ PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetN
return cur;
}
void pform_set_typedef(perm_string name, data_type_t*data_type)
{
data_type_t*&ref = lexical_scope->typedefs[name];
ivl_assert(*data_type, ref == 0);
ref = data_type;
}
bool pform_test_type_identifier(const char*txt)
{
// If there is no lexical_scope yet, then there is NO WAY the
// identifier can be a type_identifier.
if (lexical_scope == 0)
return false;
perm_string name = lex_strings.make(txt);
map<perm_string,data_type_t*>::iterator cur = lexical_scope->typedefs.find(name);
if (cur != lexical_scope->typedefs.end())
return true;
else
return false;
}
static void pform_put_behavior_in_scope(PProcess*pp)
{
lexical_scope->behaviors.push_back(pp);

View File

@ -224,6 +224,8 @@ extern void pform_endgenerate();
*/
extern PGenerate* pform_parent_generate(void);
extern void pform_set_typedef(perm_string name, data_type_t*data_type);
/*
* The makewire functions announce to the pform code new wires. These
* go into a module that is currently opened.

View File

@ -141,6 +141,11 @@ std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom)
return out;
}
void data_type_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << typeid(*this).name() << endl;
}
static void dump_attributes_map(ostream&out,
const map<perm_string,PExpr*>&attributes,
int ind)
@ -1050,6 +1055,15 @@ void PGenerate::dump(ostream&out, unsigned indent) const
}
}
void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
{
typedef map<perm_string,data_type_t*>::const_iterator iter_t;
for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) {
out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl;
cur->second->pform_dump(out, indent+4);
}
}
void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
{
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
@ -1189,6 +1203,8 @@ void Module::dump(ostream&out) const
out << ")" << endl;
}
dump_typedefs_(out, 4);
dump_parameters_(out, 4);
dump_localparams_(out, 4);

View File

@ -70,6 +70,9 @@ struct decl_assignment_t {
*/
struct data_type_t : public LineInfo {
virtual ~data_type_t() = 0;
// This method is used by the pform dumper to diagnostic dump.
virtual void pform_dump(std::ostream&out, unsigned indent) const;
};
/*