2011-04-14 03:30:00 +02:00
|
|
|
#ifndef __scope_H
|
|
|
|
|
#define __scope_H
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
|
|
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
# include <algorithm>
|
2011-04-14 04:55:18 +02:00
|
|
|
# include <list>
|
2011-04-14 03:30:00 +02:00
|
|
|
# include <map>
|
|
|
|
|
# include "StringHeap.h"
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
# include "entity.h"
|
|
|
|
|
# include "expression.h"
|
|
|
|
|
# include "vsignal.h"
|
2011-04-14 03:30:00 +02:00
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
class Architecture;
|
2011-04-14 03:30:00 +02:00
|
|
|
class ComponentBase;
|
|
|
|
|
class VType;
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
template<typename T>
|
|
|
|
|
struct delete_object{
|
|
|
|
|
void operator()(T* item) { delete item; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct delete_pair_second{
|
|
|
|
|
void operator()(pair<perm_string, T*> item){ delete item.second; }
|
|
|
|
|
};
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
class ScopeBase {
|
2011-04-14 03:30:00 +02:00
|
|
|
|
|
|
|
|
public:
|
2011-04-18 02:19:09 +02:00
|
|
|
ScopeBase() { }
|
|
|
|
|
explicit ScopeBase(const ScopeBase&ref);
|
|
|
|
|
virtual ~ScopeBase() =0;
|
|
|
|
|
|
|
|
|
|
const VType* find_type(perm_string by_name);
|
|
|
|
|
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp);
|
|
|
|
|
protected:
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
void cleanup();
|
|
|
|
|
|
2011-07-21 11:04:48 +02:00
|
|
|
//containers' cleaning helper functions
|
|
|
|
|
template<typename T> void delete_all(list<T*>& c)
|
|
|
|
|
{
|
|
|
|
|
for_each(c.begin(), c.end(), ::delete_object<T>());
|
|
|
|
|
}
|
|
|
|
|
template<typename T> void delete_all(map<perm_string, T*>& c)
|
|
|
|
|
{
|
|
|
|
|
for_each(c.begin(), c.end(), ::delete_pair_second<T>());
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
// Signal declarations...
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
std::map<perm_string,Signal*> old_signals_; //previous scopes
|
|
|
|
|
std::map<perm_string,Signal*> new_signals_; //current scope
|
2011-04-26 23:18:30 +02:00
|
|
|
// Component declarations...
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
std::map<perm_string,ComponentBase*> old_components_; //previous scopes
|
|
|
|
|
std::map<perm_string,ComponentBase*> new_components_; //current scope
|
2011-04-18 02:19:09 +02:00
|
|
|
// Type declarations...
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
std::map<perm_string,const VType*> old_types_; //previous scopes
|
|
|
|
|
std::map<perm_string,const VType*> new_types_; //current scope
|
2011-04-18 02:19:09 +02:00
|
|
|
// Constant declarations...
|
|
|
|
|
struct const_t {
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
~const_t() {delete typ; delete val;}
|
|
|
|
|
const_t(const VType*t, Expression* v) : typ(t), val(v) {};
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
const VType*typ;
|
|
|
|
|
Expression*val;
|
|
|
|
|
};
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
std::map<perm_string, struct const_t*> old_constants_; //previous scopes
|
|
|
|
|
std::map<perm_string, struct const_t*> new_constants_; //current scope
|
2011-04-18 02:19:09 +02:00
|
|
|
|
|
|
|
|
void do_use_from(const ScopeBase*that);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Scope : public ScopeBase {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Scope(const ScopeBase&ref);
|
2011-04-14 03:30:00 +02:00
|
|
|
~Scope();
|
|
|
|
|
|
|
|
|
|
ComponentBase* find_component(perm_string by_name);
|
|
|
|
|
|
2011-05-16 01:17:51 +02:00
|
|
|
Signal* find_signal(perm_string by_name);
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
public:
|
2011-04-14 03:30:00 +02:00
|
|
|
void dump_scope(ostream&out) const;
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
protected:
|
|
|
|
|
// Helper method for emitting signals in the scope.
|
|
|
|
|
int emit_signals(ostream&out, Entity*ent, Architecture*arc);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The active_scope object accumulates declarations for the scope that
|
|
|
|
|
* is in the process of being parsed. When the declarations are over,
|
|
|
|
|
* they are transferred over to the specific scope. The ActiveScope is
|
|
|
|
|
* used by the parser to build up scopes.
|
|
|
|
|
*/
|
|
|
|
|
class ActiveScope : public ScopeBase {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ActiveScope() { }
|
|
|
|
|
ActiveScope(ActiveScope*par) : ScopeBase(*par) { }
|
2011-04-26 23:18:30 +02:00
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
~ActiveScope() { }
|
|
|
|
|
|
|
|
|
|
void use_from(const ScopeBase*that) { do_use_from(that); }
|
|
|
|
|
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
|
|
|
|
|
/* All bind_name function check if the given name was present
|
|
|
|
|
* in previous scopes. If it is found, it is erased (but the pointer
|
|
|
|
|
* is not freed), in order to implement name shadowing. The pointer
|
|
|
|
|
* be freed only in the scope where the object was defined. This is
|
|
|
|
|
* done in ScopeBase::cleanup() function .*/
|
|
|
|
|
|
2011-04-18 02:19:09 +02:00
|
|
|
void bind_name(perm_string name, Signal*obj)
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
{ map<perm_string, Signal*>::iterator it;
|
|
|
|
|
if((it = old_signals_.find(name)) != old_signals_.end() )
|
|
|
|
|
old_signals_.erase(it);
|
|
|
|
|
new_signals_[name] = obj;
|
|
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
|
|
|
|
void bind_name(perm_string name, ComponentBase*obj)
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
{ map<perm_string, ComponentBase*>::iterator it;
|
|
|
|
|
if((it = old_components_.find(name)) != old_components_.end() )
|
|
|
|
|
old_components_.erase(it);
|
|
|
|
|
new_components_[name] = obj;
|
|
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
void bind_name(perm_string name, const VType* t)
|
|
|
|
|
{ map<perm_string, const VType*>::iterator it;
|
|
|
|
|
if((it = old_types_.find(name)) != old_types_.end() )
|
|
|
|
|
old_types_.erase(it);
|
|
|
|
|
new_types_[name] = t;
|
|
|
|
|
}
|
2011-04-18 02:19:09 +02:00
|
|
|
|
|
|
|
|
void bind_name(perm_string name, const VType*obj, Expression*val)
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
{ map<perm_string, const_t*>::iterator it;
|
|
|
|
|
if((it = old_constants_.find(name)) != old_constants_.end() )
|
|
|
|
|
old_constants_.erase(it);
|
|
|
|
|
new_constants_[name] = new const_t(obj, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void destroy_global_scope()
|
2011-04-18 02:19:09 +02:00
|
|
|
{
|
Use separate containers for current and previous scopes
This patch introduces in ScopeBase separate containers
for declarations coming from the current scope and from
the previous scopes.
Until now, in one scope, all objects were kept in an stl map.
When a scope was created inside other scopes, a shallow
copy of the map was made. This solution was nice for
name shadowing (in new scopes, when a name was
encountered, the old objects were overridden by a new
one), but didn't allow for distinguishing where the objects
were allocated. As a result, it is impossible to know who
the owner is and who should delete them.
In this commit ScopeBase gets two containers: for old
and new objects. If a ScopeBase is made from another
ScopeBase object, all objects from the copied object
go to an old_XXX container, where XXX depends on the
type of the copied objects. When a ScopeBase object
is deleted, the objects from new_XXX are deleted and
the ones from old_XXX are not touched.
This patch adds some complexity to the internals
of ScopeBase, but leaves its interface unchanged.
2011-07-20 16:34:36 +02:00
|
|
|
cleanup();
|
2011-04-18 02:19:09 +02:00
|
|
|
}
|
2011-04-14 03:30:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|