Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for defer parsing lambda functions #4105

Merged
merged 3 commits into from
Nov 2, 2017

Conversation

boingoing
Copy link
Contributor

Fix up the parser to enable the defer parse methods to handle lambda functions. All lambdas are allowed to be deferred, even lambdas with compact parameter lists or function bodies.

Should also allow lambda functions to be redeferred, which is really the main reason to do this work.

One of the related changes is in Parser::Parse. I changed this function to skip calling ParseStmtList in the case where we are defer parsing a single function. In these cases we know that we are going to parse a function so we don't need to start parsing a set of statements, then one statement, then one expression, then one terminal, etc until we finally start parsing the function via ParseFncDecl. Instead we can just jump directly to ParseFncDecl after setting up the correct flags. By doing this, we can avoid reparsing the lambda parameter list (because we never assume it will be an ordinary expression list) which saves us the headache of bookkeeping the block and function ids.

One other change of note is in ScopeInfo::SaveSymbolInfo. We now need to save symbol info for the arguments symbol since a lambda may be deferred in a function and lambdas capture the arguments value from their parent. I suppose we could move the arguments default binding into a regular special symbol at some point in the future.

Fix up the parser to enable the defer parse methods to handle lambda functions. All lambdas are allowed to be deferred, even lambdas with compact parameter lists or function bodies.

Should also allow lambda functions to be redeferred, which is really the main reason to do this work.

One of the related changes is in `Parser::Parse`. I changed this function to skip calling `ParseStmtList` in the case where we are defer parsing a single function. In these cases we know that we are going to parse a function so we don't need to start parsing a set of statements, then one statement, then one expression, then one terminal, etc until we finally start parsing the function via `ParseFncDecl`. Instead we can just jump directly to `ParseFncDecl` after setting up the correct flags. By doing this, we can avoid reparsing the lambda parameter list (because we never assume it will be an ordinary expression list) which saves us the headache of bookkeeping the block and function ids.

One other change of note is in `ScopeInfo::SaveSymbolInfo`. We now need to save symbol info for the `arguments` symbol since a lambda may be deferred in a function and lambdas capture the `arguments` value from their parent. I suppose we could move the `arguments` default binding into a regular special symbol at some point in the future.
BOOL FuncInfo::IsLambda() const
{
return root->sxFnc.IsLambda();
BOOL FuncInfo::IsLambda() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (sorry), please keep curly style consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, some style crept-in from JavaScript. I'll clean this one.

@@ -1695,10 +1693,11 @@ ParseNodePtr Parser::CreateSpecialVarDeclIfNeeded(ParseNodePtr pnodeFnc, IdentPt
return nullptr;
}

template<bool buildAST>
void Parser::CreateSpecialSymbolDeclarations(ParseNodePtr pnodeFnc, bool isGlobal)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that in a deferred function we still need to do binding (for all symbols) so that pid ref stacks can be popped, and bindings to symbols in outer functions will be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good point. I'll rollback the change to this.

@boingoing
Copy link
Contributor Author

Thank you, @pleath

@chakrabot chakrabot merged commit f47ec32 into chakra-core:release/1.7 Nov 2, 2017
chakrabot pushed a commit that referenced this pull request Nov 2, 2017
Merge pull request #4105 from boingoing:DeferParseLambda_3

Fix up the parser to enable the defer parse methods to handle lambda functions. All lambdas are allowed to be deferred, even lambdas with compact parameter lists or function bodies.

Should also allow lambda functions to be redeferred, which is really the main reason to do this work.

One of the related changes is in `Parser::Parse`. I changed this function to skip calling `ParseStmtList` in the case where we are defer parsing a single function. In these cases we know that we are going to parse a function so we don't need to start parsing a set of statements, then one statement, then one expression, then one terminal, etc until we finally start parsing the function via `ParseFncDecl`. Instead we can just jump directly to `ParseFncDecl` after setting up the correct flags. By doing this, we can avoid reparsing the lambda parameter list (because we never assume it will be an ordinary expression list) which saves us the headache of bookkeeping the block and function ids.

One other change of note is in `ScopeInfo::SaveSymbolInfo`. We now need to save symbol info for the `arguments` symbol since a lambda may be deferred in a function and lambdas capture the `arguments` value from their parent. I suppose we could move the `arguments` default binding into a regular special symbol at some point in the future.
chakrabot pushed a commit that referenced this pull request Nov 2, 2017
…a functions

Merge pull request #4105 from boingoing:DeferParseLambda_3

Fix up the parser to enable the defer parse methods to handle lambda functions. All lambdas are allowed to be deferred, even lambdas with compact parameter lists or function bodies.

Should also allow lambda functions to be redeferred, which is really the main reason to do this work.

One of the related changes is in `Parser::Parse`. I changed this function to skip calling `ParseStmtList` in the case where we are defer parsing a single function. In these cases we know that we are going to parse a function so we don't need to start parsing a set of statements, then one statement, then one expression, then one terminal, etc until we finally start parsing the function via `ParseFncDecl`. Instead we can just jump directly to `ParseFncDecl` after setting up the correct flags. By doing this, we can avoid reparsing the lambda parameter list (because we never assume it will be an ordinary expression list) which saves us the headache of bookkeeping the block and function ids.

One other change of note is in `ScopeInfo::SaveSymbolInfo`. We now need to save symbol info for the `arguments` symbol since a lambda may be deferred in a function and lambdas capture the `arguments` value from their parent. I suppose we could move the `arguments` default binding into a regular special symbol at some point in the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants