Handle this as special identifier strings. / Organize pform class member binding

This commit is contained in:
Stephen Williams 2013-03-02 14:51:44 -08:00
parent 670601bc2a
commit fac5cbca43
8 changed files with 95 additions and 59 deletions

View File

@ -22,7 +22,7 @@
# include <cassert>
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), this_type_(0), ports_(0), statement_(0)
: PTaskFunc(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
return_type_.type = PTF_NONE;
@ -32,12 +32,6 @@ PFunction::~PFunction()
{
}
void PFunction::set_this(class_type_t*use_type)
{
assert(this_type_ == 0);
this_type_ = use_type;
}
void PFunction::set_ports(vector<PWire *>*p)
{
assert(ports_ == 0);

View File

@ -21,8 +21,23 @@
# include "PTask.h"
# include <cassert>
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
: PScope(n,p), this_type_(0)
{
}
PTaskFunc::~PTaskFunc()
{
}
void PTaskFunc::set_this(class_type_t*type)
{
assert(this_type_ == 0);
this_type_ = type;
}
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), this_type_(0), ports_(0), statement_(0)
: PTaskFunc(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
}
@ -31,12 +46,6 @@ PTask::~PTask()
{
}
void PTask::set_this(class_type_t*type)
{
assert(this_type_ == 0);
this_type_ = type;
}
void PTask::set_ports(vector<PWire*>*p)
{
assert(ports_ == 0);

32
PTask.h
View File

@ -50,16 +50,31 @@ struct PTaskFuncArg {
std::list<pform_range_t>*range;
};
class PTaskFunc : public PScope, public LineInfo {
public:
PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc();
void set_this(class_type_t*use_type);
// If this task is a method of a class, this returns a pointer
// to the class type.
inline class_type_t* method_of() const { return this_type_; }
private:
class_type_t*this_type_;
};
/*
* The PTask holds the parsed definitions of a task.
*/
class PTask : public PScope, public LineInfo {
class PTask : public PTaskFunc {
public:
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
~PTask();
void set_this(class_type_t*use_type);
void set_ports(std::vector<PWire *>*p);
void set_statement(Statement *s);
@ -77,14 +92,9 @@ class PTask : public PScope, public LineInfo {
bool is_auto() const { return is_auto_; };
// If this task is a method of a class, this returns a pointer
// to the class type.
inline class_type_t* method_of() const { return this_type_; }
void dump(ostream&, unsigned) const;
private:
class_type_t*this_type_;
std::vector<PWire*>*ports_;
Statement*statement_;
bool is_auto_;
@ -101,13 +111,12 @@ class PTask : public PScope, public LineInfo {
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public PScope, public LineInfo {
class PFunction : public PTaskFunc {
public:
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
~PFunction();
void set_this(class_type_t*use_type);
void set_ports(std::vector<PWire *>*p);
void set_statement(Statement *s);
void set_return(PTaskFuncArg t);
@ -122,14 +131,9 @@ class PFunction : public PScope, public LineInfo {
bool is_auto() const { return is_auto_; };
// If this function is a method of a class, this returns a
// pointer to the class type.
inline class_type_t* method_of() const { return this_type_; }
void dump(ostream&, unsigned) const;
private:
class_type_t*this_type_;
PTaskFuncArg return_type_;
std::vector<PWire *> *ports_;
Statement *statement_;

View File

@ -302,6 +302,18 @@ static void elaborate_scope_class(Design*des, NetScope*scope,
use_class->set_property(cur->first, tmp);
}
for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
; cur != pclass->tasks.end() ; ++cur) {
cerr << cur->second->get_fileline() << ": sorry: "
<< "Class methods (tasks) not supported." << endl;
}
for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
; cur != pclass->funcs.end() ; ++cur) {
cerr << cur->second->get_fileline() << ": sorry: "
<< "Class methods (functions) not supported." << endl;
}
scope->add_class(use_class);
}

57
parse.y
View File

@ -60,6 +60,19 @@ static PTask* current_task = 0;
static PFunction* current_function = 0;
static stack<PBlock*> current_block_stack;
static pform_name_t* pform_create_this(void)
{
name_component_t name (perm_string::literal("@"));
pform_name_t*res = new pform_name_t;
res->push_back(name);
return res;
}
static pform_name_t* pform_create_super(void)
{
return 0;
}
/* This is used to keep track of the extra arguments after the notifier
* in the $setuphold and $recrem timing checks. This allows us to print
* a warning message that the delayed signals will not be created. We
@ -544,9 +557,10 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <gate> gate_instance
%type <gates> gate_instance_list
%type <pform_name> hierarchy_identifier
%type <pform_name> hierarchy_identifier implicit_class_handle
%type <expr> assignment_pattern expression expr_primary expr_mintypmax
%type <expr> class_new dynamic_array_new inc_or_dec_expression inside_expression lpvalue
%type <expr> class_new dynamic_array_new
%type <expr> inc_or_dec_expression inside_expression lpvalue
%type <expr> branch_probe_expression streaming_concatenation
%type <expr> delay_value delay_value_simple
%type <exprs> delay1 delay3 delay3_opt delay_value_list
@ -771,14 +785,10 @@ class_item /* IEEE1800-2005: A.1.8 */
/* Class methods... */
| method_qualifier_opt task_declaration
{ yyerror(@2, "sorry: Class methods (tasks) not supported yet.");
yyerrok;
}
{ /* The task_declaration rule puts this into the class */ }
| method_qualifier_opt function_declaration
{ yyerror(@2, "sorry: Class methods (functions) not supported yet.");
yyerrok;
}
{ /* The function_declaration rule puts this into the class */ }
/* Class constraints... */
@ -1095,8 +1105,8 @@ function_declaration /* IEEE1800-2005: A.2.6 */
;
implicit_class_handle /* IEEE1800-2005: A.8.4 */
: K_this
| K_super
: K_this { $$ = pform_create_this(); }
| K_super { $$ = pform_create_super(); }
;
/* SystemVerilog adds support for the increment/decrement
@ -3015,13 +3025,23 @@ expr_primary
}
| implicit_class_handle
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
$$ = 0;
{ PEIdent*tmp = new PEIdent(*$1);
FILE_NAME(tmp,@1);
delete $1;
$$ = tmp;
}
| implicit_class_handle '.' hierarchy_identifier
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
$$ = 0;
{ pform_name_t*nam = $1;
while (! $3->empty()) {
nam->push_back($3->front());
$3->pop_front();
}
PEIdent*tmp = new PEIdent(*nam);
FILE_NAME(tmp,@1);
delete $1;
delete $3;
$$ = tmp;
}
/* Many of the VAMS built-in functions are available as builtin
@ -3821,10 +3841,15 @@ lpvalue
}
| implicit_class_handle '.' hierarchy_identifier
{ yyerror(@1, "sorry: implicit class handles (this/super) not supported.");
PEIdent*tmp = new PEIdent(*$3);
{ pform_name_t*tmp1 = $1;
while (!$3->empty()) {
tmp1->push_back($3->front());
$3->pop_front();
}
PEIdent*tmp = new PEIdent(*tmp1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete tmp1;
delete $3;
}

View File

@ -185,8 +185,8 @@ extern void pform_class_property(const struct vlltype&loc,
property_qualifier_t pq,
data_type_t*data_type,
std::list<decl_assignment_t*>*decls);
extern void pform_set_this_class(PFunction*net);
extern void pform_set_this_class(PTask*net);
extern void pform_set_this_class(PTaskFunc*net);
extern void pform_end_class_declaration(void);
extern void pform_make_udp(perm_string name, list<perm_string>*parms,

View File

@ -908,8 +908,8 @@ void PFunction::dump(ostream&out, unsigned ind) const
}
out << pscope_name() << ";" << endl;
if (this_type_)
out << setw(ind) << "" << "method of " << this_type_->name << ";" << endl;
if (method_of())
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
if (ports_)
for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
@ -949,8 +949,8 @@ void PTask::dump(ostream&out, unsigned ind) const
out << setw(ind) << "" << "task ";
if (is_auto_) cout << "automatic ";
out << pscope_name() << ";" << endl;
if (this_type_)
out << setw(ind) << "" << "method of " << this_type_->name << ";" << endl;
if (method_of())
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
if (ports_)
for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
if ((*ports_)[idx] == 0) {

View File

@ -72,15 +72,7 @@ void pform_class_property(const struct vlltype&loc,
}
}
void pform_set_this_class(PFunction*net)
{
if (pform_cur_class == 0)
return;
net->set_this(pform_cur_class->type);
}
void pform_set_this_class(PTask*net)
void pform_set_this_class(PTaskFunc*net)
{
if (pform_cur_class == 0)
return;