summaryrefslogtreecommitdiff
path: root/cli/semantics/elements.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-05 16:29:23 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-05 16:29:23 +0200
commit4974b4763bd60eb875f93a71dbe2fe82ecfed9fc (patch)
tree9353fb3fec3fa5f77f1faaf6da8185e3d006e7ba /cli/semantics/elements.cxx
parente2299f6d95ba3264072d6ddc49f153ad73fd9d24 (diff)
Add semantic graph and traversal mechanism
The parser now builds the semantic graph.
Diffstat (limited to 'cli/semantics/elements.cxx')
-rw-r--r--cli/semantics/elements.cxx117
1 files changed, 117 insertions, 0 deletions
diff --git a/cli/semantics/elements.cxx b/cli/semantics/elements.cxx
new file mode 100644
index 0000000..de9e03a
--- /dev/null
+++ b/cli/semantics/elements.cxx
@@ -0,0 +1,117 @@
+// file : cli/semantics/elements.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <cutl/compiler/type-info.hxx>
+
+#include <semantics/elements.hxx>
+
+namespace semantics
+{
+ // scope
+ //
+
+ scope::names_iterator_pair scope::
+ find (name_type const& name) const
+ {
+ names_map::const_iterator i (names_map_.find (name));
+
+ if (i == names_map_.end ())
+ return names_iterator_pair (names_.end (), names_.end ());
+ else
+ return names_iterator_pair (i->second.begin (), i->second.end ());
+ }
+
+ scope::names_iterator scope::
+ find (names& e)
+ {
+ list_iterator_map::iterator i (iterator_map_.find (&e));
+ return i != iterator_map_.end () ? i->second : names_.end ();
+ }
+
+ void scope::
+ add_edge_left (names& e)
+ {
+ names_list::iterator it (names_.insert (names_.end (), &e));
+ iterator_map_[&e] = it;
+
+ for (names::name_iterator i (e.name_begin ()); i != e.name_end (); ++i)
+ names_map_[*i].push_back (&e);
+ }
+
+ void scope::
+ remove_edge_left (names& e)
+ {
+ list_iterator_map::iterator i (iterator_map_.find (&e));
+ assert (i != iterator_map_.end ());
+
+ names_.erase (i->second);
+ iterator_map_.erase (i);
+
+ for (names::name_iterator ni (e.name_begin ()); ni != e.name_end (); ++ni)
+ {
+ names_map::iterator j (names_map_.find (*ni));
+
+ for (names_list::iterator i (j->second.begin ());
+ i != j->second.end (); ++i)
+ {
+ if (*i == &e)
+ i = j->second.erase (i);
+ }
+ }
+ }
+
+ // type info
+ //
+ namespace
+ {
+ struct init
+ {
+ init ()
+ {
+ using compiler::type_info;
+
+ // node
+ //
+ insert (type_info (typeid (node)));
+
+ // edge
+ //
+ insert (type_info (typeid (edge)));
+
+ // names
+ //
+ {
+ type_info ti (typeid (names));
+ ti.add_base (typeid (edge));
+ insert (ti);
+ }
+
+ // nameable
+ //
+ {
+ type_info ti (typeid (nameable));
+ ti.add_base (typeid (node));
+ insert (ti);
+ }
+
+ // scope
+ //
+ {
+ type_info ti (typeid (scope));
+ ti.add_base (typeid (nameable));
+ insert (ti);
+ }
+
+ // type
+ //
+ {
+ type_info ti (typeid (type));
+ ti.add_base (typeid (node));
+ insert (ti);
+ }
+ }
+ } init_;
+ }
+}