jint icon indicating copy to clipboard operation
jint copied to clipboard

ES6 Generators

Open lahma opened this issue 4 years ago • 16 comments

lahma avatar Jan 03 '21 18:01 lahma

👏

ayende avatar Jan 04 '21 08:01 ayende

Bump? Looking to use generators to represent coroutines and this pr would be extremely helpful

roobscoob avatar Feb 20 '21 00:02 roobscoob

@roobscoob would you want to make contributions to push this forward?

lahma avatar Feb 20 '21 07:02 lahma

I would love to, though I don't think I'm good enough at c# to make meaningful contributions that won't waste people's time fixing.

That said I'll take a look at src and figure out what's left to do. If I can, I'll give it a go

roobscoob avatar Feb 20 '21 08:02 roobscoob

Current status is quite good, some 4500 more passing tests now.

main:

Passed!  - Failed:     0, Passed: 47164, Skipped: 13520, Total: 60684, Duration: 31 s - Jint.Tests.Test262.dll (net6.0)

this branch:

Failed!  - Failed:   490, Passed: 51675, Skipped: 10040, Total: 62205, Duration: 32 s - Jint.Tests.Test262.dll (net6.0)

lahma avatar Jul 06 '22 15:07 lahma

I should disallow force-pushing ;)

sebastienros avatar Oct 24 '22 17:10 sebastienros

That would be quite beautiful commit history indeed...

lahma avatar Oct 24 '22 17:10 lahma

may be splitting this PR into small parts that can be merged improve failing tests score and make possible other guys help with other PRs

cesarchefinho avatar Dec 29 '22 17:12 cesarchefinho

@cesarchefinho would you be contributing?

lahma avatar Dec 29 '22 17:12 lahma

Is this PR still in progress?

scgm0 avatar Dec 20 '23 07:12 scgm0

Is this PR still in progress?

Yes.

lahma avatar Dec 20 '23 07:12 lahma

Are there plans to support yield* (with asterisk)?

ClearCutDevel avatar Mar 06 '24 18:03 ClearCutDevel

Are there plans to support yield* (with asterisk)?

I believe it's this.

lahma avatar Mar 06 '24 18:03 lahma

Granted I may not understand this implementation too well I was wondering about this piece of code in JintStatementList.cs

if (_generator) { if (context.Engine.ExecutionContext.Suspended) { _index = i + 1; c = new Completion(CompletionType.Return, c.Value, pair.Statement._statement); break; } }

Unlike normal yield, yield* should not just skip to the next statement (_index = i + 1) if its source iterator / generator isn't yet finished. If I misunderstand it please explain why this expression is actually correct for delegating yield.

ClearCutDevel avatar Mar 08 '24 10:03 ClearCutDevel

Yes as you can see the tests aren't passing yet and this in a draft PR, it isn't fully working.

lahma avatar Mar 08 '24 13:03 lahma

I also tried a few more tests below:


    public void ForLoopYield()
    {
        // https://jsfiddle.net/rbwht2ve/3/

        const string Script = """
          const foo = function*() {
            for(var i = 0; i < 5; yield i++) {}
          };

          let str = '';
          for (const val of foo()) {
            str += val;
          }
          return str;
      """;

        var engine = new Engine();

        Assert.Equal("01234", engine.Evaluate(Script));
    }

    [Fact]
    public void DelegateYield()
    {
        // https://jsfiddle.net/164sp2Ld/

        const string Script = """
          function* bar() {
              yield 'a';
              yield 'b';
          }

          function* foo() {
              yield 'x';
              yield* bar(); // Delegating yield to bar
              yield 'y';
          }

          let str = '';
          for (const val of foo()) {
            str += val;
          }
          return str;
      """;

        var engine = new Engine();

        Assert.Equal("xaby", engine.Evaluate(Script));
    }

This would require modifying several *Statement.cs files including For, While, DoWhile, or even Switch. ExecutionContext may also need to accommodate for those changes.

I'm not sure how you would modify the JintForStatement to accommodate for yield in any of the three statements (init; condition; update) (also see my test above) but if you can get it started I can follow your example and implement it in While; DoWhile; Switch and wherever else it could be used.

ClearCutDevel avatar Mar 17 '24 15:03 ClearCutDevel