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

Function in while loop #47

Closed
philipnilsson opened this issue Oct 26, 2013 · 18 comments
Closed

Function in while loop #47

philipnilsson opened this issue Oct 26, 2013 · 18 comments

Comments

@philipnilsson
Copy link

This test case:
while (0) function n() { }

How does the standard say we should parse this? At first I thought it'd be

Statement -> ExpressionStatment -> Expression -> FunctionExpression

the problem is ExpressionStatement has lookahead </- { '{', 'function' }, so how do you arrive at a parse for this?

@achudnov
Copy link
Member

Indeed, ExpressionStatement expects not to have a function keyword at the beginning. My best guess is that it's designed that way to disambiguate function expressions (in an expression statement) and function declarations (function statements in our case).

@michaelficarra
Copy link

It's not a valid program. IterationStatement includes

while ( Expression ) Statement

Statement is defined as one of Block, VariableStatement, EmptyStatement, ExpressionStatement, IfStatement, IterationStatement, ContinueStatement, BreakStatement, ReturnStatement, WithStatement, LabelledStatement, SwitchStatement, ThrowStatement, TryStatement, DebuggerStatement. And as you point out, ExpressionStatement can't ever be a FunctionExpression because it can't begin with function. So this is not a valid program. Also, take note of the NOTE in section 12:

NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

@achudnov
Copy link
Member

Yeah, I'm aware of that, Michael. Function statements is the most widely implemented extension to the standard, that's why historically this package included them in the AST. By the way, do you know what are the "irreconcilable variations among the implementations" that the standard speaks about?

@michaelficarra
Copy link

Yep. A bunch of implementations will accept these programs, with various differences in semantics:

if(0) { function a() { } }
a();
if(1) { function a() { } }
a();
{ function a() { } }
a();
if(0) { function a() { return 0 } } else { function a() { return 1; } }
console.log(a());

@philipnilsson
Copy link
Author

So what action do we take on this? Should be follow the standard? If not, how to we modify the grammar? Add functionDeclaration to parseStatement?

@michaelficarra
Copy link

@philipnilsson: That appears to be the choice we have to make. I'd opt for strict parsing.

@philipnilsson
Copy link
Author

@michaelficarra I agree @achudnov what's your take?

@achudnov
Copy link
Member

@michaelficarra, @philipnilsson: I have said it before that I intend for the library to be standards compliant, and I'll stand by it. However, I'm also under the impression --perhaps mistaken-- that function statements is a widely implemented and relied-upon extension of the standard. My interest in using the library is parsing ECMAScript "in-the-wild", particularly as found in web applications. By any chance, does any of you know if function statements are commonly used in JavaScript as found in web applications?

@philipnilsson
Copy link
Author

I'd say we close this until we have a compelling reason to support it, or we find people run into trouble due to this restriction. I guess a good test case is parsing some larger open source code bases. If we end up failing due to this, we could introduce a workaround.

@achudnov
Copy link
Member

@michaelficarra: in the examples you have mentioned earlier, what are the differences in the semantics?

@philipnilsson: just to clarify, do you mean modifying the AST and the parser to strictly adhere to the standard? Meaning no function statements (but have top level function declarations). If so, I'd support that. Then we could also test it on, say, 10 popular JavaScript libraries and see if the the es5 branch can parse all of them correctly. The other solution I would support is supporting parsing function statements, but issuing a warning (which is one of the approaches recommended by the spec). That, however, requires implementing #42 .

@achudnov achudnov added this to the ECMAScript 5 support milestone Feb 28, 2014
@achudnov
Copy link
Member

achudnov commented May 3, 2014

This requires refactoring of the AST and the parser to adhere to the spec. FunctionStmt should be a FunctionDecl, and be only present at the top level. Can we enforce this at the data-type level? Something like

data Decl a = Stmt (Statement a)
            | FunctionDecl a (Id a) [Id a] [Statement a]
data Program a = Program a [Decl a]

@michaelficarra
Copy link

Not quite. More like

data Decl a = Stmt (Statement a)
            | FunctionDecl a (Id a) [Id a] [Decl a]
data Program a = Program a [Decl a]
-- ... some time later ...
data FunctionExpression a = FunctionExpression a (Maybe (Id a)) [Id a] [Decl a]

FunctionDeclarations can exist at program level and in function bodies.

@achudnov
Copy link
Member

achudnov commented May 5, 2014

I can't see why function expressions need to be a separate datatype,
Michael. Also, was that a typo?

|FunctionDeclaration|s can exist at program level and in function
bodies.

@michaelficarra
Copy link

Yeah, they don't need to be. I was just trying to illustrate that function expressions and function declarations would both need to contain a list of Decl, representing the statements in their body.

No typos, though. Not sure what you were referring to as a possible typo.

@achudnov
Copy link
Member

achudnov commented May 5, 2014

I was referring to this:

FunctionDeclarations can exist at program level and in function bodies.

According to the spec, FunctionDeclarations cannot exist at the function level (that's what you also said 6 months ago).

@michaelficarra
Copy link

No, I don't see where I said that. They cannot exist within arbitrary blocks, such as if(a){ function b(){} }, or in arbitrary statement position, such as while(a) function b(){}. But they are allowed at program level (function a(){}) and directly within function -- expression or declaration -- bodies (f(function(){ function a(){} })). Does that make sense?

@achudnov
Copy link
Member

achudnov commented May 6, 2014

Yes, it does, and you are right. It looks like the solution is going to be a bit more complex: the function declarations and expressions are going to hold [Decl a] instead of [Statement a]. Thank you, Michael.

@achudnov
Copy link
Member

achudnov commented Dec 1, 2015

Having a fresh look, this test case is invalid, as Michael implied.

@achudnov achudnov closed this as completed Dec 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants