void link_announce (tree ln, string id, modification mod) { //cout << "Link event " << ln << ", " << id << ", " << mod << "\n"; for (list<tree> l= get_mirrors (ln, id); !is_nil (l); l= l->next) if (is_applicable (l->item, mod)) apply (get_reference (l->item), copy (mod)); }
void bridge_compound_rep::my_typeset (int desired_status) { int d; tree f; if (L(st) == COMPOUND) { d= 1; f= st[0]; if (is_compound (f)) f= env->exec (f); if (is_atomic (f)) { string var= f->label; if (env->provides (var)) f= env->read (var); else f= tree (ERROR, st); } } else { string var= as_string (L(st)); if (env->provides (var)) f= env->read (var); else f= tree (ERROR, st); d= 0; } if (is_applicable (f)) { int i, n=N(f)-1, m=N(st)-d; env->macro_arg= list<hashmap<string,tree> > ( hashmap<string,tree> (UNINIT), env->macro_arg); env->macro_src= list<hashmap<string,path> > ( hashmap<string,path> (path (DECORATION)), env->macro_src); if (L(f) == XMACRO) { if (is_atomic (f[0])) { string var= f[0]->label; env->macro_arg->item (var)= st; env->macro_src->item (var)= ip; } } else for (i=0; i<n; i++) if (is_atomic (f[i])) { string var= f[i]->label; env->macro_arg->item (var)= i<m? st[i+d]: attach_dip (tree (UNINIT), decorate_right (ip)); env->macro_src->item (var)= i<m? descend (ip,i+d): decorate_right(ip); } initialize (f[n], d, f); // /*IF_NON_CHILD_ENFORCING(st)*/ ttt->insert_marker (st, ip); if (!the_drd->is_child_enforcing (st)) ttt->insert_marker (st, ip); body->typeset (desired_status); env->macro_arg= env->macro_arg->next; env->macro_src= env->macro_src->next; } else { initialize (f, d, f); ///*IF_NON_CHILD_ENFORCING(st)*/ ttt->insert_marker (st, ip); if (!the_drd->is_child_enforcing (st)) ttt->insert_marker (st, ip); body->typeset (desired_status); } }
bool is_applicable (patch p, tree t) { switch (get_type (p)) { case PATCH_MODIFICATION: return is_applicable (t, get_modification (p)); case PATCH_COMPOUND: for (int i=0; i<N(p); i++) { if (!is_applicable (p[i], t)) return false; t= clean_apply (p[i], t); } return true; case PATCH_BRANCH: case PATCH_AUTHOR: for (int i=0; i<N(p); i++) if (!is_applicable (p[i], t)) return false; return true; case PATCH_BIRTH: return true; default: FAILED ("unsupported patch type"); return false; } }
void bridge_compound_rep::notify_insert (path p, tree u) { // cout << "Insert " << p << ", " << u << " in " << st << "\n"; ASSERT (!is_nil (p), "nil path"); if (is_atom (p) || is_nil (body)) bridge_rep::notify_insert (p, u); else { // bool mp_flag= is_multi_paragraph (st); if (is_func (fun, XMACRO, 2)) notify_macro (MACRO_INSERT, fun[0]->label, -1, p, u); else if (is_applicable (fun) && (p->item < N(fun))) notify_macro (MACRO_INSERT, fun[p->item-delta]->label, -1, p->next, u); st= insert_at (st, p, u); // if (mp_flag != is_multi_paragraph (st)) valid= false; } status= CORRUPTED; }
void bridge_compound_rep::notify_remove (path p, int nr) { // cout << "Remove " << p << ", " << nr << " in " << st << "\n"; ASSERT (!is_nil (p), "nil path"); if (is_atom (p) || is_nil (body)) bridge_rep::notify_remove (p, nr); else { // bool mp_flag= is_multi_paragraph (st); if (is_func (fun, XMACRO, 2)) notify_macro (MACRO_REMOVE, fun[0]->label, -1, p, tree (as_string (nr))); else if (is_applicable (fun) && (p->item < N(fun))) notify_macro (MACRO_REMOVE, fun[p->item-delta]->label, -1, p->next, tree (as_string (nr))); st= remove_at (st, p, nr); // if (mp_flag != is_multi_paragraph (st)) valid= false; } status= CORRUPTED; }
void bridge_compound_rep::notify_assign (path p, tree u) { // cout << "Assign " << p << ", " << u << " in " << st << "\n"; ASSERT (!is_nil (p) || L(u) >= START_EXTENSIONS, "nil path"); if (is_nil (p) || (p->item == 0) || is_nil (body)) { st= substitute (st, p, u); valid= false; } else { // bool mp_flag= is_multi_paragraph (st); if (is_func (fun, XMACRO, 2)) notify_macro (MACRO_ASSIGN, fun[0]->label, -1, p, u); else if (is_applicable (fun) && (p->item < N(fun))) notify_macro (MACRO_ASSIGN, fun[p->item-delta]->label, -1, p->next, u); st= substitute (st, p, u); // if (mp_flag != is_multi_paragraph (st)) valid= false; } status= CORRUPTED; }
modification invert (modification m, tree t) { ASSERT (is_applicable (t, m), "modification not applicable"); path rp= root (m); switch (m->k) { case MOD_ASSIGN: return mod_assign (rp, copy (subtree (t, rp))); case MOD_INSERT: return mod_remove (rp, index (m), insert_length (m->t)); case MOD_REMOVE: { int i= index (m); int n= argument (m); return mod_insert (rp, i, copy (insert_range (subtree (t, rp), i, n))); } case MOD_SPLIT: return mod_join (rp, index (m)); case MOD_JOIN: { int i= index (m); return mod_split (rp, i, insert_length (subtree (t, rp * i))); } case MOD_ASSIGN_NODE: return mod_assign_node (rp, L (subtree (t, rp))); case MOD_INSERT_NODE: return mod_remove_node (rp, argument (m)); case MOD_REMOVE_NODE: { tree u= subtree (t, rp); int i= index (m); return mod_insert_node (rp, i, copy (u (0, i) * u (i+1, N(u)))); } case MOD_SET_CURSOR: return m; default: FAILED ("unexpected situation"); } }
path cursor_hint (modification m, tree t) { ASSERT (is_applicable (t, m), "modification not applicable"); path rp= root (m); tree st= subtree (t, rp); switch (m->k) { case MOD_ASSIGN: return end (t, rp); case MOD_INSERT: if (is_atomic (st)) return rp * index (m); else if (index (m) == N (st)) return end (t, rp); else return start (t, rp * index (m)); case MOD_REMOVE: if (is_atomic (st)) return rp * (index (m) + argument (m)); else if (index (m) == N (st)) return end (t, rp); else if (argument (m) == 0) return start (t, rp * index (m)); else return end (t, rp * (index (m) + argument (m) - 1)); case MOD_SPLIT: if (is_atomic (st [index (m)])) return m->p; else if (argument (m) == N (st [index (m)])) return end (t, rp * index(m)); else return start (t, m->p); case MOD_JOIN: return end (t, m->p); case MOD_ASSIGN_NODE: return end (t, rp); case MOD_INSERT_NODE: return end (t, rp); case MOD_REMOVE_NODE: return end (t, rp * index (m)); case MOD_SET_CURSOR: return path (); default: FAILED ("unexpected situation"); return path (); } }