Back to index

texmacs  1.0.7.15
bridge_with.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : bridge_with.cpp
00004 * DESCRIPTION: Bridge between logical and physical local enviroment changes
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "bridge.hpp"
00013 
00014 class bridge_with_rep: public bridge_rep {
00015 protected:
00016   int    last;
00017   bridge body;
00018 
00019 public:
00020   bridge_with_rep (typesetter ttt, tree st, path ip);
00021   void initialize ();
00022 
00023   void notify_assign (path p, tree u);
00024   void notify_insert (path p, tree u);
00025   void notify_remove (path p, int nr);
00026   bool notify_macro  (int type, string var, int level, path p, tree u);
00027   void notify_change ();
00028 
00029   void my_exec_until (path p);
00030   bool my_typeset_will_be_complete ();
00031   void my_typeset (int desired_status);
00032 };
00033 
00034 bridge_with_rep::bridge_with_rep (typesetter ttt, tree st, path ip):
00035   bridge_rep (ttt, st, ip)
00036 {
00037   initialize ();
00038 }
00039 
00040 void
00041 bridge_with_rep::initialize () {
00042   last= N(st)-1;
00043   if (is_nil(body)) body= make_bridge (ttt, st[last], descend (ip, last));
00044   else replace_bridge (body, st[last], descend (ip, last));
00045 }
00046 
00047 bridge
00048 bridge_with (typesetter ttt, tree st, path ip) {
00049   return tm_new<bridge_with_rep> (ttt, st, ip);
00050 }
00051 
00052 /******************************************************************************
00053 * Event notification
00054 ******************************************************************************/
00055 
00056 void
00057 bridge_with_rep::notify_assign (path p, tree u) {
00058   // cout << "Assign " << p << ", " << u << " in " << st << "\n";
00059   ASSERT (!is_nil (p) || is_func (u, WITH), "nil path");
00060   if (is_nil (p)) {
00061     st=u;
00062     initialize ();
00063   }
00064   else {
00065     bool mp_flag= is_multi_paragraph (st);
00066     if (p->item == last) {
00067       if (is_atom (p)) body= make_bridge (ttt, u, descend (ip, last));
00068       else body->notify_assign (p->next, u);
00069       st= substitute (st, p->item, body->st);
00070     }
00071     else {
00072       st= substitute (st, p, u);
00073       body->notify_change ();
00074     }
00075     if (mp_flag != is_multi_paragraph (st)) initialize ();
00076   }
00077   status= CORRUPTED;
00078 }
00079 
00080 void
00081 bridge_with_rep::notify_insert (path p, tree u) {
00082   // cout << "Insert " << p << ", " << u << " in " << st << "\n";
00083   ASSERT (!is_nil (p), "nil path");
00084   if (is_atom (p) || (p->item != last)) bridge_rep::notify_insert (p, u);
00085   else {
00086     bool mp_flag= is_multi_paragraph (st);
00087     body->notify_insert (p->next, u);
00088     st= substitute (st, last, body->st);
00089     if (mp_flag != is_multi_paragraph (st)) initialize ();
00090   }
00091   status= CORRUPTED;
00092 }
00093 
00094 void
00095 bridge_with_rep::notify_remove (path p, int nr) {
00096   // cout << "Remove " << p << ", " << nr << " in " << st << "\n";
00097   ASSERT (!is_nil (p), "nil path");
00098   if (is_atom (p) || (p->item != last)) bridge_rep::notify_remove (p, nr);
00099   else {
00100     bool mp_flag= is_multi_paragraph (st);
00101     body->notify_remove (p->next, nr);
00102     st= substitute (st, last, body->st);
00103     if (mp_flag != is_multi_paragraph (st)) initialize ();
00104   }
00105   status= CORRUPTED;
00106 }
00107 
00108 bool
00109 bridge_with_rep::notify_macro (int type, string var, int l, path p, tree u) {
00110   bool flag= body->notify_macro (type, var, l, p, u);
00111   if (flag) status= CORRUPTED;
00112   return flag;
00113 }
00114 
00115 void
00116 bridge_with_rep::notify_change () {
00117   status= CORRUPTED;
00118   body->notify_change ();
00119 }
00120 
00121 /******************************************************************************
00122 * Typesetting
00123 ******************************************************************************/
00124 
00125 void
00126 bridge_with_rep::my_exec_until (path p) {
00127   int i, k= last>>1; // is k=0 allowed ?
00128   if (((last&1) != 0) || (p->item != last)) return;
00129   STACK_NEW_ARRAY(vars,string,k);
00130   STACK_NEW_ARRAY(newv,tree,k);
00131   for (i=0; i<k; i++) {
00132     tree var_t= env->exec (st[i<<1]);
00133     if (is_atomic (var_t)) {
00134       string var= var_t->label;
00135       vars[i]= var;
00136       newv[i]= env->exec (st[(i<<1)+1]);
00137     }
00138     else {
00139       STACK_DELETE_ARRAY(vars);
00140       STACK_DELETE_ARRAY(newv);
00141       return;
00142     }
00143   }
00144   for (i=0; i<k; i++) env->monitored_write_update (vars[i], newv[i]);
00145   body->exec_until (p->next);
00146   STACK_DELETE_ARRAY(vars);
00147   STACK_DELETE_ARRAY(newv);
00148 }
00149 
00150 bool
00151 bridge_with_rep::my_typeset_will_be_complete () {
00152   if (status != CORRUPTED) return false;
00153   return body->my_typeset_will_be_complete ();
00154 }
00155 
00156 void
00157 bridge_with_rep::my_typeset (int desired_status) {
00158   int i, k= last>>1; // is k=0 allowed ?
00159   // if ((last&1) != 0) return;
00160   
00161   STACK_NEW_ARRAY(vars,string,k);
00162   STACK_NEW_ARRAY(oldv,tree,k);
00163   STACK_NEW_ARRAY(newv,tree,k);
00164   for (i=0; i<k; i++) {
00165     tree var_t= env->exec (st[i<<1]);
00166     if (is_atomic (var_t)) {
00167       string var= var_t->label;
00168       vars[i]= var;
00169       oldv[i]= env->read (var);
00170       newv[i]= env->exec (st[(i<<1)+1]);
00171     }
00172     /*
00173     else {
00174       STACK_DELETE_ARRAY(vars);
00175       STACK_DELETE_ARRAY(oldv);
00176       STACK_DELETE_ARRAY(newv);
00177       return;
00178     }
00179     */
00180   }
00181 
00182   // for (i=0; i<k; i++) env->monitored_write_update (vars[i], newv[i]);
00183   for (i=0; i<k; i++) env->write_update (vars[i], newv[i]);
00184   ttt->insert_marker (st, ip);
00185   body->typeset (desired_status);
00186   for (i=k-1; i>=0; i--) env->write_update (vars[i], oldv[i]);
00187   STACK_DELETE_ARRAY(vars);
00188   STACK_DELETE_ARRAY(oldv);
00189   STACK_DELETE_ARRAY(newv);
00190 }