Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit 42b3e6f26844a0d3c9167374a2d5d48f16e90d23 1 parent e146281
@steveicarus authored
View
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;
View
7 lexor.lex
@@ -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
8 parse_misc.h
@@ -78,6 +78,14 @@ 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
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);
View
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.
View
16 pform_dump.cc
@@ -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
3  pform_types.h
@@ -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;
};
/*
Please sign in to comment.
Something went wrong with that request. Please try again.