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>parameters;
map<perm_string,param_expr_t>localparams; map<perm_string,param_expr_t>localparams;
// Defined types in the scope.
map<perm_string,data_type_t*>typedefs;
// Named events in the scope. // Named events in the scope.
map<perm_string,PEvent*>events; map<perm_string,PEvent*>events;
@ -105,6 +108,8 @@ class LexicalScope {
LexicalScope* parent_scope() const { return parent_; } LexicalScope* parent_scope() const { return parent_; }
protected: protected:
void dump_typedefs_(ostream&out, unsigned indent) const;
void dump_parameters_(ostream&out, unsigned indent) const; void dump_parameters_(ostream&out, unsigned indent) const;
void dump_localparams_(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; 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; 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 <discipline> DISCIPLINE_IDENTIFIER
%token <text> PATHPULSE_IDENTIFIER %token <text> PATHPULSE_IDENTIFIER
%token <number> BASED_NUMBER DEC_NUMBER %token <number> BASED_NUMBER DEC_NUMBER
@ -706,10 +706,11 @@ block_item_decl
if ($1) delete $1; 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 ';' | 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; if ($1) delete $1;
} }
@ -784,11 +785,18 @@ data_type
{ $$ = $1; } { $$ = $1; }
| enum_data_type | enum_data_type
{ $$ = $1; } { $$ = $1; }
| TYPE_IDENTIFIER
{ yyerror(@1, "sorry: Named types not supported here");
$$ = 0;
}
; ;
type_declaration type_declaration
: K_typedef data_type IDENTIFIER ';' : 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", /* 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_timeunit_decl;
extern bool have_timeprec_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 * Export these functions because we have to generate PENumber class
* in pform.cc for user defparam definition from command file. * 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; 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) static void pform_put_behavior_in_scope(PProcess*pp)
{ {
lexical_scope->behaviors.push_back(pp); lexical_scope->behaviors.push_back(pp);

View File

@ -224,6 +224,8 @@ extern void pform_endgenerate();
*/ */
extern PGenerate* pform_parent_generate(void); 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 * The makewire functions announce to the pform code new wires. These
* go into a module that is currently opened. * 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; 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, static void dump_attributes_map(ostream&out,
const map<perm_string,PExpr*>&attributes, const map<perm_string,PExpr*>&attributes,
int ind) 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 void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
{ {
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t; typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t;
@ -1189,6 +1203,8 @@ void Module::dump(ostream&out) const
out << ")" << endl; out << ")" << endl;
} }
dump_typedefs_(out, 4);
dump_parameters_(out, 4); dump_parameters_(out, 4);
dump_localparams_(out, 4); dump_localparams_(out, 4);

View File

@ -70,6 +70,9 @@ struct decl_assignment_t {
*/ */
struct data_type_t : public LineInfo { struct data_type_t : public LineInfo {
virtual ~data_type_t() = 0; 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;
}; };
/* /*