mozilla-spidermonkey / jsparagus

Experimental JS parser-generator project.
Other
439 stars 20 forks source link

Support `yield` and `await` as identifiers #79

Open jorendorff opened 4 years ago

jorendorff commented 4 years ago

await is a valid Identifier except in async functions. yield is a valid Identifier except in generators and strict mode code.

For example, js/src/tests/non262/generators/syntax.js contains this gem:

// In classic mode, yield is a normal identifier, outside of generators.
function yield(yield) { yield: yield (yield + yield (0)); }

The spec grammar handles this by conditionally including yield and await in several Identifier productions. I remember thinking it would be better to flip a lexer switch when we enter a generator or async function. I'm less sure now.

codehag commented 4 years ago

I am trying this one

nbp commented 4 years ago

I think this would be easier once #48 is fixed. I will recommend waiting for handling this one before as this might be harder than expected.

codehag commented 4 years ago

thanks for pointing that out. Might make sense to wait. I am stuck on the IdentifierReference. I broke down the codesnippit above into the following parts:

{ yield: yield } and (yield + yield)

For the first one, {yield: yield} it looks like it just needed a line added to LabelIdentifier. I now have the following ast spit out:

Script(
    Script {
        directives: [],
        statements: [
            BlockStatement {
                block: Block {
                    statements: [
                        LabeledStatement {
                            label: Label {
                                value: "yield",
                                loc: SourceLocation {
                                    start: 1,
                                    end: 6,
                                },
                            },
                            body: ExpressionStatement(
                                YieldExpression {
                                    expression: None,
                                    loc: SourceLocation {
                                        start: 8,
                                        end: 13,
                                    },
                                },
                            ),
                            loc: SourceLocation {
                                start: 1,
                                end: 13,
                            },
                        },
                    ],
                    declarations: None,
                    loc: SourceLocation {
                        start: 0,
                        end: 14,
                    },
                },
                loc: SourceLocation {
                    start: 0,
                    end: 14,
                },
            },
        ],
        loc: SourceLocation {
            start: 0,
            end: 14,
        },
    },
)
Err(
    NotImplemented(
        "TODO: BlockStatement",
    ),
)

But the second yield is still a YieldExpression. I am not sure how to make yield; unambiguous. That is what I am stuck on now.

Does it make sense to do the partial fix?

codehag commented 4 years ago

I will remove myself for now until we address the issue @nbp mentioned

nbp commented 4 years ago

This issue should be fixed by #359