Back to index

texmacs  1.0.7.15
tree_addendum.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tree_addendum.cpp
00004 * DESCRIPTION: Persistently attach data to trees
00005 * COPYRIGHT  : (C) 2012  Joris van der Hoeven
00006 *******************************************************************************
00007 * An inverse path observer maintains the inverse path of the position
00008 * of the corresponding tree with respect to the global meta-tree.
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "tree.hpp"
00016 #include "blackbox.hpp"
00017 
00018 /******************************************************************************
00019 * Definition of the tree_pointer_rep class
00020 ******************************************************************************/
00021 
00022 class tree_addendum_rep: public observer_rep {
00023 private:
00024   tree_rep* ptr;
00025   int kind;
00026   blackbox contents;
00027 
00028 public:
00029   tree_addendum_rep (tree ref, int kind2, blackbox contents2):
00030     ptr (ref.rep), kind (kind2), contents (contents2) {}
00031   int get_type () { return OBSERVER_ADDENDUM; }
00032   tm_ostream& print (tm_ostream& out) {
00033     return out << " addendum (" << kind << ", " << contents << ")"; }
00034 
00035   void notify_assign      (tree& ref, tree t);
00036   void notify_insert      (tree& ref, int pos, int nr);
00037   void notify_remove      (tree& ref, int pos, int nr);
00038   void notify_split       (tree& ref, int pos, tree prev);
00039   void notify_var_split   (tree& ref, tree t1, tree t2);
00040   void notify_join        (tree& ref, int pos, tree next);
00041   void notify_var_join    (tree& ref, tree t, int offset);
00042   void notify_assign_node (tree& ref, tree_label op);
00043   void notify_insert_node (tree& ref, int pos);
00044   void notify_remove_node (tree& ref, int pos);
00045   void notify_detach      (tree& ref, tree closest, bool right);
00046 
00047   bool get_contents (int kind, blackbox& bb);
00048   bool set_tree (tree t);
00049   bool get_tree (tree& t);
00050 };
00051 
00052 /******************************************************************************
00053 * Specific routines for tree_addendum observers
00054 ******************************************************************************/
00055 
00056 bool
00057 tree_addendum_rep::get_contents (int which, blackbox& bb) {
00058   if (which != kind) return false;
00059   bb= contents;
00060   return true;
00061 }
00062 
00063 bool
00064 tree_addendum_rep::get_tree (tree& t) {
00065   t= tree (ptr);
00066   return true;
00067 }
00068 
00069 bool
00070 tree_addendum_rep::set_tree (tree t) {
00071   if (ptr != t.rep) {
00072     tree ref (ptr);
00073     remove_observer (ref->obs, observer (this));
00074     ptr= t.rep;
00075     insert_observer (t->obs, observer (this));
00076   }
00077   return true;
00078 }
00079 
00080 /******************************************************************************
00081 * Call back routines for modifications
00082 ******************************************************************************/
00083 
00084 void
00085 tree_addendum_rep::notify_assign (tree& ref, tree t) {
00086   // cout << "Notify assign " << ref << ", " << t << "\n";
00087   (void) ref; (void) set_tree (t);
00088   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00089 }
00090 
00091 void
00092 tree_addendum_rep::notify_insert (tree& ref, int pos, int nr) {
00093   // cout << "Notify insert " << ref << ", " << pos << ", " << nr << "\n";
00094   (void) ref; (void) pos; (void) nr;
00095   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00096 }
00097 
00098 void
00099 tree_addendum_rep::notify_remove (tree& ref, int pos, int nr) {
00100   // cout << "Notify remove " << ref << ", " << pos << ", " << nr << "\n";
00101   (void) ref; (void) pos; (void) nr;
00102   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00103 }
00104 
00105 void
00106 tree_addendum_rep::notify_split (tree& ref, int pos, tree prev) {
00107   (void) ref; (void) pos; (void) prev;
00108 }
00109 
00110 void
00111 tree_addendum_rep::notify_var_split (tree& ref, tree t1, tree t2) {
00112   // cout << "Notify var split " << ref << ", " << t1 << ", " << t2 << "\n";
00113   (void) t2; (void) ref;
00114   (void) set_tree (t1); // always at the left
00115   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00116 }
00117 
00118 void
00119 tree_addendum_rep::notify_join (tree& ref, int pos, tree next) {
00120   (void) ref; (void) pos; (void) next;
00121 }
00122 
00123 void
00124 tree_addendum_rep::notify_var_join (tree& ref, tree t, int offset) {
00125   // cout << "Notify var join " << ref << ", " << t << ", " << offset << "\n";
00126   (void) ref; (void) offset;
00127   (void) set_tree (t);
00128   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00129 }
00130 
00131 void
00132 tree_addendum_rep::notify_assign_node (tree& ref, tree_label op) {
00133   // cout << "Notify assign node " << ref << ", " << as_string (op) << "\n";
00134   (void) ref; (void) op;
00135   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00136 }
00137 
00138 void
00139 tree_addendum_rep::notify_insert_node (tree& ref, int pos) {
00140   //cout << "Notify insert node " << ref << ", " << pos << "\n";
00141   // NOTE: we might want to remove these lines; see tree_pointer.cpp
00142   remove_observer (ref[pos]->obs, observer (this));
00143   ptr= ref.rep;
00144   insert_observer (ref->obs, observer (this));
00145   //cout << "position -> " << obtain_position (observer (this)) << "\n";
00146 }
00147 
00148 void
00149 tree_addendum_rep::notify_remove_node (tree& ref, int pos) {
00150   // cout << "Notify remove node " << ref << ", " << pos << "\n";
00151   (void) set_tree (ref[pos]);
00152   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00153 }
00154 
00155 void
00156 tree_addendum_rep::notify_detach (tree& ref, tree closest, bool right) {
00157   // cout << "Notify detach " << ref << ", " << closest <<", "<< right << "\n";
00158   (void) right; (void) ref;
00159   (void) set_tree (closest);
00160   // cout << "position -> " << obtain_position (observer (this)) << "\n";
00161 }
00162 
00163 /******************************************************************************
00164 * Public interface
00165 ******************************************************************************/
00166 
00167 observer
00168 tree_addendum (tree ref, int kind, blackbox contents) {
00169   return tm_new<tree_addendum_rep> (ref, kind, contents);
00170 }
00171 
00172 observer
00173 tree_addendum_new (tree ref, int kind, blackbox contents) {
00174   observer obs= tree_addendum (ref, kind, contents);
00175   attach_observer (ref, obs);
00176   return obs;
00177 }
00178 
00179 void
00180 tree_addendum_delete (observer obs) {
00181   tree ref= obtain_tree (obs);
00182   detach_observer (ref, obs);
00183 }