Rework of lexical scope handling in parser.

This patch modifies the parser to use a single stack to track lexical
scopes, rather than starting a new stack for each generate construct.
This commit is contained in:
Martin Whitaker 2010-01-08 22:49:48 +00:00 committed by Stephen Williams
parent 6eb5f593f0
commit b4f070e60b
11 changed files with 77 additions and 124 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,7 +21,7 @@
#include "PTask.h" #include "PTask.h"
PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__) PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0) : PScope(name, parent), ports_(0), statement_(0)
{ {
is_auto_ = is_auto__; is_auto_ = is_auto__;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006,2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2006,2009,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,12 +21,10 @@
# include "PWire.h" # include "PWire.h"
# include "ivl_assert.h" # include "ivl_assert.h"
PGenerate::PGenerate(unsigned id) PGenerate::PGenerate(LexicalScope*parent, unsigned id)
: id_number(id) : LexicalScope(parent), id_number(id)
{ {
direct_nested_ = false; direct_nested_ = false;
parent = 0;
lexical_scope = 0;
} }
PGenerate::~PGenerate() PGenerate::~PGenerate()

View File

@ -1,7 +1,7 @@
#ifndef __PGenerate_H #ifndef __PGenerate_H
#define __PGenerate_H #define __PGenerate_H
/* /*
* Copyright (c) 2006-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 2006-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -53,7 +53,7 @@ class PWire;
class PGenerate : public LineInfo, public LexicalScope { class PGenerate : public LineInfo, public LexicalScope {
public: public:
explicit PGenerate(unsigned id_number); explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate(); ~PGenerate();
// Generate schemes have an ID number, for when the scope is // Generate schemes have an ID number, for when the scope is
@ -63,7 +63,7 @@ class PGenerate : public LineInfo, public LexicalScope {
// This is used during parsing to stack lexical scopes within // This is used during parsing to stack lexical scopes within
// this generate scheme. // this generate scheme.
PScope*lexical_scope; // LexicalScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE, enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK}; GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
@ -92,7 +92,7 @@ class PGenerate : public LineInfo, public LexicalScope {
// Generate schemes can contain further generate schemes. // Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes; list<PGenerate*> generate_schemes;
PGenerate*parent; // PGenerate*parent;
// This method is called by the elaboration of a module to // This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to // generate scopes. the container is the scope that is to

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -19,13 +19,13 @@
# include "PScope.h" # include "PScope.h"
PScope::PScope(perm_string n, PScope*parent) PScope::PScope(perm_string n, LexicalScope*parent)
: name_(n), parent_(parent) : LexicalScope(parent), name_(n)
{ {
} }
PScope::PScope(perm_string n) PScope::PScope(perm_string n)
: name_(n), parent_(0) : LexicalScope(0), name_(n)
{ {
} }

View File

@ -1,7 +1,7 @@
#ifndef __PScope_H #ifndef __PScope_H
#define __PScope_H #define __PScope_H
/* /*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -46,7 +46,7 @@ class NetScope;
class LexicalScope { class LexicalScope {
public: public:
explicit LexicalScope() { } explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
// A virtual destructor is so that dynamic_cast can work. // A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { } virtual ~LexicalScope() { }
@ -94,6 +94,8 @@ class LexicalScope {
list<PProcess*> behaviors; list<PProcess*> behaviors;
list<AProcess*> analog_behaviors; list<AProcess*> analog_behaviors;
LexicalScope* parent_scope() const { return parent_; }
protected: protected:
void dump_parameters_(ostream&out, unsigned indent) const; void dump_parameters_(ostream&out, unsigned indent) const;
@ -104,6 +106,7 @@ class LexicalScope {
void dump_wires_(ostream&out, unsigned indent) const; void dump_wires_(ostream&out, unsigned indent) const;
private: private:
LexicalScope*parent_;
}; };
class PScope : public LexicalScope { class PScope : public LexicalScope {
@ -117,12 +120,11 @@ class PScope : public LexicalScope {
// modules do not nest in Verilog, the parent must be nil for // modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their // modules. Scopes for tasks and functions point to their
// containing module. // containing module.
PScope(perm_string name, PScope*parent); PScope(perm_string name, LexicalScope*parent);
PScope(perm_string name); PScope(perm_string name);
virtual ~PScope(); virtual ~PScope();
perm_string pscope_name() const { return name_; } perm_string pscope_name() const { return name_; }
PScope* pscope_parent() { return parent_; }
protected: protected:
bool elaborate_sig_wires_(Design*des, NetScope*scope) const; bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
@ -131,7 +133,6 @@ class PScope : public LexicalScope {
private: private:
perm_string name_; perm_string name_;
PScope*parent_;
}; };
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,7 +21,7 @@
# include "PTask.h" # include "PTask.h"
PTask::PTask(perm_string name, PScope*parent, bool is_auto__) PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0) : PScope(name, parent), ports_(0), statement_(0)
{ {
is_auto_ = is_auto__; is_auto_ = is_auto__;

View File

@ -1,7 +1,7 @@
#ifndef __PTask_H #ifndef __PTask_H
#define __PTask_H #define __PTask_H
/* /*
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -51,7 +51,7 @@ struct PTaskFuncArg {
class PTask : public PScope, public LineInfo { class PTask : public PScope, public LineInfo {
public: public:
explicit PTask(perm_string name, PScope*parent, bool is_auto); explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
~PTask(); ~PTask();
void set_ports(svector<PWire *>*p); void set_ports(svector<PWire *>*p);
@ -93,7 +93,7 @@ class PTask : public PScope, public LineInfo {
class PFunction : public PScope, public LineInfo { class PFunction : public PScope, public LineInfo {
public: public:
explicit PFunction(perm_string name, PScope*parent, bool is_auto); explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
~PFunction(); ~PFunction();
void set_ports(svector<PWire *>*p); void set_ports(svector<PWire *>*p);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2008,2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -93,7 +93,7 @@ PAssignNB::~PAssignNB()
{ {
} }
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t) PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t) : PScope(n, parent), bl_type_(t)
{ {
} }

View File

@ -159,7 +159,7 @@ class PBlock : public PScope, public Statement {
enum BL_TYPE { BL_SEQ, BL_PAR }; enum BL_TYPE { BL_SEQ, BL_PAR };
// If the block has a name, it is a scope and also has a parent. // If the block has a name, it is a scope and also has a parent.
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t); explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
// If it doesn't have a name, it's not a scope // If it doesn't have a name, it's not a scope
explicit PBlock(BL_TYPE t); explicit PBlock(BL_TYPE t);
~PBlock(); ~PBlock();

142
pform.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -258,29 +258,20 @@ static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno)
* *
* Items that have scoped names are put in the lexical_scope object. * Items that have scoped names are put in the lexical_scope object.
*/ */
static PScope* lexical_scope = 0; static LexicalScope* lexical_scope = 0;
void pform_pop_scope() void pform_pop_scope()
{ {
if (pform_cur_generate) { lexical_scope = lexical_scope->parent_scope();
assert(pform_cur_generate->lexical_scope);
PScope*cur = pform_cur_generate->lexical_scope;
pform_cur_generate->lexical_scope = cur->pscope_parent();
} else {
assert(lexical_scope);
lexical_scope = lexical_scope->pscope_parent();
}
} }
PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
{ {
perm_string task_name = lex_strings.make(name); perm_string task_name = lex_strings.make(name);
PTask*task; PTask*task = new PTask(task_name, lexical_scope, is_auto);
FILE_NAME(task, loc);
if (pform_cur_generate) { if (pform_cur_generate) {
task = new PTask(task_name, pform_cur_generate->lexical_scope,
is_auto);
FILE_NAME(task, loc);
// Check if the task is already in the dictionary. // Check if the task is already in the dictionary.
if (pform_cur_generate->tasks.find(task->pscope_name()) != if (pform_cur_generate->tasks.find(task->pscope_name()) !=
pform_cur_generate->tasks.end()) { pform_cur_generate->tasks.end()) {
@ -291,11 +282,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
error_count += 1; error_count += 1;
} }
pform_cur_generate->tasks[task->pscope_name()] = task; pform_cur_generate->tasks[task->pscope_name()] = task;
pform_cur_generate->lexical_scope = task;
} else { } else {
task = new PTask(task_name, lexical_scope,
is_auto);
FILE_NAME(task, loc);
// Check if the task is already in the dictionary. // Check if the task is already in the dictionary.
if (pform_cur_module->tasks.find(task->pscope_name()) != if (pform_cur_module->tasks.find(task->pscope_name()) !=
pform_cur_module->tasks.end()) { pform_cur_module->tasks.end()) {
@ -305,8 +292,8 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
error_count += 1; error_count += 1;
} }
pform_cur_module->tasks[task->pscope_name()] = task; pform_cur_module->tasks[task->pscope_name()] = task;
lexical_scope = task;
} }
lexical_scope = task;
return task; return task;
} }
@ -316,11 +303,9 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
{ {
perm_string func_name = lex_strings.make(name); perm_string func_name = lex_strings.make(name);
PFunction*func; PFunction*func = new PFunction(func_name, lexical_scope, is_auto);
FILE_NAME(func, loc);
if (pform_cur_generate) { if (pform_cur_generate) {
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
is_auto);
FILE_NAME(func, loc);
// Check if the function is already in the dictionary. // Check if the function is already in the dictionary.
if (pform_cur_generate->funcs.find(func->pscope_name()) != if (pform_cur_generate->funcs.find(func->pscope_name()) !=
pform_cur_generate->funcs.end()) { pform_cur_generate->funcs.end()) {
@ -331,11 +316,7 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
error_count += 1; error_count += 1;
} }
pform_cur_generate->funcs[func->pscope_name()] = func; pform_cur_generate->funcs[func->pscope_name()] = func;
pform_cur_generate->lexical_scope = func;
} else { } else {
func = new PFunction(func_name, lexical_scope,
is_auto);
FILE_NAME(func, loc);
// Check if the function is already in the dictionary. // Check if the function is already in the dictionary.
if (pform_cur_module->funcs.find(func->pscope_name()) != if (pform_cur_module->funcs.find(func->pscope_name()) !=
pform_cur_module->funcs.end()) { pform_cur_module->funcs.end()) {
@ -345,8 +326,8 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
error_count += 1; error_count += 1;
} }
pform_cur_module->funcs[func->pscope_name()] = func; pform_cur_module->funcs[func->pscope_name()] = func;
lexical_scope = func;
} }
lexical_scope = func;
return func; return func;
} }
@ -355,14 +336,8 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
{ {
perm_string block_name = lex_strings.make(name); perm_string block_name = lex_strings.make(name);
PBlock*block; PBlock*block = new PBlock(block_name, lexical_scope, bt);
if (pform_cur_generate) { lexical_scope = block;
block = new PBlock(block_name, pform_cur_generate->lexical_scope, bt);
pform_cur_generate->lexical_scope = block;
} else {
block = new PBlock(block_name, lexical_scope, bt);
lexical_scope = block;
}
return block; return block;
} }
@ -380,29 +355,10 @@ void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
delete attr; delete attr;
} }
static LexicalScope*pform_get_cur_scope()
{
if (pform_cur_generate)
if (pform_cur_generate->lexical_scope)
return pform_cur_generate->lexical_scope;
else
return pform_cur_generate;
else
return lexical_scope;
}
static bool pform_at_module_level() static bool pform_at_module_level()
{ {
if (pform_cur_generate) return (lexical_scope == pform_cur_module)
if (pform_cur_generate->lexical_scope) || (lexical_scope == pform_cur_generate);
return false;
else
return true;
else
if (lexical_scope->pscope_parent())
return false;
else
return true;
} }
PWire*pform_get_wire_in_scope(perm_string name) PWire*pform_get_wire_in_scope(perm_string name)
@ -411,22 +367,22 @@ PWire*pform_get_wire_in_scope(perm_string name)
scope depth will be empty because generate schemes scope depth will be empty because generate schemes
cannot be within sub-scopes. Only directly in cannot be within sub-scopes. Only directly in
modules. */ modules. */
return pform_get_cur_scope()->wires_find(name); return lexical_scope->wires_find(name);
} }
static void pform_put_wire_in_scope(perm_string name, PWire*net) static void pform_put_wire_in_scope(perm_string name, PWire*net)
{ {
pform_get_cur_scope()->wires[name] = net; lexical_scope->wires[name] = net;
} }
static void pform_put_behavior_in_scope(PProcess*pp) static void pform_put_behavior_in_scope(PProcess*pp)
{ {
pform_get_cur_scope()->behaviors.push_back(pp); lexical_scope->behaviors.push_back(pp);
} }
void pform_put_behavior_in_scope(AProcess*pp) void pform_put_behavior_in_scope(AProcess*pp)
{ {
pform_get_cur_scope()->analog_behaviors.push_back(pp); lexical_scope->analog_behaviors.push_back(pp);
} }
void pform_set_default_nettype(NetNet::Type type, void pform_set_default_nettype(NetNet::Type type,
@ -819,7 +775,7 @@ void pform_endmodule(const char*name, bool in_celldefine,
// The current lexical scope should be this module by now, and // The current lexical scope should be this module by now, and
// this module should not have a parent lexical scope. // this module should not have a parent lexical scope.
ivl_assert(*pform_cur_module, lexical_scope == pform_cur_module); ivl_assert(*pform_cur_module, lexical_scope == pform_cur_module);
lexical_scope = pform_cur_module->pscope_parent(); pform_pop_scope();
ivl_assert(*pform_cur_module, lexical_scope == 0); ivl_assert(*pform_cur_module, lexical_scope == 0);
pform_cur_module = 0; pform_cur_module = 0;
@ -864,11 +820,11 @@ void pform_start_generate_for(const struct vlltype&li,
PExpr*test, PExpr*test,
char*ident2, PExpr*next) char*ident2, PExpr*next)
{ {
PGenerate*gen = new PGenerate(scope_generate_counter++); PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_LOOP; pform_cur_generate->scheme_type = PGenerate::GS_LOOP;
@ -884,11 +840,11 @@ void pform_start_generate_for(const struct vlltype&li,
void pform_start_generate_if(const struct vlltype&li, PExpr*test) void pform_start_generate_if(const struct vlltype&li, PExpr*test)
{ {
PGenerate*gen = new PGenerate(scope_generate_counter++); PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_CONDIT; pform_cur_generate->scheme_type = PGenerate::GS_CONDIT;
@ -906,11 +862,11 @@ void pform_start_generate_else(const struct vlltype&li)
PGenerate*cur = pform_cur_generate; PGenerate*cur = pform_cur_generate;
pform_endgenerate(); pform_endgenerate();
PGenerate*gen = new PGenerate(scope_generate_counter++); PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_ELSE; pform_cur_generate->scheme_type = PGenerate::GS_ELSE;
@ -926,11 +882,11 @@ void pform_start_generate_else(const struct vlltype&li)
*/ */
void pform_start_generate_case(const struct vlltype&li, PExpr*expr) void pform_start_generate_case(const struct vlltype&li, PExpr*expr)
{ {
PGenerate*gen = new PGenerate(scope_generate_counter++); PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_CASE; pform_cur_generate->scheme_type = PGenerate::GS_CASE;
@ -945,11 +901,11 @@ void pform_start_generate_case(const struct vlltype&li, PExpr*expr)
*/ */
void pform_start_generate_nblock(const struct vlltype&li, char*name) void pform_start_generate_nblock(const struct vlltype&li, char*name)
{ {
PGenerate*gen = new PGenerate(scope_generate_counter++); PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_NBLOCK; pform_cur_generate->scheme_type = PGenerate::GS_NBLOCK;
@ -973,11 +929,11 @@ void pform_generate_case_item(const struct vlltype&li, svector<PExpr*>*expr_list
assert(pform_cur_generate); assert(pform_cur_generate);
assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE); assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE);
PGenerate*gen = new PGenerate(pform_cur_generate->id_number); PGenerate*gen = new PGenerate(lexical_scope, pform_cur_generate->id_number);
lexical_scope = gen;
FILE_NAME(gen, li); FILE_NAME(gen, li);
gen->parent = pform_cur_generate;
pform_cur_generate = gen; pform_cur_generate = gen;
pform_cur_generate->scheme_type = PGenerate::GS_CASE_ITEM; pform_cur_generate->scheme_type = PGenerate::GS_CASE_ITEM;
@ -1017,17 +973,20 @@ void pform_endgenerate()
pform_cur_generate->scope_name = lex_strings.make(tmp); pform_cur_generate->scope_name = lex_strings.make(tmp);
} }
PGenerate*cur = pform_cur_generate; // The current lexical scope should be this generate construct by now
pform_cur_generate = cur->parent; ivl_assert(*pform_cur_generate, lexical_scope == pform_cur_generate);
pform_pop_scope();
if (pform_cur_generate != 0) { PGenerate*parent_generate = dynamic_cast<PGenerate*>(lexical_scope);
assert(cur->scheme_type == PGenerate::GS_CASE_ITEM if (parent_generate) {
|| pform_cur_generate->scheme_type != PGenerate::GS_CASE); assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM
pform_cur_generate->generate_schemes.push_back(cur); || parent_generate->scheme_type != PGenerate::GS_CASE);
parent_generate->generate_schemes.push_back(pform_cur_generate);
} else { } else {
assert(cur->scheme_type != PGenerate::GS_CASE_ITEM); assert(pform_cur_generate->scheme_type != PGenerate::GS_CASE_ITEM);
pform_cur_module->generate_schemes.push_back(cur); pform_cur_module->generate_schemes.push_back(pform_cur_generate);
} }
pform_cur_generate = parent_generate;
} }
MIN_TYP_MAX min_typ_max_flag = TYP; MIN_TYP_MAX min_typ_max_flag = TYP;
@ -1478,10 +1437,8 @@ void pform_set_net_range(list<perm_string>*names,
*/ */
static void pform_make_event(perm_string name, const char*fn, unsigned ln) static void pform_make_event(perm_string name, const char*fn, unsigned ln)
{ {
LexicalScope*scope = pform_get_cur_scope();
// Check if the named event is already in the dictionary. // Check if the named event is already in the dictionary.
if (scope->events.find(name) != scope->events.end()) { if (lexical_scope->events.find(name) != lexical_scope->events.end()) {
LineInfo tloc; LineInfo tloc;
FILE_NAME(&tloc, fn, ln); FILE_NAME(&tloc, fn, ln);
cerr << tloc.get_fileline() << ": error: duplicate definition " cerr << tloc.get_fileline() << ": error: duplicate definition "
@ -1492,7 +1449,7 @@ static void pform_make_event(perm_string name, const char*fn, unsigned ln)
PEvent*event = new PEvent(name); PEvent*event = new PEvent(name);
FILE_NAME(event, fn, ln); FILE_NAME(event, fn, ln);
scope->events[name] = event; lexical_scope->events[name] = event;
} }
void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln) void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
@ -2149,12 +2106,7 @@ void pform_set_type_attrib(perm_string name, const string&key,
*/ */
void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r) void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r)
{ {
PWire*cur = 0; PWire*cur = lexical_scope->wires_find(name);
if (pform_cur_generate) {
cur = pform_cur_generate->wires_find(name);
} else {
cur = lexical_scope->wires_find(name);
}
if (cur == 0) { if (cur == 0) {
VLerror("internal error: name is not a valid memory for index."); VLerror("internal error: name is not a valid memory for index.");
return; return;
@ -2187,7 +2139,7 @@ void pform_set_parameter(const struct vlltype&loc,
bool signed_flag, svector<PExpr*>*range, PExpr*expr, bool signed_flag, svector<PExpr*>*range, PExpr*expr,
LexicalScope::range_t*value_range) LexicalScope::range_t*value_range)
{ {
LexicalScope*scope = pform_get_cur_scope(); LexicalScope*scope = lexical_scope;
if (scope == pform_cur_generate) { if (scope == pform_cur_generate) {
VLerror("parameter declarations are not permitted in generate blocks"); VLerror("parameter declarations are not permitted in generate blocks");
return; return;
@ -2239,7 +2191,7 @@ void pform_set_localparam(const struct vlltype&loc,
perm_string name, ivl_variable_type_t type, perm_string name, ivl_variable_type_t type,
bool signed_flag, svector<PExpr*>*range, PExpr*expr) bool signed_flag, svector<PExpr*>*range, PExpr*expr)
{ {
LexicalScope*scope = pform_get_cur_scope(); LexicalScope*scope = lexical_scope;
// Check if the localparam name is already in the dictionary. // Check if the localparam name is already in the dictionary.
if (scope->localparams.find(name) != scope->localparams.end()) { if (scope->localparams.find(name) != scope->localparams.end()) {
@ -2260,7 +2212,7 @@ void pform_set_localparam(const struct vlltype&loc,
} }
assert(expr); assert(expr);
Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name]; Module::param_expr_t&parm = scope->localparams[name];
FILE_NAME(&parm, loc); FILE_NAME(&parm, loc);
parm.expr = expr; parm.expr = expr;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -978,6 +978,7 @@ void PGenerate::dump(ostream&out, unsigned indent) const
{ {
out << setw(indent) << "" << "generate(" << id_number << ")"; out << setw(indent) << "" << "generate(" << id_number << ")";
PGenerate*parent = dynamic_cast<PGenerate*>(parent_scope());
switch (scheme_type) { switch (scheme_type) {
case GS_NONE: case GS_NONE:
break; break;
@ -999,6 +1000,7 @@ void PGenerate::dump(ostream&out, unsigned indent) const
out << " case (" << *loop_test << ")"; out << " case (" << *loop_test << ")";
break; break;
case GS_CASE_ITEM: case GS_CASE_ITEM:
assert(parent);
if (loop_test) if (loop_test)
out << " (" << *loop_test << ") == (" << *parent->loop_test << ")"; out << " (" << *loop_test << ") == (" << *parent->loop_test << ")";
else else