Permalink
Browse files

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.
  • Loading branch information...
1 parent e146281 commit 42b3e6f26844a0d3c9167374a2d5d48f16e90d23 @steveicarus committed Jan 9, 2012
Showing with 75 additions and 4 deletions.
  1. +5 −0 PScope.h
  2. +7 −0 lexor.lex
  3. +12 −4 parse.y
  4. +8 −0 parse_misc.h
  5. +22 −0 pform.cc
  6. +2 −0 pform.h
  7. +16 −0 pform_dump.cc
  8. +3 −0 pform_types.h
View
@@ -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
@@ -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;
}
View
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",
View
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
};
/*

0 comments on commit 42b3e6f

Please sign in to comment.