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>
|
||||
|
||||
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);
|
||||
|
|
|
|||
23
PTask.cc
23
PTask.cc
|
|
@ -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
32
PTask.h
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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
57
parse.y
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
pform.h
4
pform.h
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue