Since RobG already explained the cause of the problem, I'll limit this answer to a possible workaround.
If you do not mind polluting the global scope (maybe that's even desired here?), you can use an indirect eval
call to force all the expressions to be evaluated globally:
var repl = function(result) {
return {
result:
result,
then:
function (expression, continuation) {
return continuation((1,eval)(expression));
},
};
}
You could also call repl
instead of continuation, so you don't need to pass it to then
every time:
var repl = function(result) {
return {
result:
result,
then:
function (expression) {
return repl((1,eval)(expression));
},
};
}
repl(eval('var x = 1')).then('var y = 2')
.then('y')
.result
The solution Pitarou accepted was hidden in a jsFiddle in a comment to this answer. For reference, here's a slightly modified version of the "ugly hack" solution (which evals the source code of the function to create a closure):
function make_repl() {
return {
result: undefined,
then: function (expression) {
return {
result: eval(expression),
then: eval('('+this.then.toString()+')'),
};
},
};
};
var repl = make_repl();
repl = repl.then('var x = 1').then('var y = 2').then('x + " " + y');
console.log(repl.result); // prints "1 2"
console.log(typeof(x), typeof(y));
// prints "undefined undefined", so we know the global scope was not touched