0

I wrote a "Karel the robot" for teaching Javascript (and Python version using Brython). Instead of having only a mini-language, like the original Karel the robot, I want to give the user access to the entire Javascript language. In order to do so, I simply use eval() to evaluate the user program. (*See http://reeborg.ca/learn_js.html for my first version [which will be replaced by the newer version when it is completed] and http://reeborg.ca/learn_js_new_dev.html for a newer version. I'm writing a new version as the original one had a memory leak that made the browser crash.*)

It would be helpful, for enhancing the user experience, if I could keep track of objects/variables that are/have been created by the user script.

One crude way to do this that I can think of would be to pre-processs the script and try to identify any obvious variables (declared with the var keyword, or function) but I was wondering if there was an easy and more reliable way to do so without writing a javascript interpreter. (Perhaps hacking jshint/jslint and run it on the script to identify variables...)

Edit:

Here is the code where I actually do the evaluation. As it is done within a function (and enforcing the use of variable declaration), perhaps this makes it easier to accomplish what I'm hoping to do.

RUR.runner.eval_javascript = function (src) {
// Note: by having "use strict;" here, it has the interesting effect of requiring user
// programs to conform to "strict" usage, meaning that all variables have to be declared,
// etc.
"use strict";  // will propagate to user's code, enforcing good programming habits.
// lint, then eval
editorUpdateHints();
if(editor.widgets.length === 0) {
    libraryUpdateHints();
    if(library.widgets.length !== 0) {
        $('#library-problem').show().fadeOut(4000);
    }
}
RUR.reset_definitions();
eval(src); // jshint ignore:line
};
André
  • 914
  • 1
  • 10
  • 23

4 Answers4

0

Can't think of a simple way to keep track of things if you're using eval without writing something to monitor the var space (maybe there is a way of intergrating with the console).

However, this might help: http://repl.it/languages https://github.com/replit

amay0048
  • 961
  • 9
  • 11
0

"without writing a javascript interpreter"

If you'd consider using someone else's javascript interpreter, have a look at Narcissus.

guest
  • 6,450
  • 30
  • 44
0

The evaled script can access two scopes, that of the function doing the eval and the global object. You could scan all these objects before the script is run, take note of all the variable names and then do the same scan afterwards and the difference is the variables the script introduced.

Jack Allan
  • 14,554
  • 11
  • 45
  • 57
  • How would I do this. I tried to console.log() the variables just before and after the call to eval("var a = 1;") using Object.keys(this) and Object.getOwnPropertyNames(this) and it did not indicate that "a" had been added. "a" was also undefined globally as it was not recognized in the console. – André Apr 05 '14 at 22:49
0

@Jack Allan is correct, you would do something like this:

var windowvars = new Array();
var evalvars = new Array();

for (i in window){
  console.log(i);
  windowvars.push(i);
}

eval('var aaa = 1;');

for (j in window){
  console.log(j);
  if (windowvars.indexOf(j) < 0){
    evalvars.push(j);
  }
}
amay0048
  • 961
  • 9
  • 11
  • I just did that in my code and evalvars is empty: there is no sign that aaa was created. – André Apr 05 '14 at 23:47
  • The execution context seems to be the problem here. The code above works in the terminal, but not in this [fiddle](http://jsfiddle.net/amay0048/QgheP/). My guess is that you will have a tough time [getting all variables in scope](http://stackoverflow.com/questions/2051678/getting-all-variables-in-scope) without using in interpreter. Replit, or [js.js](https://github.com/jterrace/js.js/) might be useful. – amay0048 Apr 06 '14 at 01:12