I am trying to evaluate JavaScript code based on what a user enters into a code editor. I get their code as a single string, use babel to transform it and then split on newlines to get the code by line. I want to see if the current line evaluates to something and if so, print that out. I skip lines that do not evaluate to anything but the problem is if some writes code like the following:
1 | const x = 5;
2 | x
Ideally I would like to print something like:
1 |
2 | 5
The problem though is that I need line 1 to evaluate line two. If I just join the lines of code and evaluate that (something like: const x = 5;\nx;
) it will result in 5;
However, if a line further down does not evaluate to anything, then it will also return 5 but that is not correct because const y = 3;
does not evaluate to 5. So for example the following:
1 | const x = 5;
2 | x
3 | const y = 3;
concatenated (something like: const x = 5;\nx\nconst y = 3;): would result in:
1 | undefined
2 | 5
3 | 5 // PROBLEM: this should also be undefined.
I have tried this solution: Context-preserving eval but it does not answer my question. Moreover, The solution throws an error in the following line when I tried it out:
// 'void (__EVAL = ${__EVAL.toString()});' causes an error
var __EVAL = s => eval(`void (__EVAL = ${__EVAL.toString()}); ${s}`);
I want to evaluate the latest statement in a block of code, given I have the code written before that, but only return a result if the current line evaluates to something. So as one final example, the following code:
1 | const x = 5;
2 | x
3 | const y = 3;
4 |
5 | const add = (a, b) => {
6 | return a + b;
7 | };
8 |
9 | add(x, y);
should give:
1 |
2 | 5
3 |
4 |
5 |
6 |
7 |
8 |
9 | 8