jint
jint copied to clipboard
ES6 Generators
👏
Bump? Looking to use generators to represent coroutines and this pr would be extremely helpful
@roobscoob would you want to make contributions to push this forward?
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
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)
I should disallow force-pushing ;)
That would be quite beautiful commit history indeed...
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 would you be contributing?
Is this PR still in progress?
Is this PR still in progress?
Yes.
Are there plans to support yield* (with asterisk)?
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.
Yes as you can see the tests aren't passing yet and this in a draft PR, it isn't fully working.
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.