NeilFraser / JS-Interpreter

A sandboxed JavaScript interpreter in JavaScript.
Apache License 2.0
1.96k stars 352 forks source link

Highlight/Select the line of code while executing #239

Closed pravishanth closed 1 year ago

pravishanth commented 1 year ago

Hi,

I would like the interpreter to highlight the line of code being executing, can you please advise how I can achieve this?

Here is a sample video showing what I am talking about. https://imgur.com/a/tNrBoV6

cpcallen commented 1 year ago

Hi @pravishanth,

If you have var myInterpreter = new Interprerter(/* ... */), and you have loaded some code in (via the contructor or via .appendCode(), you can use myInterpreter.stateStack[myInterpreter.stateStack.length - 1].node.start and myInterpreter.stateStack[myInterpreter.stateStack.length - 1].node.end to find the start and end indexes of the code currently being executed, as offsets into the string containing the code you fed to the interpreter, and this will be updated each time .step() is called.

Note that this will show you every single step of the interpretation, starting with highlighting the entire program and narrowing down to highlighting individual literals; if you want to do something more like line-by-line highlighting, you can check .node.type and only update the displayed highlight if the node type is a "...Statement" node (e.g. 'IfStatement', 'ExpressionStatement', etc.)

(The node objects in the interpreter are produced by the Acorn parser and follow very closely (but maybe not quite 100%) the Esprima Syntax Tree spec; see that spec for the full list of node types.)

NeilFraser commented 1 year ago

Unfortunately the above answer doesn't work well for a few reasons. One is that "...Statement" is not a complete list of lines, for example VariableDeclaration can sometimes be a line, but not when inside a for loop. Another is that lines will be double-counted as the statement is entered, and again as the statement is exited.

Working on a more complete solution...

NeilFraser commented 1 year ago

I've created a Line Step Demo which demonstrates how to step line-by-line. Basically it uses @cpcallen's approach, but handles all the known edge cases. I'm not confident that it's 100% correct, but any hiccups (such as visiting the same line twice) should be easy to solve once spotted.