rusty-ecma / RESSA

Rusty EcmaScript Syntax Analyzer
MIT License
111 stars 14 forks source link

ES2020 Operators support #92

Open Fee0 opened 7 months ago

Fee0 commented 7 months ago

I would like to have support for the operators coming with ES2020 (https://www.w3schools.com/jS/js_2020.asp):

Any hints how to implement them are very welcome. I probably start with the Logical AND / OR as these seem more simple to me.

FreeMasen commented 7 months ago

I good place to start would be to add these punctuation marks to ress. This enum would need new variants, and then the tokenizer would need to be updated to parse these new tokens. This method is the starting point for parsing the new operators.

Once that is done, an update to resast would need to be made to account for the new tokens, all but ?. and ?? should be pretty trivial to update since they should just be part of binary assignment, this enum is a good place to start for that.

For ?. changes will need to be made to the MemberExpr to account for the new indexer.

for ?? I believe it would end up being an update of the BinaryExpression

Once those are in place, then ressa can be updated to handle these new tokens/generate the new AST.

FreeMasen commented 6 months ago

Most of this is now in place, however I am still trying to figure out how to integrate the optional chain.

Fee0 commented 6 months ago

awesome @FreeMasen ! What are your doubts about optional chaining? Can we get some inspiration from other projects for this? E.g. https://github.com/swc-project/swc/blob/c4230373e4379edbadf2aa0a5381bf18b1746bb9/crates/swc_ecma_compat_es2022/src/optional_chaining_impl.rs ?

FreeMasen commented 6 months ago

I would say that the primary issue I have is that the usage is pretty inconsistent. For example

a?.b
a?.['b']
a?.()

In these three expressions, the first completely replaces the index operator, while the second is a duplicate indexer and the last one is entirely new syntax for the call expression.

So, coming up with a decent way to represent this as a single Expr variant is complicated.

Looking at the SWC implementation they are using a Vec to capture the identifiers which would be fully its own expression. This might be something that can be used here but I think the semantics of our usage are going to need some kind of modification.

It might make sense to have an Expr::Optional { expr: Box<Self>, op: QuestionmarkDot } and also a MemberIndexer::Optional(QuestionmarkDot) and then require the parser/AST consumer to handle each case individually

Fee0 commented 6 months ago

uh agree this operator can be thrown into many places which makes it difficult to represent as Expr. Makes sense to handle it individually then. For the function call we just add Option<QuestionmarkDot> to CallExpr

Fee0 commented 5 months ago

Made a try to finish the optional chaining:

What do you think?

FreeMasen commented 5 months ago

I think what you have looks very good!