Skip to content Skip to sidebar Skip to footer

JavaScript: Do All Evaluations In One Vm

I'm creating a custom JavaScript console that I expect to work exactly like the console in dev tools. (or … something like a REPL) https://github.com/MohammadMD1383/js-interactiv

Solution 1:

You can use a generator function and "feed" expressions to it as they come in. Since the generator retains its context, all variables from previous lines will be there when you evaluate the next one:

function* VM(expr) {
    while (1) {
        try {
            expr = yield eval(expr || '')
        } catch(err) {
            expr = yield err
        }
    }
}


vm = VM()
vm.next()

function evaluate(line) {
    let result = vm.next(line).value
    if (result instanceof Error)
        console.log(line, 'ERROR', result.message)
    else
        console.log(line, 'result', result)
}

evaluate('var a = 55')
evaluate('a')
evaluate('var b = 5')
evaluate('c = a + b')
evaluate('foobar--')
evaluate('c++')
evaluate('[a, b, c]')

As suggested in another thread, a "self-similar" eval will also preserve block-scoping variables:

let _EVAL = e => eval(`_EVAL=${_EVAL}; undefined; ${e}`)

function evaluate(line) {
    try {
      let result = _EVAL(line)
      console.log(line, '==>', result)
    } catch (err) {
        console.log(line, '==>', 'ERROR', err.message)
    }
}

evaluate('var a = 55')
evaluate('a')
evaluate('foobar--')
evaluate('let x = 10')
evaluate('const y = 20')
evaluate('[a, x, y]')

Post a Comment for "JavaScript: Do All Evaluations In One Vm"