abelljs/abell-renderer

Farewell to Acorn.

Closed this issue · 1 comments

One of the most uncomfortable things right now for me is the existence of acorn in the renderer.

Literally, the only place where acorn is used to is to generate something what we call a statementTypeMap https://github.com/abelljs/abell-renderer/blob/main/src/compiler.js#L38

Statement Type Map is an array of the types of statements we have in the code. This is eventually used to determine if the last statement is an assignment or expression.

E.g.

const a = 3;
a + b;
b = 9;

Will output-

['VariableDeclaration', 'ExpressionStatement', 'AssignmentExpression']

Why?

JavaScript returns the value when you assign. So if you run a = 3 in console, it will return 3, And so does only writing 3, And so does writing 2 + 1.

And in vm module, we only get what the code outputs.

But hey, how do we know if it is 3 coming from assignment or 3 coming from expression? We use the statement type maps!

So when it is an assignment, we don't return a value and thus printing a blank string.

Why acorn is a problem?

Using a whole frikin JavaScript parser just to tell if the code has assignment in the end is an overkill!

Solution

Probably write a custom tokenizer so instead of doing the whole parsing, we can just tokenize and figure out the statement type map from tokens.

Performance Improvements-

Whole parsing takes around 27ms for 3 lines of js code. Whereas tokenizing can take 10ms. This difference will be much larger for larger scripts.

I just did the performance check and apparently the 27ms are just for the initial parsing but after that every other parsing happens in around 2-3ms so even moving away from acorn won't have much of the performance boost. I think this is something that we can tackle later in the future when saving few ms are important to performance.