Skip to content

Commit

Permalink
Implement simple typedefs, and parse type identifiers.
Browse files Browse the repository at this point in the history
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
steveicarus committed Feb 3, 2012
1 parent e146281 commit 42b3e6f
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 4 deletions.
5 changes: 5 additions & 0 deletions PScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions lexor.lex
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
16 changes: 12 additions & 4 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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",
Expand Down
8 changes: 8 additions & 0 deletions parse_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
22 changes: 22 additions & 0 deletions pform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions pform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 16 additions & 0 deletions pform_dump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1189,6 +1203,8 @@ void Module::dump(ostream&out) const
out << ")" << endl;
}

dump_typedefs_(out, 4);

dump_parameters_(out, 4);

dump_localparams_(out, 4);
Expand Down
3 changes: 3 additions & 0 deletions pform_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand Down

0 comments on commit 42b3e6f

Please sign in to comment.