aboutsummaryrefslogtreecommitdiff
path: root/cutl/compiler
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-06 12:52:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-06 12:52:53 +0200
commitcb9ea47e7825b5073d4d645afb94f6326cb7cf4d (patch)
tree201c215b08df918924153a60520046c294438a6b /cutl/compiler
Start the libcutl repository
Diffstat (limited to 'cutl/compiler')
-rw-r--r--cutl/compiler/context.cxx23
-rw-r--r--cutl/compiler/context.hxx70
-rw-r--r--cutl/compiler/context.txx85
-rw-r--r--cutl/compiler/traversal.hxx155
-rw-r--r--cutl/compiler/traversal.txx145
-rw-r--r--cutl/compiler/type-id.hxx47
-rw-r--r--cutl/compiler/type-id.ixx45
-rw-r--r--cutl/compiler/type-id.txx18
-rw-r--r--cutl/compiler/type-info.cxx31
-rw-r--r--cutl/compiler/type-info.hxx109
-rw-r--r--cutl/compiler/type-info.ixx96
11 files changed, 824 insertions, 0 deletions
diff --git a/cutl/compiler/context.cxx b/cutl/compiler/context.cxx
new file mode 100644
index 0000000..da31d6e
--- /dev/null
+++ b/cutl/compiler/context.cxx
@@ -0,0 +1,23 @@
+// file : cutl/compiler/context.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <cutl/compiler/context.hxx>
+
+namespace cutl
+{
+ namespace compiler
+ {
+ void context::
+ remove (char const* key)
+ {
+ map::iterator i (map_.find (key));
+
+ if (i == map_.end ())
+ throw no_entry ();
+
+ map_.erase (i);
+ }
+ }
+}
diff --git a/cutl/compiler/context.hxx b/cutl/compiler/context.hxx
new file mode 100644
index 0000000..4bae010
--- /dev/null
+++ b/cutl/compiler/context.hxx
@@ -0,0 +1,70 @@
+// file : cutl/compiler/context.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CUTL_COMPILER_CONTEXT_HXX
+#define CUTL_COMPILER_CONTEXT_HXX
+
+#include <map>
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <cutl/container/any.hxx>
+
+namespace cutl
+{
+ namespace compiler
+ {
+ class context
+ {
+ public:
+ struct no_entry {};
+ struct typing {};
+
+ public:
+ context () {}
+
+ private:
+ context (context const&);
+
+ context&
+ operator= (context const&);
+
+ public:
+ std::size_t
+ count (char const* key) const
+ {
+ return map_.count (key);
+ }
+
+ template <typename X>
+ X&
+ get (char const* key);
+
+ template <typename X>
+ X const&
+ get (char const* key) const;
+
+ template <typename X>
+ X const&
+ get (char const* key, X const& default_value) const;
+
+ template <typename X>
+ void
+ set (char const* key, X const& value);
+
+ void
+ remove (char const* key);
+
+ private:
+ typedef std::map<std::string, container::any> map;
+
+ map map_;
+ };
+ }
+}
+
+#include <cutl/compiler/context.txx>
+
+#endif // CUTL_COMPILER_CONTEXT_HXX
diff --git a/cutl/compiler/context.txx b/cutl/compiler/context.txx
new file mode 100644
index 0000000..55a24f7
--- /dev/null
+++ b/cutl/compiler/context.txx
@@ -0,0 +1,85 @@
+// file : cutl/compiler/context.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace compiler
+ {
+ template <typename X>
+ X& context::
+ get (char const* key)
+ {
+ map::iterator i (map_.find (key));
+
+ if (i == map_.end ())
+ throw no_entry ();
+
+ try
+ {
+ return i->second.value<X> ();
+ }
+ catch (container::any::typing const&)
+ {
+ throw typing ();
+ }
+ }
+
+ template <typename X>
+ X const& context::
+ get (char const* key) const
+ {
+ map::const_iterator i (map_.find (key));
+
+ if (i == map_.end ())
+ throw no_entry ();
+
+ try
+ {
+ return i->second.value<X> ();
+ }
+ catch (container::any::typing const&)
+ {
+ throw typing ();
+ }
+ }
+
+ template <typename X>
+ X const& context::
+ get (char const* key, X const& default_value) const
+ {
+ map::const_iterator i (map_.find (key));
+
+ if (i == map_.end ())
+ return default_value;
+
+ try
+ {
+ return i->second.value<X> ();
+ }
+ catch (container::any::typing const&)
+ {
+ throw typing ();
+ }
+ }
+
+ template <typename X>
+ void context::
+ set (char const* key, X const& value)
+ {
+ try
+ {
+ std::pair<map::iterator, bool> r (
+ map_.insert (map::value_type (key, value)));
+
+ if (!r.second)
+ r.first->second.value<X> () = value;
+ }
+ catch (container::any::typing const&)
+ {
+ throw typing ();
+ }
+ }
+ }
+}
diff --git a/cutl/compiler/traversal.hxx b/cutl/compiler/traversal.hxx
new file mode 100644
index 0000000..ad677b0
--- /dev/null
+++ b/cutl/compiler/traversal.hxx
@@ -0,0 +1,155 @@
+// file : cutl/compiler/traversal.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CUTL_COMPILER_TRAVERSAL_HXX
+#define CUTL_COMPILER_TRAVERSAL_HXX
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include <cutl/compiler/type-info.hxx>
+
+namespace cutl
+{
+ namespace compiler
+ {
+ //
+ //
+ template<typename B>
+ class traverser
+ {
+ public:
+ virtual
+ ~traverser ();
+
+ virtual void
+ trampoline (B&) = 0;
+ };
+
+ //
+ //
+ template<typename B>
+ class traverser_map
+ {
+ public:
+ typedef std::vector<traverser<B>*> traversers;
+ typedef std::map<type_id, traversers> map_type;
+ typedef typename map_type::const_iterator iterator;
+
+ iterator
+ begin () const
+ {
+ return map_.begin ();
+ }
+
+ iterator
+ end () const
+ {
+ return map_.end ();
+ }
+
+ void
+ add (type_id const& id, traverser<B>& t)
+ {
+ traversers& travs (map_[id]);
+ travs.push_back (&t);
+ }
+
+ protected:
+ map_type map_;
+ };
+
+ //
+ //
+ template <typename X, typename B>
+ class traverser_impl: public traverser<B>,
+ public virtual traverser_map<B>
+ {
+ public:
+ typedef X type;
+
+ traverser_impl ()
+ {
+ add (typeid (type), *this);
+ }
+
+ virtual void
+ traverse (type&) = 0;
+
+ public:
+ virtual void
+ trampoline (B&);
+ };
+
+ //
+ //
+ template <typename B>
+ class dispatcher: public virtual traverser_map<B>
+ {
+ public:
+ virtual
+ ~dispatcher ();
+
+ void
+ traverser (traverser_map<B>&);
+
+ virtual void
+ dispatch (B&);
+
+ public:
+ template <typename I, typename X>
+ static void
+ iterate_and_dispatch (I begin, I end, dispatcher<X>& d)
+ {
+ for (; begin != end; ++begin)
+ {
+ d.dispatch (*begin);
+ }
+ }
+
+ template <typename T, typename A, typename I, typename X>
+ static void
+ iterate_and_dispatch (I begin,
+ I end,
+ dispatcher<X>& d,
+ T& t,
+ void (T::*next)(A&),
+ A& a)
+ {
+ for (; begin != end;)
+ {
+ d.dispatch (*begin);
+
+ if (++begin != end && next != 0)
+ (t.*next) (a);
+ }
+ }
+
+ private:
+ struct comparator
+ {
+ bool
+ operator () (type_info const& a, type_info const& b) const
+ {
+ return a.type_id () < b.type_id ();
+ }
+ };
+
+ typedef std::map<type_info, std::size_t, comparator> level_map;
+ typedef std::set<type_info, comparator> type_info_set;
+
+ static std::size_t
+ compute_levels (type_info const&, std::size_t current, level_map&);
+
+ static void
+ flatten_tree (type_info const&, type_info_set&);
+ };
+ }
+}
+
+#include <cutl/compiler/traversal.txx>
+
+#endif // CUTL_COMPILER_TRAVERSAL_HXX
diff --git a/cutl/compiler/traversal.txx b/cutl/compiler/traversal.txx
new file mode 100644
index 0000000..315d11b
--- /dev/null
+++ b/cutl/compiler/traversal.txx
@@ -0,0 +1,145 @@
+// file : cutl/compiler/traversal.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace compiler
+ {
+ // traverser
+ //
+ template<typename B>
+ traverser<B>::
+ ~traverser ()
+ {
+ }
+
+ // traverser_impl
+ //
+
+ template <typename X, typename B>
+ void traverser_impl<X, B>::
+ trampoline (B& x)
+ {
+ this->traverse (dynamic_cast<type&> (x));
+ }
+
+ // dispatcher
+ //
+
+ template <typename B>
+ dispatcher<B>::
+ ~dispatcher ()
+ {
+ }
+
+ template <typename B>
+ void dispatcher<B>::
+ traverser (traverser_map<B>& m)
+ {
+ // Copy entries from m to our map.
+ //
+ for (typename traverser_map<B>::iterator
+ i (m.begin ()), e (m.end ()); i != e; ++i)
+ {
+ typename traverser_map<B>::traversers& travs (this->map_[i->first]);
+
+ for (typename traverser_map<B>::traversers::const_iterator
+ t (i->second.begin ()), e (i->second.end ()); t != e; ++t)
+ {
+ travs.push_back (*t);
+ }
+ }
+ }
+
+ template <typename B>
+ void dispatcher<B>::
+ dispatch (B& x)
+ {
+ using std::size_t;
+
+ level_map levels;
+ type_info const& ti (lookup (x));
+ size_t max (compute_levels (ti, 0, levels));
+
+ // cerr << "starting dispatch process for " << ti.type_id ().name ()
+ // << " with " << max << " levels" << endl;
+
+ for (size_t l (0); l < max + 1; ++l)
+ {
+ type_info_set dispatched;
+
+ for (typename level_map::const_iterator
+ i (levels.begin ()), e (levels.end ()); i != e; ++i)
+ {
+ if (i->second == l)
+ {
+ typename traverser_map<B>::map_type::const_iterator v (
+ this->map_.find (i->first.type_id ()));
+
+ if (v != this->map_.end ())
+ {
+ // cerr << "dispatching traversers for " << ti.type_id ().name ()
+ // << " as " << i->first.type_id ().name () << endl;
+
+ typename traverser_map<B>::traversers const& travs (v->second);
+
+ for (typename traverser_map<B>::traversers::const_iterator
+ ti (travs.begin ()), te (travs.end ()); ti != te; ++ti)
+ {
+ (*ti)->trampoline (x);
+ }
+
+ flatten_tree (i->first, dispatched);
+ }
+ }
+ }
+
+ // Remove traversed types from the level map.
+ //
+ for (typename type_info_set::const_iterator i (dispatched.begin ());
+ i != dispatched.end (); ++i)
+ {
+ levels.erase (*i);
+ }
+ }
+ }
+
+ template <typename B>
+ std::size_t dispatcher<B>::
+ compute_levels (type_info const& ti, std::size_t cur, level_map& map)
+ {
+ using std::size_t;
+
+ size_t ret (cur);
+
+ if (map.find (ti) == map.end () || map[ti] < cur)
+ map[ti] = cur;
+
+ for (type_info::base_iterator i (ti.begin_base ());
+ i != ti.end_base (); ++i)
+ {
+ size_t tmp (compute_levels (i->type_info (), cur + 1, map));
+
+ if (tmp > ret)
+ ret = tmp;
+ }
+
+ return ret;
+ }
+
+ template <typename B>
+ void dispatcher<B>::
+ flatten_tree (type_info const& ti, type_info_set& set)
+ {
+ set.insert (ti);
+
+ for (type_info::base_iterator i (ti.begin_base ());
+ i != ti.end_base (); ++i)
+ {
+ flatten_tree (i->type_info (), set);
+ }
+ }
+ }
+}
diff --git a/cutl/compiler/type-id.hxx b/cutl/compiler/type-id.hxx
new file mode 100644
index 0000000..7731f6d
--- /dev/null
+++ b/cutl/compiler/type-id.hxx
@@ -0,0 +1,47 @@
+// file : cutl/compiler/type-id.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CUTL_COMPILER_TYPE_ID_HXX
+#define CUTL_COMPILER_TYPE_ID_HXX
+
+#include <typeinfo> // std::type_info
+
+namespace cutl
+{
+ namespace compiler
+ {
+ class type_id
+ {
+ public:
+ template<typename X>
+ type_id (X const volatile&);
+
+ type_id (std::type_info const&);
+
+ public:
+ char const*
+ name () const;
+
+ friend bool
+ operator== (type_id const&, type_id const&);
+
+ friend bool
+ operator!= (type_id const&, type_id const&);
+
+ friend bool
+ operator< (type_id const&, type_id const&);
+
+ private:
+ std::type_info const* ti_;
+ };
+
+ typedef type_id type_id_t;
+ }
+}
+
+#include <cutl/compiler/type-id.ixx>
+#include <cutl/compiler/type-id.txx>
+
+#endif // CUTL_COMPILER_TYPE_ID_HXX
diff --git a/cutl/compiler/type-id.ixx b/cutl/compiler/type-id.ixx
new file mode 100644
index 0000000..4092d6d
--- /dev/null
+++ b/cutl/compiler/type-id.ixx
@@ -0,0 +1,45 @@
+// file : cutl/compiler/type-id.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace compiler
+ {
+ inline
+ type_id::
+ type_id (std::type_info const& ti)
+ : ti_ (&ti)
+ {
+ }
+
+ inline
+ char const* type_id::
+ name () const
+ {
+ return ti_->name ();
+ }
+
+ inline
+ bool
+ operator== (type_id const& x, type_id const& y)
+ {
+ return *x.ti_ == *y.ti_;
+ }
+
+ inline
+ bool
+ operator!= (type_id const& x, type_id const& y)
+ {
+ return *x.ti_ != *y.ti_;
+ }
+
+ inline
+ bool
+ operator< (type_id const& x, type_id const& y)
+ {
+ return x.ti_->before (*y.ti_);
+ }
+ }
+}
diff --git a/cutl/compiler/type-id.txx b/cutl/compiler/type-id.txx
new file mode 100644
index 0000000..9fee905
--- /dev/null
+++ b/cutl/compiler/type-id.txx
@@ -0,0 +1,18 @@
+// file : cutl/compiler/type-id.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace compiler
+ {
+ template <typename X>
+ inline
+ type_id::
+ type_id (X const volatile& x)
+ : ti_ (&typeid (x))
+ {
+ }
+ }
+}
diff --git a/cutl/compiler/type-info.cxx b/cutl/compiler/type-info.cxx
new file mode 100644
index 0000000..4be7177
--- /dev/null
+++ b/cutl/compiler/type-info.cxx
@@ -0,0 +1,31 @@
+// file : cutl/compiler/type-info.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>
+
+namespace cutl
+{
+ namespace compiler
+ {
+ using namespace bits;
+
+ type_info const&
+ lookup (type_id const& tid)
+ {
+ type_info_map::const_iterator i (type_info_map_->find (tid));
+
+ if (i == type_info_map_->end ())
+ throw no_type_info ();
+
+ return i->second;
+ }
+
+ void
+ insert (type_info const& ti)
+ {
+ type_info_map_->insert (type_info_map::value_type (ti.type_id (), ti));
+ }
+ }
+}
diff --git a/cutl/compiler/type-info.hxx b/cutl/compiler/type-info.hxx
new file mode 100644
index 0000000..f970067
--- /dev/null
+++ b/cutl/compiler/type-info.hxx
@@ -0,0 +1,109 @@
+// file : cutl/compiler/type-info.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CUTL_COMPILER_TYPE_INFO_HXX
+#define CUTL_COMPILER_TYPE_INFO_HXX
+
+#include <map>
+#include <vector>
+#include <typeinfo> // std::type_info
+
+#include <cutl/static-ptr.hxx>
+#include <cutl/compiler/type-id.hxx>
+
+namespace cutl
+{
+ namespace compiler
+ {
+ //
+ //
+ class type_info;
+ typedef type_info type_info_t;
+
+
+ //
+ //
+ class base_info
+ {
+ public:
+ base_info (type_id const&);
+
+ public:
+ type_info_t const&
+ type_info () const;
+
+ private:
+ type_id type_id_;
+ mutable type_info_t const* type_info_;
+ };
+
+ typedef base_info base_info_t;
+
+
+ //
+ //
+ class type_info
+ {
+ typedef std::vector<base_info> bases;
+
+ public:
+ typedef
+ bases::const_iterator
+ base_iterator;
+
+ public:
+ type_info (type_id_t const&);
+
+ type_id_t
+ type_id () const;
+
+ base_iterator
+ begin_base () const;
+
+ base_iterator
+ end_base () const;
+
+ void
+ add_base (type_id_t const&);
+
+ private:
+ type_id_t type_id_;
+ bases bases_;
+ };
+
+
+ //
+ //
+ class no_type_info {};
+
+ type_info const&
+ lookup (type_id const&);
+
+ type_info const&
+ lookup (std::type_info const&);
+
+ template <typename X>
+ type_info const&
+ lookup (X const volatile&);
+
+ template<typename X>
+ type_info const&
+ lookup ();
+
+ void
+ insert (type_info const&);
+
+ namespace bits
+ {
+ struct default_type_info_id {};
+ typedef std::map<type_id, type_info> type_info_map;
+ static static_ptr<type_info_map, default_type_info_id> type_info_map_;
+ }
+ }
+}
+
+#include <cutl/compiler/type-info.ixx>
+
+#endif // CUTL_COMPILER_TYPE_INFO_HXX
diff --git a/cutl/compiler/type-info.ixx b/cutl/compiler/type-info.ixx
new file mode 100644
index 0000000..3f1bb86
--- /dev/null
+++ b/cutl/compiler/type-info.ixx
@@ -0,0 +1,96 @@
+// file : cutl/compiler/type-info.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace compiler
+ {
+ // base_info
+ //
+
+ inline
+ base_info::
+ base_info (type_id const& type_id)
+ : type_id_ (type_id), type_info_ (0)
+ {
+ }
+
+ inline
+ type_info_t const& base_info::
+ type_info () const
+ {
+ // We need to do delayed lookup because of the unpredictable
+ // order in which type information may be added.
+ //
+ // @@ MT-unsafe
+ //
+ if (type_info_ == 0)
+ type_info_ = &(lookup (type_id_));
+
+ return *type_info_;
+ }
+
+ // type_info
+ //
+
+ inline
+ type_info::
+ type_info (type_id_t const& tid)
+ : type_id_ (tid)
+ {
+ }
+
+ inline
+ type_id_t type_info::
+ type_id () const
+ {
+ return type_id_;
+ }
+
+ inline
+ type_info::base_iterator type_info::
+ begin_base () const
+ {
+ return bases_.begin ();
+ }
+
+
+ inline
+ type_info::base_iterator type_info::
+ end_base () const
+ {
+ return bases_.end ();
+ }
+
+ inline
+ void type_info::
+ add_base (type_id_t const& tid)
+ {
+ bases_.push_back (base_info (tid));
+ }
+
+ //
+ //
+ inline type_info const&
+ lookup (std::type_info const& tid)
+ {
+ return lookup (type_id (tid));
+ }
+
+ template <typename X>
+ inline type_info const&
+ lookup (X const volatile& x)
+ {
+ return lookup (typeid (x));
+ }
+
+ template<typename X>
+ inline type_info const&
+ lookup ()
+ {
+ return lookup (typeid (X));
+ }
+ }
+}