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:
parent
e14628193a
commit
42b3e6f268
5
PScope.h
5
PScope.h
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
16
parse.y
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
22
pform.cc
22
pform.cc
|
|
@ -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);
|
||||
|
|
|
|||
2
pform.h
2
pform.h
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue