Parse more package items
Rework lexical support for PACKAGE_IDENTIFIER so that the lexor can help with package scoped identifiers. Pform package types and package functions up to elaboration.
This commit is contained in:
parent
23dbfabb1e
commit
bae0f1d3a7
20
PExpr.cc
20
PExpr.cc
|
|
@ -174,7 +174,7 @@ PEBShift::~PEBShift()
|
||||||
}
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||||
: path_(n), parms_(parms)
|
: package_(0), path_(n), parms_(parms)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,19 +186,29 @@ static pform_name_t pn_from_ps(perm_string n)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
|
||||||
|
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
|
||||||
|
{
|
||||||
|
int tmp_idx = 0;
|
||||||
|
assert(parms_.size() == parms.size());
|
||||||
|
for (list<PExpr*>::const_iterator idx = parms.begin()
|
||||||
|
; idx != parms.end() ; ++idx)
|
||||||
|
parms_[tmp_idx++] = *idx;
|
||||||
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
||||||
: path_(pn_from_ps(n)), parms_(parms)
|
: package_(0), path_(pn_from_ps(n)), parms_(parms)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(perm_string n)
|
PECallFunction::PECallFunction(perm_string n)
|
||||||
: path_(pn_from_ps(n))
|
: package_(0), path_(pn_from_ps(n))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Anachronism. Try to work all use of svector out.
|
// NOTE: Anachronism. Try to work all use of svector out.
|
||||||
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||||
: path_(n), parms_(parms.size())
|
: package_(0), path_(n), parms_(parms.size())
|
||||||
{
|
{
|
||||||
int tmp_idx = 0;
|
int tmp_idx = 0;
|
||||||
assert(parms_.size() == parms.size());
|
assert(parms_.size() == parms.size());
|
||||||
|
|
@ -208,7 +218,7 @@ PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||||
}
|
}
|
||||||
|
|
||||||
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
||||||
: path_(pn_from_ps(n)), parms_(parms.size())
|
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
|
||||||
{
|
{
|
||||||
int tmp_idx = 0;
|
int tmp_idx = 0;
|
||||||
assert(parms_.size() == parms.size());
|
assert(parms_.size() == parms.size());
|
||||||
|
|
|
||||||
11
PExpr.h
11
PExpr.h
|
|
@ -770,11 +770,15 @@ class PETernary : public PExpr {
|
||||||
class PECallFunction : public PExpr {
|
class PECallFunction : public PExpr {
|
||||||
public:
|
public:
|
||||||
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
|
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
|
||||||
|
// Call function defined in package.
|
||||||
|
explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
|
||||||
|
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
|
||||||
|
|
||||||
// Call of system function (name is not hierarchical)
|
// Call of system function (name is not hierarchical)
|
||||||
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
|
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
|
||||||
explicit PECallFunction(perm_string n);
|
explicit PECallFunction(perm_string n);
|
||||||
|
|
||||||
// svector versions. Should be removed!
|
// std::list versions. Should be removed!
|
||||||
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
|
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
|
||||||
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
|
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
|
||||||
|
|
||||||
|
|
@ -794,14 +798,17 @@ class PECallFunction : public PExpr {
|
||||||
width_mode_t&mode);
|
width_mode_t&mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PPackage*package_;
|
||||||
pform_name_t path_;
|
pform_name_t path_;
|
||||||
vector<PExpr *> parms_;
|
std::vector<PExpr *> parms_;
|
||||||
|
|
||||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||||
|
|
||||||
|
|
||||||
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
|
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
|
||||||
|
|
||||||
|
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
|
||||||
|
unsigned expr_wid, unsigned flags)const;
|
||||||
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
||||||
unsigned expr_wid) const;
|
unsigned expr_wid) const;
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
||||||
16
elab_expr.cc
16
elab_expr.cc
|
|
@ -1775,10 +1775,26 @@ static NetExpr* check_for_class_property(const LineInfo*li,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* PECallFunction::elaborate_expr_pkg_(Design*des, NetScope*scope,
|
||||||
|
unsigned expr_wid,
|
||||||
|
unsigned flags) const
|
||||||
|
{
|
||||||
|
if (debug_elaborate) {
|
||||||
|
cerr << get_fileline() << ": PECallFunction::elaborate_expr_pkg_: "
|
||||||
|
<< "Elaborate " << path_
|
||||||
|
<< " as function in package " << package_->pscope_name()
|
||||||
|
<< "." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
||||||
unsigned expr_wid, unsigned flags) const
|
unsigned expr_wid, unsigned flags) const
|
||||||
{
|
{
|
||||||
|
if (package_)
|
||||||
|
return elaborate_expr_pkg_(des, scope, expr_wid, flags);
|
||||||
|
|
||||||
flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag
|
flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag
|
||||||
|
|
||||||
if (peek_tail_name(path_)[0] == '$')
|
if (peek_tail_name(path_)[0] == '$')
|
||||||
|
|
|
||||||
41
lexor.lex
41
lexor.lex
|
|
@ -91,6 +91,19 @@ static bool in_module = false;
|
||||||
static bool in_UDP = false;
|
static bool in_UDP = false;
|
||||||
bool in_celldefine = false;
|
bool in_celldefine = false;
|
||||||
UCDriveType uc_drive = UCD_NONE;
|
UCDriveType uc_drive = UCD_NONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parser sometimes needs to indicate to the lexor that the next
|
||||||
|
* identifier needs to be understood in the context of a package. The
|
||||||
|
* parser feeds back that left context with calls to the
|
||||||
|
* lex_in_package_scope.
|
||||||
|
*/
|
||||||
|
static PPackage* in_package_scope = 0;
|
||||||
|
void lex_in_package_scope(PPackage*pkg)
|
||||||
|
{
|
||||||
|
in_package_scope = pkg;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%x CCOMMENT
|
%x CCOMMENT
|
||||||
|
|
@ -297,6 +310,24 @@ TU [munpf]
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Special case: If this is part of a scoped name, then check
|
||||||
|
the package for identifier details. For example, if the
|
||||||
|
source file is foo::bar, the parse.y will note the
|
||||||
|
PACKAGE_IDENTIFIER and "::" token and mark the
|
||||||
|
"in_package_scope" variable. Then this lexor will see the
|
||||||
|
identifier here and interpret it in the package scope. */
|
||||||
|
if (in_package_scope) {
|
||||||
|
if (rc == IDENTIFIER) {
|
||||||
|
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
||||||
|
delete[]yylval.text;
|
||||||
|
yylval.data_type = type;
|
||||||
|
rc = TYPE_IDENTIFIER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in_package_scope = 0;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* If this identifier names a discipline, then return this as
|
/* If this identifier names a discipline, then return this as
|
||||||
a DISCIPLINE_IDENTIFIER and return the discipline as the
|
a DISCIPLINE_IDENTIFIER and return the discipline as the
|
||||||
value instead. */
|
value instead. */
|
||||||
|
|
@ -310,6 +341,16 @@ TU [munpf]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If this identifer names a previously declared package, then
|
||||||
|
return this as a PACKAGE_IDENTIFIER instead. */
|
||||||
|
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||||
|
if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
|
||||||
|
delete[]yylval.text;
|
||||||
|
yylval.package = pkg;
|
||||||
|
rc = PACKAGE_IDENTIFIER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If this identifier names a previously declared type, then
|
/* If this identifier names a previously declared type, then
|
||||||
return this as a TYPE_IDENTIFIER instead. */
|
return this as a TYPE_IDENTIFIER instead. */
|
||||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||||
|
|
|
||||||
33
parse.y
33
parse.y
|
|
@ -401,6 +401,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
class_type_t*class_type;
|
class_type_t*class_type;
|
||||||
real_type_t::type_t real_type;
|
real_type_t::type_t real_type;
|
||||||
property_qualifier_t property_qualifier;
|
property_qualifier_t property_qualifier;
|
||||||
|
PPackage*package;
|
||||||
|
|
||||||
verinum* number;
|
verinum* number;
|
||||||
|
|
||||||
|
|
@ -410,8 +411,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
||||||
list<index_component_t> *dimensions;
|
list<index_component_t> *dimensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
|
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
|
||||||
%token <data_type> TYPE_IDENTIFIER
|
%token <data_type> TYPE_IDENTIFIER
|
||||||
|
%token <package> PACKAGE_IDENTIFIER
|
||||||
%token <discipline> DISCIPLINE_IDENTIFIER
|
%token <discipline> DISCIPLINE_IDENTIFIER
|
||||||
%token <text> PATHPULSE_IDENTIFIER
|
%token <text> PATHPULSE_IDENTIFIER
|
||||||
%token <number> BASED_NUMBER DEC_NUMBER UNBASED_NUMBER
|
%token <number> BASED_NUMBER DEC_NUMBER UNBASED_NUMBER
|
||||||
|
|
@ -925,6 +927,12 @@ data_type /* IEEE1800-2005: A.2.2.1 */
|
||||||
{ if ($2) $$ = new parray_type_t($1, $2);
|
{ if ($2) $$ = new parray_type_t($1, $2);
|
||||||
else $$ = $1;
|
else $$ = $1;
|
||||||
}
|
}
|
||||||
|
| PACKAGE_IDENTIFIER K_SCOPE_RES
|
||||||
|
{ lex_in_package_scope($1); }
|
||||||
|
TYPE_IDENTIFIER
|
||||||
|
{ lex_in_package_scope(0);
|
||||||
|
$$ = $4;
|
||||||
|
}
|
||||||
| K_string
|
| K_string
|
||||||
{ string_type_t*tmp = new string_type_t;
|
{ string_type_t*tmp = new string_type_t;
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -1373,14 +1381,12 @@ package_import_declaration /* IEEE1800-2005 A.2.1.3 */
|
||||||
;
|
;
|
||||||
|
|
||||||
package_import_item
|
package_import_item
|
||||||
: IDENTIFIER K_SCOPE_RES IDENTIFIER
|
: PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER
|
||||||
{ pform_package_import(@2, $1, $3);
|
{ pform_package_import(@2, $1, $3);
|
||||||
delete[]$1;
|
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
| IDENTIFIER K_SCOPE_RES '*'
|
| PACKAGE_IDENTIFIER K_SCOPE_RES '*'
|
||||||
{ pform_package_import(@2, $1, 0);
|
{ pform_package_import(@2, $1, 0);
|
||||||
delete[]$1;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -2985,7 +2991,7 @@ expr_primary
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
| IDENTIFIER K_SCOPE_RES IDENTIFIER
|
| PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER
|
||||||
{ $$ = pform_package_ident(@2, $1, $3); }
|
{ $$ = pform_package_ident(@2, $1, $3); }
|
||||||
|
|
||||||
/* An identifier followed by an expression list in parentheses is a
|
/* An identifier followed by an expression list in parentheses is a
|
||||||
|
|
@ -2993,8 +2999,7 @@ expr_primary
|
||||||
call. */
|
call. */
|
||||||
|
|
||||||
| hierarchy_identifier '(' expression_list_proper ')'
|
| hierarchy_identifier '(' expression_list_proper ')'
|
||||||
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
{ PECallFunction*tmp = pform_make_call_function(@1, *$1, *$3);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -3006,15 +3011,21 @@ expr_primary
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| hierarchy_identifier '(' ')'
|
| hierarchy_identifier '(' ')'
|
||||||
{ const vector<PExpr*> empty;
|
{ const list<PExpr*> empty;
|
||||||
PECallFunction*tmp = new PECallFunction(*$1, empty);
|
PECallFunction*tmp = pform_make_call_function(@1, *$1, empty);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
if (!gn_system_verilog()) {
|
if (!gn_system_verilog()) {
|
||||||
yyerror(@1, "error: Empty function argument list requires SystemVerilog.");
|
yyerror(@1, "error: Empty function argument list requires SystemVerilog.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
| PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER '(' expression_list_proper ')'
|
||||||
|
{ perm_string use_name = lex_strings.make($3);
|
||||||
|
PECallFunction*tmp = new PECallFunction($1, use_name, *$5);
|
||||||
|
FILE_NAME(tmp, @3);
|
||||||
|
delete[]$3;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
| SYSTEM_IDENTIFIER '(' ')'
|
| SYSTEM_IDENTIFIER '(' ')'
|
||||||
{ perm_string tn = lex_strings.make($1);
|
{ perm_string tn = lex_strings.make($1);
|
||||||
const vector<PExpr*>empty;
|
const vector<PExpr*>empty;
|
||||||
|
|
|
||||||
16
parse_misc.h
16
parse_misc.h
|
|
@ -78,6 +78,15 @@ extern UCDriveType uc_drive;
|
||||||
extern bool have_timeunit_decl;
|
extern bool have_timeunit_decl;
|
||||||
extern bool have_timeprec_decl;
|
extern bool have_timeprec_decl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The parser signals back to the lexor that the next identifier
|
||||||
|
* should be in the package scope. For example, if the source is
|
||||||
|
* <package> :: <foo>
|
||||||
|
* Then the parser calls this function to set the package context so
|
||||||
|
* that the lexor can interpret <foo> in the package context.
|
||||||
|
*/
|
||||||
|
extern void lex_in_package_scope(PPackage*pkg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test if this identifier is a type identifier in the current
|
* Test if this identifier is a type identifier in the current
|
||||||
* context. The pform code needs to help the lexor here because the
|
* context. The pform code needs to help the lexor here because the
|
||||||
|
|
@ -85,6 +94,13 @@ extern bool have_timeprec_decl;
|
||||||
* type names.
|
* type names.
|
||||||
*/
|
*/
|
||||||
extern data_type_t* pform_test_type_identifier(const char*txt);
|
extern data_type_t* pform_test_type_identifier(const char*txt);
|
||||||
|
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test if this identigier is a package name. The pform needs to help
|
||||||
|
* the lexor here because the parser detects packages and saves them.
|
||||||
|
*/
|
||||||
|
extern PPackage* pform_test_package_identifier(const char*txt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export these functions because we have to generate PENumber class
|
* Export these functions because we have to generate PENumber class
|
||||||
|
|
|
||||||
54
pform.cc
54
pform.cc
|
|
@ -519,18 +519,70 @@ data_type_t* pform_test_type_identifier(const char*txt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
perm_string name = lex_strings.make(txt);
|
perm_string name = lex_strings.make(txt);
|
||||||
map<perm_string,data_type_t*>::iterator cur;
|
|
||||||
LexicalScope*cur_scope = lexical_scope;
|
LexicalScope*cur_scope = lexical_scope;
|
||||||
do {
|
do {
|
||||||
|
map<perm_string,data_type_t*>::iterator cur;
|
||||||
|
|
||||||
|
// First look to see if this identifier is imported from
|
||||||
|
// a package. If it is, see if it is a type in that
|
||||||
|
// package. If it is, then great. If imported as
|
||||||
|
// something other then a type, then give up now becase
|
||||||
|
// the name has at least shadowed any other possible
|
||||||
|
// meaning for this name.
|
||||||
|
map<perm_string,PPackage*>::iterator cur_pkg;
|
||||||
|
cur_pkg = cur_scope->imports.find(name);
|
||||||
|
if (cur_pkg != cur_scope->imports.end()) {
|
||||||
|
PPackage*pkg = cur_pkg->second;
|
||||||
|
cur = pkg->typedefs.find(name);
|
||||||
|
if (cur != pkg->typedefs.end())
|
||||||
|
return cur->second;
|
||||||
|
|
||||||
|
// Not a type. Give up.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cur = cur_scope->typedefs.find(name);
|
cur = cur_scope->typedefs.find(name);
|
||||||
if (cur != cur_scope->typedefs.end())
|
if (cur != cur_scope->typedefs.end())
|
||||||
return cur->second;
|
return cur->second;
|
||||||
|
|
||||||
cur_scope = cur_scope->parent_scope();
|
cur_scope = cur_scope->parent_scope();
|
||||||
} while (cur_scope);
|
} while (cur_scope);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
|
const pform_name_t&name,
|
||||||
|
const list<PExpr*>&parms)
|
||||||
|
{
|
||||||
|
PECallFunction*tmp = 0;
|
||||||
|
|
||||||
|
// First try to get the function name from a package. Check
|
||||||
|
// the imports, and if the name is there, make the function as
|
||||||
|
// a package member.
|
||||||
|
do {
|
||||||
|
if (name.size() != 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
perm_string use_name = peek_tail_name(name);
|
||||||
|
|
||||||
|
map<perm_string,PPackage*>::iterator cur_pkg;
|
||||||
|
cur_pkg = lexical_scope->imports.find(use_name);
|
||||||
|
if (cur_pkg == lexical_scope->imports.end())
|
||||||
|
break;
|
||||||
|
|
||||||
|
tmp = new PECallFunction(cur_pkg->second, use_name, parms);
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if (tmp == 0) {
|
||||||
|
tmp = new PECallFunction(name, parms);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_NAME(tmp, loc);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
static void pform_put_behavior_in_scope(PProcess*pp)
|
static void pform_put_behavior_in_scope(PProcess*pp)
|
||||||
{
|
{
|
||||||
lexical_scope->behaviors.push_back(pp);
|
lexical_scope->behaviors.push_back(pp);
|
||||||
|
|
|
||||||
13
pform.h
13
pform.h
|
|
@ -57,6 +57,7 @@
|
||||||
*/
|
*/
|
||||||
class PGate;
|
class PGate;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
class PPackage;
|
||||||
class PSpecPath;
|
class PSpecPath;
|
||||||
class PClass;
|
class PClass;
|
||||||
class PPackage;
|
class PPackage;
|
||||||
|
|
@ -207,10 +208,10 @@ extern void pform_start_package_declaration(const struct vlltype&loc,
|
||||||
const char*type);
|
const char*type);
|
||||||
extern void pform_end_package_declaration(const struct vlltype&loc);
|
extern void pform_end_package_declaration(const struct vlltype&loc);
|
||||||
extern void pform_package_import(const struct vlltype&loc,
|
extern void pform_package_import(const struct vlltype&loc,
|
||||||
const char*pkg_name, const char*ident);
|
PPackage*pkg, const char*ident);
|
||||||
|
|
||||||
extern PExpr* pform_package_ident(const struct vlltype&loc,
|
extern PExpr* pform_package_ident(const struct vlltype&loc,
|
||||||
const char*pkg_name, const char*ident);
|
PPackage*pkg, const char*ident);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This creates an identifier aware of names that may have been
|
* This creates an identifier aware of names that may have been
|
||||||
|
|
@ -272,6 +273,14 @@ extern PGenerate* pform_parent_generate(void);
|
||||||
|
|
||||||
extern void pform_set_typedef(perm_string name, data_type_t*data_type);
|
extern void pform_set_typedef(perm_string name, data_type_t*data_type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function makes a PECallFunction of the named function. Decide
|
||||||
|
* if this function is in the scope or is imported from a package.
|
||||||
|
*/
|
||||||
|
extern PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
|
const pform_name_t&name,
|
||||||
|
const list<PExpr*>&parms);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The makewire functions announce to the pform code new wires. These
|
* The makewire functions announce to the pform code new wires. These
|
||||||
* go into a module that is currently opened.
|
* go into a module that is currently opened.
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,8 @@ void PEConcat::dump(ostream&out) const
|
||||||
|
|
||||||
void PECallFunction::dump(ostream &out) const
|
void PECallFunction::dump(ostream &out) const
|
||||||
{
|
{
|
||||||
|
if (package_) out << package_->pscope_name() << "::";
|
||||||
|
|
||||||
out << path_ << "(";
|
out << path_ << "(";
|
||||||
|
|
||||||
if (! parms_.empty()) {
|
if (! parms_.empty()) {
|
||||||
|
|
@ -1537,5 +1539,7 @@ void PPackage::pform_dump(std::ostream&out) const
|
||||||
out << "package " << pscope_name() << endl;
|
out << "package " << pscope_name() << endl;
|
||||||
dump_localparams_(out, 4);
|
dump_localparams_(out, 4);
|
||||||
dump_parameters_(out, 4);
|
dump_parameters_(out, 4);
|
||||||
|
dump_tasks_(out, 4);
|
||||||
|
dump_funcs_(out, 4);
|
||||||
out << "endpackage" << endl;
|
out << "endpackage" << endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
101
pform_package.cc
101
pform_package.cc
|
|
@ -71,18 +71,8 @@ void pform_end_package_declaration(const struct vlltype&loc)
|
||||||
* package is declared in pform ahead of time (it is) and that we can
|
* package is declared in pform ahead of time (it is) and that we can
|
||||||
* simply transfer definitions to the current scope (we can).
|
* simply transfer definitions to the current scope (we can).
|
||||||
*/
|
*/
|
||||||
void pform_package_import(const struct vlltype&, const char*pkg_name, const char*ident)
|
void pform_package_import(const struct vlltype&, PPackage*pkg, const char*ident)
|
||||||
{
|
{
|
||||||
perm_string use_name = lex_strings.make(pkg_name);
|
|
||||||
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
|
|
||||||
if (pcur == pform_packages.end()) {
|
|
||||||
ostringstream msg;
|
|
||||||
msg << "Package " << pkg_name << " not found." << ends;
|
|
||||||
VLerror(msg.str().c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PPackage*pkg = pcur->second;
|
|
||||||
LexicalScope*scope = pform_peek_scope();
|
LexicalScope*scope = pform_peek_scope();
|
||||||
|
|
||||||
if (ident) {
|
if (ident) {
|
||||||
|
|
@ -90,15 +80,36 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
|
||||||
|
|
||||||
map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
|
map<perm_string,LexicalScope::param_expr_t>::const_iterator cur
|
||||||
= pkg->parameters.find(use_ident);
|
= pkg->parameters.find(use_ident);
|
||||||
if (cur == pkg->parameters.end()) {
|
if (cur != pkg->parameters.end()) {
|
||||||
ostringstream msg;
|
scope->imports[cur->first] = pkg;
|
||||||
msg << "Symbol " << use_ident
|
|
||||||
<< " not found in package " << pcur->first << "." << ends;
|
|
||||||
VLerror(msg.str().c_str());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
cur = pkg->localparams.find(use_ident);
|
||||||
|
if (cur != pkg->localparams.end()) {
|
||||||
|
scope->imports[cur->first] = pkg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<perm_string,data_type_t*>::const_iterator tcur;
|
||||||
|
tcur = pkg->typedefs.find(use_ident);
|
||||||
|
if (tcur != pkg->typedefs.end()) {
|
||||||
|
scope->imports[tcur->first] = pkg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<perm_string,PFunction*>::const_iterator fcur;
|
||||||
|
fcur = pkg->funcs.find(use_ident);
|
||||||
|
if (fcur != pkg->funcs.end()) {
|
||||||
|
scope->imports[fcur->first] = pkg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ostringstream msg;
|
||||||
|
msg << "Symbol " << use_ident
|
||||||
|
<< " not found in package " << pkg->pscope_name() << "." << ends;
|
||||||
|
VLerror(msg.str().c_str());
|
||||||
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -109,24 +120,56 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
|
||||||
|
|
||||||
scope->imports[cur->first] = pkg;
|
scope->imports[cur->first] = pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->localparams.begin()
|
||||||
|
; cur != pkg->localparams.end() ; ++cur) {
|
||||||
|
|
||||||
|
scope->imports[cur->first] = pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.begin()
|
||||||
|
; cur != pkg->typedefs.end() ; ++cur) {
|
||||||
|
|
||||||
|
scope->imports[cur->first] = pkg;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (map<perm_string,PFunction*>::const_iterator cur = pkg->funcs.begin()
|
||||||
|
; cur != pkg->funcs.end() ; ++cur) {
|
||||||
|
|
||||||
|
scope->imports[cur->first] = pkg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PExpr* pform_package_ident(const struct vlltype&loc,
|
PExpr* pform_package_ident(const struct vlltype&loc,
|
||||||
const char*pkg_name, const char*ident_name)
|
PPackage*pkg, const char*ident_name)
|
||||||
{
|
{
|
||||||
perm_string use_name = lex_strings.make(pkg_name);
|
|
||||||
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
|
|
||||||
if (pcur == pform_packages.end()) {
|
|
||||||
ostringstream msg;
|
|
||||||
msg << "Package " << pkg_name << " not found." << ends;
|
|
||||||
VLerror(msg.str().c_str());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pcur->second);
|
|
||||||
perm_string use_ident = lex_strings.make(ident_name);
|
perm_string use_ident = lex_strings.make(ident_name);
|
||||||
PEIdent*tmp = new PEIdent(pcur->second, use_ident);
|
PEIdent*tmp = new PEIdent(pkg, use_ident);
|
||||||
FILE_NAME(tmp, loc);
|
FILE_NAME(tmp, loc);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt)
|
||||||
|
{
|
||||||
|
perm_string use_name = lex_strings.make(txt);
|
||||||
|
map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.find(use_name);
|
||||||
|
if (cur != pkg->typedefs.end())
|
||||||
|
return cur->second;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The lexor uses this function to know if the
|
||||||
|
*/
|
||||||
|
PPackage* pform_test_package_identifier(const char*pkg_name)
|
||||||
|
{
|
||||||
|
perm_string use_name = lex_strings.make(pkg_name);
|
||||||
|
map<perm_string,PPackage*>::const_iterator pcur = pform_packages.find(use_name);
|
||||||
|
if (pcur == pform_packages.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
assert(pcur->second);
|
||||||
|
return pcur->second;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue