Variable: js--moz-interactor

js--moz-interactor is a variable defined in js.el.gz.

Value

"(function(repl) { repl.defineInteractor('js', { onStart: function onStart(repl) { if(!repl._jsObjects) { repl._jsObjects = {}; repl._jsLastID = 0; repl._jsGC = this._jsGC; } this._input = ''; }, _jsGC: function _jsGC(ids_in_use) { var objects = this._jsObjects; var keys = []; var num_freed = 0; for(var pn in objects) { keys.push(Number(pn)); } keys.sort(function(x, y) x - y); ids_in_use.sort(function(x, y) x - y); var i = 0; var j = 0; while(i < ids_in_use.length && j < keys.length) { var id = ids_in_use[i++]; while(j < keys.length && keys[j] !== id) { var k_id = keys[j++]; delete objects[k_id]; ++num_freed; } ++j; } while(j < keys.length) { var k_id = keys[j++]; delete objects[k_id]; ++num_freed; } return num_freed; }, _mkArray: function _mkArray() { var result = []; for(var i = 0; i < arguments.length; ++i) { result.push(arguments[i]); } return result; }, _parsePropDescriptor: function _parsePropDescriptor(parts) { if(typeof parts === 'string') { parts = [ parts ]; } var obj = parts[0]; var start = 1; if(typeof obj === 'string') { obj = window; start = 0; } else if(parts.length < 2) { throw new Error('expected at least 2 arguments'); } for(var i = start; i < parts.length - 1; ++i) { obj = obj[parts[i]]; } return [obj, parts[parts.length - 1]]; }, _getProp: function _getProp(/*...*/) { if(arguments.length === 0) { throw new Error('no arguments supplied to getprop'); } if(arguments.length === 1 && (typeof arguments[0]) !== 'string') { return arguments[0]; } var [obj, propname] = this._parsePropDescriptor(arguments); return obj[propname]; }, _putProp: function _putProp(properties, value) { var [obj, propname] = this._parsePropDescriptor(properties); obj[propname] = value; }, _delProp: function _delProp(propname) { var [obj, propname] = this._parsePropDescriptor(arguments); delete obj[propname]; }, _typeOf: function _typeOf(thing) { return typeof thing; }, _callNew: function(constructor) { if(typeof constructor === 'string') { constructor = window[constructor]; } else if(constructor.length === 1 && typeof constructor[0] !== 'string') { constructor = constructor[0]; } else { var [obj,propname] = this._parsePropDescriptor(constructor); constructor = obj[propname]; } /* Hacky, but should be robust */ var s = 'new constructor('; for(var i = 1; i < arguments.length; ++i) { if(i != 1) { s += ','; } s += 'arguments[' + i + ']'; } s += ')'; return eval(s); }, _callEval: function(thisobj, js) { return eval.call(thisobj, js); }, getPrompt: function getPrompt(repl) { return 'EVAL>' }, _lookupObject: function _lookupObject(repl, id) { if(typeof id === 'string') { switch(id) { case 'global': return window; case 'nil': return null; case 't': return true; case 'false': return false; case 'undefined': return undefined; case 'repl': return repl; case 'interactor': return this; case 'NaN': return NaN; case 'Infinity': return Infinity; case '-Infinity': return -Infinity; default: throw new Error('No object with special id:' + id); } } var ret = repl._jsObjects[id]; if(ret === undefined) { throw new Error('No object with id:' + id + '(' + typeof id + ')'); } return ret; }, _findOrAllocateObject: function _findOrAllocateObject(repl, value) { if(typeof value !== 'object' && typeof value !== 'function') { throw new Error('_findOrAllocateObject called on non-object(' + typeof(value) + '): ' + value) } for(var id in repl._jsObjects) { id = Number(id); var obj = repl._jsObjects[id]; if(obj === value) { return id; } } var id = ++repl._jsLastID; repl._jsObjects[id] = value; return id; }, _fixupList: function _fixupList(repl, list) { for(var i = 0; i < list.length; ++i) { if(list[i] instanceof Array) { this._fixupList(repl, list[i]); } else if(typeof list[i] === 'object') { var obj = list[i]; if(obj.funcall) { var parts = obj.funcall; this._fixupList(repl, parts); var [thisobj, func] = this._parseFunc(parts[0]); list[i] = func.apply(thisobj, parts.slice(1)); } else if(obj.objid) { list[i] = this._lookupObject(repl, obj.objid); } else { throw new Error('Unknown object type: ' + obj.toSource()); } } } }, _parseFunc: function(func) { var thisobj = null; if(typeof func === 'string') { func = window[func]; } else if(func instanceof Array) { if(func.length === 1 && typeof func[0] !== 'string') { func = func[0]; } else { [thisobj, func] = this._parsePropDescriptor(func); func = thisobj[func]; } } return [thisobj,func]; }, _encodeReturn: function(value, array_as_mv) { var ret; if(value === null) { ret = ['special', 'null']; } else if(value === true) { ret = ['special', 'true']; } else if(value === false) { ret = ['special', 'false']; } else if(value === undefined) { ret = ['special', 'undefined']; } else if(typeof value === 'number') { if(isNaN(value)) { ret = ['special', 'NaN']; } else if(value === Infinity) { ret = ['special', 'Infinity']; } else if(value === -Infinity) { ret = ['special', '-Infinity']; } else { ret = ['atom', value]; } } else if(typeof value === 'string') { ret = ['atom', value]; } else if(array_as_mv && value instanceof Array) { ret = ['array', value.map(this._encodeReturn, this)]; } else { ret = ['objid', this._findOrAllocateObject(repl, value)]; } return ret; }, _handleInputLine: function _handleInputLine(repl, line) { var ret; var array_as_mv = false; try { if(line[0] === '*') { array_as_mv = true; line = line.substring(1); } var parts = eval(line); this._fixupList(repl, parts); var [thisobj, func] = this._parseFunc(parts[0]); ret = this._encodeReturn( func.apply(thisobj, parts.slice(1)), array_as_mv); } catch(x) { ret = ['error', x.toString() ]; } var JSON = Components.classes['@mozilla.org/dom/json;1'].createInstance(Components.interfaces.nsIJSON); repl.print(JSON.encode(ret)); repl._prompt(); }, handleInput: function handleInput(repl, chunk) { this._input += chunk; var match, line; while(match = this._input.match(/.*\\n/)) { line = match[0]; if(line === 'EXIT\\n') { repl.popInteractor(); repl._prompt(); return; } this._input = this._input.substring(line.length); this._handleInputLine(repl, line); } } }); }) "

Documentation

String to set MozRepl up into a simple-minded evaluation mode.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/js.el.gz
(defconst js--moz-interactor
  (replace-regexp-in-string
   "[ \n]+" " "
   ; */" Make Emacs happy
"(function(repl) {
  repl.defineInteractor('js', {
    onStart: function onStart(repl) {
      if(!repl._jsObjects) {
        repl._jsObjects = {};
        repl._jsLastID = 0;
        repl._jsGC = this._jsGC;
      }
      this._input = '';
    },

    _jsGC: function _jsGC(ids_in_use) {
      var objects = this._jsObjects;
      var keys = [];
      var num_freed = 0;

      for(var pn in objects) {
        keys.push(Number(pn));
      }

      keys.sort(function(x, y) x - y);
      ids_in_use.sort(function(x, y) x - y);
      var i = 0;
      var j = 0;

      while(i < ids_in_use.length && j < keys.length) {
        var id = ids_in_use[i++];
        while(j < keys.length && keys[j] !== id) {
          var k_id = keys[j++];
          delete objects[k_id];
          ++num_freed;
        }
        ++j;
      }

      while(j < keys.length) {
        var k_id = keys[j++];
        delete objects[k_id];
        ++num_freed;
      }

      return num_freed;
    },

    _mkArray: function _mkArray() {
      var result = [];
      for(var i = 0; i < arguments.length; ++i) {
        result.push(arguments[i]);
      }
      return result;
    },

    _parsePropDescriptor: function _parsePropDescriptor(parts) {
      if(typeof parts === 'string') {
        parts = [ parts ];
      }

      var obj = parts[0];
      var start = 1;

      if(typeof obj === 'string') {
        obj = window;
        start = 0;
      } else if(parts.length < 2) {
        throw new Error('expected at least 2 arguments');
      }

      for(var i = start; i < parts.length - 1; ++i) {
        obj = obj[parts[i]];
      }

      return [obj, parts[parts.length - 1]];
    },

    _getProp: function _getProp(/*...*/) {
      if(arguments.length === 0) {
        throw new Error('no arguments supplied to getprop');
      }

      if(arguments.length === 1 &&
         (typeof arguments[0]) !== 'string')
      {
        return arguments[0];
      }

      var [obj, propname] = this._parsePropDescriptor(arguments);
      return obj[propname];
    },

    _putProp: function _putProp(properties, value) {
      var [obj, propname] = this._parsePropDescriptor(properties);
      obj[propname] = value;
    },

    _delProp: function _delProp(propname) {
      var [obj, propname] = this._parsePropDescriptor(arguments);
      delete obj[propname];
    },

    _typeOf: function _typeOf(thing) {
      return typeof thing;
    },

    _callNew: function(constructor) {
      if(typeof constructor === 'string')
      {
        constructor = window[constructor];
      } else if(constructor.length === 1 &&
                typeof constructor[0] !== 'string')
      {
        constructor = constructor[0];
      } else {
        var [obj,propname] = this._parsePropDescriptor(constructor);
        constructor = obj[propname];
      }

      /* Hacky, but should be robust */
      var s = 'new constructor(';
      for(var i = 1; i < arguments.length; ++i) {
        if(i != 1) {
          s += ',';
        }

        s += 'arguments[' + i + ']';
      }

      s += ')';
      return eval(s);
    },

    _callEval: function(thisobj, js) {
      return eval.call(thisobj, js);
    },

    getPrompt: function getPrompt(repl) {
      return 'EVAL>'
    },

    _lookupObject: function _lookupObject(repl, id) {
      if(typeof id === 'string') {
        switch(id) {
        case 'global':
          return window;
        case 'nil':
          return null;
        case 't':
          return true;
        case 'false':
          return false;
        case 'undefined':
          return undefined;
        case 'repl':
          return repl;
        case 'interactor':
          return this;
        case 'NaN':
          return NaN;
        case 'Infinity':
          return Infinity;
        case '-Infinity':
          return -Infinity;
        default:
          throw new Error('No object with special id:' + id);
        }
      }

      var ret = repl._jsObjects[id];
      if(ret === undefined) {
        throw new Error('No object with id:' + id + '(' + typeof id + ')');
      }
      return ret;
    },

    _findOrAllocateObject: function _findOrAllocateObject(repl, value) {
      if(typeof value !== 'object'  && typeof value !== 'function') {
        throw new Error('_findOrAllocateObject called on non-object('
                        + typeof(value) + '): '
                        + value)
      }

      for(var id in repl._jsObjects) {
        id = Number(id);
        var obj = repl._jsObjects[id];
        if(obj === value) {
          return id;
        }
      }

      var id = ++repl._jsLastID;
      repl._jsObjects[id] = value;
      return id;
    },

    _fixupList: function _fixupList(repl, list) {
      for(var i = 0; i < list.length; ++i) {
        if(list[i] instanceof Array) {
          this._fixupList(repl, list[i]);
        } else if(typeof list[i] === 'object') {
          var obj = list[i];
          if(obj.funcall) {
            var parts = obj.funcall;
            this._fixupList(repl, parts);
            var [thisobj, func] = this._parseFunc(parts[0]);
            list[i] = func.apply(thisobj, parts.slice(1));
          } else if(obj.objid) {
            list[i] = this._lookupObject(repl, obj.objid);
          } else {
            throw new Error('Unknown object type: ' + obj.toSource());
          }
        }
      }
    },

    _parseFunc: function(func) {
      var thisobj = null;

      if(typeof func === 'string') {
        func = window[func];
      } else if(func instanceof Array) {
        if(func.length === 1 && typeof func[0] !== 'string') {
          func = func[0];
        } else {
          [thisobj, func] = this._parsePropDescriptor(func);
          func = thisobj[func];
        }
      }

      return [thisobj,func];
    },

    _encodeReturn: function(value, array_as_mv) {
      var ret;

      if(value === null) {
        ret = ['special', 'null'];
      } else if(value === true) {
        ret = ['special', 'true'];
      } else if(value === false) {
        ret = ['special', 'false'];
      } else if(value === undefined) {
        ret = ['special', 'undefined'];
      } else if(typeof value === 'number') {
        if(isNaN(value)) {
          ret = ['special', 'NaN'];
        } else if(value === Infinity) {
          ret = ['special', 'Infinity'];
        } else if(value === -Infinity) {
          ret = ['special', '-Infinity'];
        } else {
          ret = ['atom', value];
        }
      } else if(typeof value === 'string') {
        ret = ['atom', value];
      } else if(array_as_mv && value instanceof Array) {
        ret = ['array', value.map(this._encodeReturn, this)];
      } else {
        ret = ['objid', this._findOrAllocateObject(repl, value)];
      }

      return ret;
    },

    _handleInputLine: function _handleInputLine(repl, line) {
      var ret;
      var array_as_mv = false;

      try {
        if(line[0] === '*') {
          array_as_mv = true;
          line = line.substring(1);
        }
        var parts = eval(line);
        this._fixupList(repl, parts);
        var [thisobj, func] = this._parseFunc(parts[0]);
        ret = this._encodeReturn(
          func.apply(thisobj, parts.slice(1)),
          array_as_mv);
      } catch(x) {
        ret = ['error', x.toString() ];
      }

      var JSON = Components.classes['@mozilla.org/dom/json;1'].createInstance(Components.interfaces.nsIJSON);
      repl.print(JSON.encode(ret));
      repl._prompt();
    },

    handleInput: function handleInput(repl, chunk) {
      this._input += chunk;
      var match, line;
      while(match = this._input.match(/.*\\n/)) {
        line = match[0];

        if(line === 'EXIT\\n') {
          repl.popInteractor();
          repl._prompt();
          return;
        }

        this._input = this._input.substring(line.length);
        this._handleInputLine(repl, line);
      }
    }
  });
})
")

  "String to set MozRepl up into a simple-minded evaluation mode.")