Handle this as special identifier strings. / Organize pform class member binding
This commit is contained in:
parent
670601bc2a
commit
fac5cbca43
|
|
@ -22,7 +22,7 @@
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
||||||
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
|
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__;
|
is_auto_ = is_auto__;
|
||||||
return_type_.type = PTF_NONE;
|
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)
|
void PFunction::set_ports(vector<PWire *>*p)
|
||||||
{
|
{
|
||||||
assert(ports_ == 0);
|
assert(ports_ == 0);
|
||||||
|
|
|
||||||
23
PTask.cc
23
PTask.cc
|
|
@ -21,8 +21,23 @@
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
# include <cassert>
|
# 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__)
|
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__;
|
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)
|
void PTask::set_ports(vector<PWire*>*p)
|
||||||
{
|
{
|
||||||
assert(ports_ == 0);
|
assert(ports_ == 0);
|
||||||
|
|
|
||||||
32
PTask.h
32
PTask.h
|
|
@ -50,16 +50,31 @@ struct PTaskFuncArg {
|
||||||
std::list<pform_range_t>*range;
|
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.
|
* The PTask holds the parsed definitions of a task.
|
||||||
*/
|
*/
|
||||||
class PTask : public PScope, public LineInfo {
|
class PTask : public PTaskFunc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
||||||
~PTask();
|
~PTask();
|
||||||
|
|
||||||
void set_this(class_type_t*use_type);
|
|
||||||
void set_ports(std::vector<PWire *>*p);
|
void set_ports(std::vector<PWire *>*p);
|
||||||
void set_statement(Statement *s);
|
void set_statement(Statement *s);
|
||||||
|
|
||||||
|
|
@ -77,14 +92,9 @@ class PTask : public PScope, public LineInfo {
|
||||||
|
|
||||||
bool is_auto() const { return is_auto_; };
|
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;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class_type_t*this_type_;
|
|
||||||
std::vector<PWire*>*ports_;
|
std::vector<PWire*>*ports_;
|
||||||
Statement*statement_;
|
Statement*statement_;
|
||||||
bool is_auto_;
|
bool is_auto_;
|
||||||
|
|
@ -101,13 +111,12 @@ class PTask : public PScope, public LineInfo {
|
||||||
*
|
*
|
||||||
* The output value is not elaborated until elaborate_sig.
|
* The output value is not elaborated until elaborate_sig.
|
||||||
*/
|
*/
|
||||||
class PFunction : public PScope, public LineInfo {
|
class PFunction : public PTaskFunc {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
||||||
~PFunction();
|
~PFunction();
|
||||||
|
|
||||||
void set_this(class_type_t*use_type);
|
|
||||||
void set_ports(std::vector<PWire *>*p);
|
void set_ports(std::vector<PWire *>*p);
|
||||||
void set_statement(Statement *s);
|
void set_statement(Statement *s);
|
||||||
void set_return(PTaskFuncArg t);
|
void set_return(PTaskFuncArg t);
|
||||||
|
|
@ -122,14 +131,9 @@ class PFunction : public PScope, public LineInfo {
|
||||||
|
|
||||||
bool is_auto() const { return is_auto_; };
|
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;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class_type_t*this_type_;
|
|
||||||
PTaskFuncArg return_type_;
|
PTaskFuncArg return_type_;
|
||||||
std::vector<PWire *> *ports_;
|
std::vector<PWire *> *ports_;
|
||||||
Statement *statement_;
|
Statement *statement_;
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,18 @@ static void elaborate_scope_class(Design*des, NetScope*scope,
|
||||||
use_class->set_property(cur->first, tmp);
|
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);
|
scope->add_class(use_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
57
parse.y
57
parse.y
|
|
@ -60,6 +60,19 @@ static PTask* current_task = 0;
|
||||||
static PFunction* current_function = 0;
|
static PFunction* current_function = 0;
|
||||||
static stack<PBlock*> current_block_stack;
|
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
|
/* 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
|
* in the $setuphold and $recrem timing checks. This allows us to print
|
||||||
* a warning message that the delayed signals will not be created. We
|
* 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 <gate> gate_instance
|
||||||
%type <gates> gate_instance_list
|
%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> 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> branch_probe_expression streaming_concatenation
|
||||||
%type <expr> delay_value delay_value_simple
|
%type <expr> delay_value delay_value_simple
|
||||||
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
%type <exprs> delay1 delay3 delay3_opt delay_value_list
|
||||||
|
|
@ -771,14 +785,10 @@ class_item /* IEEE1800-2005: A.1.8 */
|
||||||
/* Class methods... */
|
/* Class methods... */
|
||||||
|
|
||||||
| method_qualifier_opt task_declaration
|
| method_qualifier_opt task_declaration
|
||||||
{ yyerror(@2, "sorry: Class methods (tasks) not supported yet.");
|
{ /* The task_declaration rule puts this into the class */ }
|
||||||
yyerrok;
|
|
||||||
}
|
|
||||||
|
|
||||||
| method_qualifier_opt function_declaration
|
| method_qualifier_opt function_declaration
|
||||||
{ yyerror(@2, "sorry: Class methods (functions) not supported yet.");
|
{ /* The function_declaration rule puts this into the class */ }
|
||||||
yyerrok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Class constraints... */
|
/* Class constraints... */
|
||||||
|
|
@ -1095,8 +1105,8 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
;
|
;
|
||||||
|
|
||||||
implicit_class_handle /* IEEE1800-2005: A.8.4 */
|
implicit_class_handle /* IEEE1800-2005: A.8.4 */
|
||||||
: K_this
|
: K_this { $$ = pform_create_this(); }
|
||||||
| K_super
|
| K_super { $$ = pform_create_super(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* SystemVerilog adds support for the increment/decrement
|
/* SystemVerilog adds support for the increment/decrement
|
||||||
|
|
@ -3015,13 +3025,23 @@ expr_primary
|
||||||
}
|
}
|
||||||
|
|
||||||
| implicit_class_handle
|
| implicit_class_handle
|
||||||
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
$$ = 0;
|
FILE_NAME(tmp,@1);
|
||||||
|
delete $1;
|
||||||
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| implicit_class_handle '.' hierarchy_identifier
|
| implicit_class_handle '.' hierarchy_identifier
|
||||||
{ yyerror(@1, "sorry: Implicit class handles (this/super) are not supported.");
|
{ pform_name_t*nam = $1;
|
||||||
$$ = 0;
|
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
|
/* Many of the VAMS built-in functions are available as builtin
|
||||||
|
|
@ -3821,10 +3841,15 @@ lpvalue
|
||||||
}
|
}
|
||||||
|
|
||||||
| implicit_class_handle '.' hierarchy_identifier
|
| implicit_class_handle '.' hierarchy_identifier
|
||||||
{ yyerror(@1, "sorry: implicit class handles (this/super) not supported.");
|
{ pform_name_t*tmp1 = $1;
|
||||||
PEIdent*tmp = new PEIdent(*$3);
|
while (!$3->empty()) {
|
||||||
|
tmp1->push_back($3->front());
|
||||||
|
$3->pop_front();
|
||||||
|
}
|
||||||
|
PEIdent*tmp = new PEIdent(*tmp1);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
delete tmp1;
|
||||||
delete $3;
|
delete $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
pform.h
4
pform.h
|
|
@ -185,8 +185,8 @@ extern void pform_class_property(const struct vlltype&loc,
|
||||||
property_qualifier_t pq,
|
property_qualifier_t pq,
|
||||||
data_type_t*data_type,
|
data_type_t*data_type,
|
||||||
std::list<decl_assignment_t*>*decls);
|
std::list<decl_assignment_t*>*decls);
|
||||||
extern void pform_set_this_class(PFunction*net);
|
extern void pform_set_this_class(PTaskFunc*net);
|
||||||
extern void pform_set_this_class(PTask*net);
|
|
||||||
extern void pform_end_class_declaration(void);
|
extern void pform_end_class_declaration(void);
|
||||||
|
|
||||||
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
|
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
|
||||||
|
|
|
||||||
|
|
@ -908,8 +908,8 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
||||||
}
|
}
|
||||||
|
|
||||||
out << pscope_name() << ";" << endl;
|
out << pscope_name() << ";" << endl;
|
||||||
if (this_type_)
|
if (method_of())
|
||||||
out << setw(ind) << "" << "method of " << this_type_->name << ";" << endl;
|
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
|
||||||
|
|
||||||
if (ports_)
|
if (ports_)
|
||||||
for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
|
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 ";
|
out << setw(ind) << "" << "task ";
|
||||||
if (is_auto_) cout << "automatic ";
|
if (is_auto_) cout << "automatic ";
|
||||||
out << pscope_name() << ";" << endl;
|
out << pscope_name() << ";" << endl;
|
||||||
if (this_type_)
|
if (method_of())
|
||||||
out << setw(ind) << "" << "method of " << this_type_->name << ";" << endl;
|
out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl;
|
||||||
if (ports_)
|
if (ports_)
|
||||||
for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) {
|
||||||
if ((*ports_)[idx] == 0) {
|
if ((*ports_)[idx] == 0) {
|
||||||
|
|
|
||||||
|
|
@ -72,15 +72,7 @@ void pform_class_property(const struct vlltype&loc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_this_class(PFunction*net)
|
void pform_set_this_class(PTaskFunc*net)
|
||||||
{
|
|
||||||
if (pform_cur_class == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
net->set_this(pform_cur_class->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pform_set_this_class(PTask*net)
|
|
||||||
{
|
{
|
||||||
if (pform_cur_class == 0)
|
if (pform_cur_class == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue