docs: function ast_mangle(ast, do_toplevel) {
          var w = ast_walker(), walk = w.walk, scope;
  
          function get_mangled(name, newMangle) {
                  if (!do_toplevel && !scope.parent) return name; // don't mangle toplevel
                  return scope.get_mangled(name, newMangle);
          };
  
          function _lambda(name, args, body) {
                  if (name) name = get_mangled(name);
                  body = with_scope(body.scope, function(){
                          args = args.map(function(name){ return get_mangled(name) });
                          return body.map(walk);
                  });
                  return [ this[0], name, args, body ];
          };
  
          function with_scope(s, cont) {
                  var _scope = scope;
                  scope = s;
                  for (var i in s.names) if (HOP(s.names, i)) {
                          get_mangled(i, true);
                  }
                  try { var ret = cont(); ret.scope = s; return ret; }
                  finally { scope = _scope; };
          };
  
          function _vardefs(defs) {
                  return defs.map(function(d){
                          return [ get_mangled(d[0]), walk(d[1]) ];
                  });
          };
  
          return w.with_walkers({
                  "function": _lambda,
                  "defun": _lambda,
                  "var": function(defs) {
                          return [ "var", _vardefs(defs) ];
                  },
                  "const": function(defs) {
                          return [ "const", _vardefs(defs) ];
                  },
                  "name": function(name) {
                          return [ "name", get_mangled(name) ];
                  },
                  "try": function(t, c, f) {
                          return [ "try",
                                   t.map(walk),
                                   c ? with_scope(c.scope, function(){
                                           return [ get_mangled(c[0]), c[1].map(walk) ];
                                   }) : null,
                                   f != null ? f.map(walk) : null ];
                  },
                  "toplevel": function(body) {
                          return with_scope(this.scope, function(){
                                  return [ "toplevel", body.map(walk) ];
                          });
                  },
                  "for-in": function(has_var, name, obj, stat) {
                          return [ "for-in", has_var, get_mangled(name), walk(obj), walk(stat) ];
                  }
          }, function() {
                  return walk(ast_add_scope(ast));
          });
  }