tree edit_env_rep::rewrite_inactive_arg ( tree t, tree var, int i, bool block, bool flush) { tree r= subvar (var, i); if ((inactive_mode == INACTIVE_INLINE_RECURSE) || (inactive_mode == INACTIVE_BLOCK_RECURSE)) { if (N (recover_env) > 0) { int j; tree recover= copy (recover_env), old_recover= recover_env; for (j=0; j<N(recover); j+=2) { string var= recover[j]->label; recover[j+1]= read (var); write_update (var, recover_env[j+1]); } recover_env= tuple (); r= rewrite_inactive (t[i], r, block, flush); recover_env= old_recover; for (j=0; j<N(recover); j+=2) write_update (recover[j]->label, recover[j+1]); } else r= rewrite_inactive (t[i], r, block, flush); } return highlight (r, t[i], drd->get_type_child (t, i)); }
tree edit_env_rep::rewrite_inactive (tree t, tree var) { // cout << "Rewrite inactive " << t << ", " << var << "\n"; recover_env= tuple (); bool block= (inactive_mode >= INACTIVE_BLOCK_RECURSE); tree r= rewrite_inactive (t, var, block, block); if (is_multi_paragraph (r)) { r= tree (WITH, PAR_PAR_SEP, "0fn", r); r= tree (SURROUND, "", tree (VSPACE, "0.5fn"), r); } if ((inactive_mode == INACTIVE_INLINE_RECURSE) || (inactive_mode == INACTIVE_BLOCK_RECURSE)) r= tree (WITH, MODE, "src", r); // cout << "---> " << r << "\n\n"; return r; }
tree edit_env_rep::rewrite_inactive_style_with ( tree t, tree var, bool block, bool flush, bool once) { int i, n= N(t); tree recover= tuple (); for (i=0; i<n-1; i+=2) if (is_atomic (t[i])) { recover << t[i] << read (t[i]->label); write_update (t[i]->label, t[i+1]); } if (once) recover_env= recover; tree r= rewrite_inactive (t[n-1], subvar (var, n-1), block, flush); for (i=0; i<N(recover); i+=2) write_update (recover[i]->label, recover[i+1]); if (once) recover_env= tuple (); return tree (MARK, var, r); }
tree rewrite_impl (tree t) { switch (L(t)) { case EXTERN: { int i, n= N(t); tree r (TUPLE, n); for (i=0; i<n; i++) r[i]= evaluate (t[i]); object expr= null_object (); for (i=n-1; i>0; i--) expr= cons (object (r[i]), expr); string fun= evaluate_string (t[0]); expr= cons (string_to_object (fun), expr); bool secure= as_bool (std_env ["secure"]); if (!secure && script_status < 2) { if (!as_bool (call ("secure?", expr))) return tree (ERROR, "insecure script"); } environment old_env= reenter_rewrite_env; reenter_rewrite_env= std_env; object o= eval (expr); reenter_rewrite_env= old_env; return content_to_tree (o); } #ifdef CLASSICAL_MACRO_EXPANSION case MAP_ARGS: { if (!(is_atomic (t[0]) && is_atomic (t[1]) && is_atomic (t[2]))) return evaluate_error ("invalid map-args"); if (macro_top_level (std_env)) return evaluate_error ("undefined", t[2]); basic_environment local= macro_arguments (std_env); int key= make_tree_label (t[2]->label); if (!local->contains (key)) return evaluate_error ("undefined", t[2]); tree v= local [key]; if (is_atomic (v)) return evaluate_error ("invalid-map-args"); macro_up (std_env); int start= 0, end= N(v); if (N(t)>=4) start= as_int (evaluate (t[3])); if (N(t)>=5) end = as_int (evaluate (t[4])); int i, n= max (0, end-start); tree r (make_tree_label (t[1]->label), n); for (i=0; i<n; i++) r[i]= tree (make_tree_label (t[0]->label), tree (ARG, copy (t[2]), as_string (start+i)), as_string (start+i)); macro_redown (std_env, local); return r; } #endif // CLASSICAL_MACRO_EXPANSION case VAR_INCLUDE: { url base_file_name (as_string (std_env ["base-file-name"])); url file_name= url_system (evaluate_string (t[0])); return load_inclusion (relative (base_file_name, file_name)); } case REWRITE_INACTIVE: { #ifdef CLASSICAL_MACRO_EXPANSION if ((!is_func (t[0], ARG)) || is_compound (t[0][0])) return evaluate_error ("invalid rewrite-inactive"); if (macro_top_level (std_env)) return evaluate_error ("undefined", t[0][0]); basic_environment local= macro_arguments (std_env); int key= make_tree_label (t[0][0]->label); if (!local->contains (key)) return evaluate_error ("undefined", t[0][0]); tree val= local [key]; int i, n= N(t[0]); for (i=1; i<n; i++) { int j= as_int (t[0][i]); if ((j>=0) && (j<N(val))) val= val[j]; else return evaluate_error ("invalid rewrite-inactive"); } #else tree val= t[0]; #endif int inactive_mode= INACTIVE_INLINE_RECURSE; if (t[1] == "recurse") inactive_mode= INACTIVE_INLINE_RECURSE; else if (t[1] == "recurse*") inactive_mode= INACTIVE_BLOCK_RECURSE; else if (t[1] == "once") inactive_mode= INACTIVE_INLINE_ONCE; else if (t[1] == "once*") inactive_mode= INACTIVE_BLOCK_ONCE; else if (t[1] == "error") inactive_mode= INACTIVE_INLINE_ERROR; else if (t[1] == "error*") inactive_mode= INACTIVE_BLOCK_ERROR; return rewrite_inactive (val, inactive_mode); } default: return t; } }