Added yield support (completed generators).

This commit is contained in:
Ingvar Stepanyan 2014-07-26 06:09:29 +03:00 committed by Marijn Haverbeke
parent b8a3300a21
commit 8f96965d36
2 changed files with 55 additions and 40 deletions

View File

@ -220,11 +220,12 @@
var lastStart, lastEnd, lastEndLoc;
// This is the parser's state. `inFunction` is used to reject
// `return` statements outside of functions, `labels` to verify that
// `break` and `continue` have somewhere to jump to, and `strict`
// indicates whether strict mode is on.
// `return` statements outside of functions, `inGenerator` to
// reject `yield`s outside of generators, `labels` to verify
// that `break` and `continue` have somewhere to jump to, and
// `strict` indicates whether strict mode is on.
var inFunction, labels, strict;
var inFunction, inGenerator, labels, strict;
// This counter is used for checking that arrow expressions did
// not contain nested parentheses in argument list.
@ -294,6 +295,7 @@
var _this = {keyword: "this"};
var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true}, _static = {keyword: "static"};
var _export = {keyword: "export"}, _import = {keyword: "import"}, _from = {keyword: "from"}, _as = {keyword: "as"};
var _yield = {keyword: "yield", beforeExpr: true};
// The keywords that denote values.
@ -321,7 +323,7 @@
"void": {keyword: "void", prefix: true, beforeExpr: true},
"delete": {keyword: "delete", prefix: true, beforeExpr: true},
"class": _class, "extends": _extends, "static": _static, "of": _of,
"export": _export, "import": _import, "from": _from, "as": _as};
"export": _export, "import": _import, "from": _from, "as": _as, "yield": _yield};
// Punctuation token types. Again, the `type` property is purely for debugging.
@ -441,7 +443,7 @@
var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends static of export import from as");
var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends static of export import from as yield");
var isKeyword = isEcma5AndLessKeyword;
@ -1247,7 +1249,7 @@
function parseTopLevel(program) {
lastStart = lastEnd = tokPos;
if (options.locations) lastEndLoc = new Position;
inFunction = strict = null;
inFunction = inGenerator = strict = null;
labels = [];
readToken();
@ -1855,6 +1857,9 @@
case _bquote:
return parseTemplate();
case _yield:
return inGenerator ? parseYield() : parseIdent(true);
default:
unexpected();
}
@ -2119,11 +2124,11 @@
} else {
// Start a new scope with regard to labels and the `inFunction`
// flag (restore them to their old value afterwards).
var oldInFunc = inFunction, oldLabels = labels;
inFunction = true; labels = [];
var oldInFunc = inFunction, oldInGen = inGenerator, oldLabels = labels;
inFunction = true; inGenerator = node.generator; labels = [];
node.body = parseBlock(true);
node.expression = false;
inFunction = oldInFunc; labels = oldLabels;
inFunction = oldInFunc; inGenerator = oldInGen; labels = oldLabels;
}
// If this is a strict mode function, verify that argument names
@ -2410,4 +2415,14 @@
return nodes;
}
// Parses yield expression inside generator.
function parseYield() {
var node = startNode();
next();
node.delegate = parseIsGenerator();
node.argument = parseExpression(true);
return finishNode(node, "YieldExpression");
}
});

View File

@ -5933,10 +5933,10 @@ test("(function* () { yield v })", {
end: {line: 1, column: 23}
}
},
range: [16, 24],
range: [16, 23],
loc: {
start: {line: 1, column: 16},
end: {line: 1, column: 24}
end: {line: 1, column: 23}
}
}],
range: [14, 25],
@ -5948,10 +5948,10 @@ test("(function* () { yield v })", {
rest: null,
generator: true,
expression: false,
range: [1, 25],
range: [0, 26],
loc: {
start: {line: 1, column: 1},
end: {line: 1, column: 25}
start: {line: 1, column: 0},
end: {line: 1, column: 26}
}
},
range: [0, 26],
@ -6002,10 +6002,10 @@ test("(function* () { yield *v })", {
end: {line: 1, column: 24}
}
},
range: [16, 25],
range: [16, 24],
loc: {
start: {line: 1, column: 16},
end: {line: 1, column: 25}
end: {line: 1, column: 24}
}
}],
range: [14, 26],
@ -6017,10 +6017,10 @@ test("(function* () { yield *v })", {
rest: null,
generator: true,
expression: false,
range: [1, 26],
range: [0, 27],
loc: {
start: {line: 1, column: 1},
end: {line: 1, column: 26}
start: {line: 1, column: 0},
end: {line: 1, column: 27}
}
},
range: [0, 27],
@ -6077,10 +6077,10 @@ test("function* test () { yield *v }", {
end: {line: 1, column: 28}
}
},
range: [20, 29],
range: [20, 28],
loc: {
start: {line: 1, column: 20},
end: {line: 1, column: 29}
end: {line: 1, column: 28}
}
}],
range: [18, 30],
@ -6164,10 +6164,10 @@ test("var x = { *test () { yield *v } };", {
end: {line: 1, column: 29}
}
},
range: [21, 30],
range: [21, 29],
loc: {
start: {line: 1, column: 21},
end: {line: 1, column: 30}
end: {line: 1, column: 29}
}
}],
range: [19, 31],
@ -6179,9 +6179,9 @@ test("var x = { *test () { yield *v } };", {
rest: null,
generator: true,
expression: false,
range: [19, 31],
range: [16, 31],
loc: {
start: {line: 1, column: 19},
start: {line: 1, column: 16},
end: {line: 1, column: 31}
}
},
@ -6310,10 +6310,10 @@ test("(function* () { yield yield 10 })", {
end: {line: 1, column: 30}
}
},
range: [16, 31],
range: [16, 30],
loc: {
start: {line: 1, column: 16},
end: {line: 1, column: 31}
end: {line: 1, column: 30}
}
}],
range: [14, 32],
@ -6325,10 +6325,10 @@ test("(function* () { yield yield 10 })", {
rest: null,
generator: true,
expression: false,
range: [1, 32],
range: [0, 33],
loc: {
start: {line: 1, column: 1},
end: {line: 1, column: 32}
start: {line: 1, column: 0},
end: {line: 1, column: 33}
}
},
range: [0, 33],
@ -7619,9 +7619,9 @@ test("class A {*gen(v) { yield v; }}", {
rest: null,
generator: true,
expression: false,
range: [17, 29],
range: [13, 29],
loc: {
start: {line: 1, column: 17},
start: {line: 1, column: 13},
end: {line: 1, column: 29}
}
},
@ -7733,9 +7733,9 @@ test("class A { static *gen(v) { yield v; }}", {
rest: null,
generator: true,
expression: false,
range: [25, 37],
range: [21, 37],
loc: {
start: {line: 1, column: 25},
start: {line: 1, column: 21},
end: {line: 1, column: 37}
}
},
@ -9887,9 +9887,9 @@ test("var x = {*[test]() { yield *v; }}", {
rest: null,
generator: true,
expression: false,
range: [19, 32],
range: [16, 32],
loc: {
start: {line: 1, column: 19},
start: {line: 1, column: 16},
end: {line: 1, column: 32}
}
},
@ -14653,7 +14653,7 @@ test("e => yield* 10", {
locations: true
});
testFail("(function () { yield 10 })", "Unexpected token (1:22)", {ecmaVersion: 6});
testFail("(function () { yield 10 })", "Unexpected token (1:21)", {ecmaVersion: 6});
test("(function () { yield* 10 })", {
type: "Program",
@ -14736,9 +14736,9 @@ test("(function () { yield* 10 })", {
testFail("(function() { \"use strict\"; f(yield v) })", "Unexpected token (1:36)", {ecmaVersion: 6});
testFail("var obj = { *test** }", "Unexpected token (1:18)", {ecmaVersion: 6});
testFail("var obj = { *test** }", "Unexpected token (1:17)", {ecmaVersion: 6});
testFail("class A extends yield B { }", "Unexpected token (1:23)", {ecmaVersion: 6});
testFail("class A extends yield B { }", "Unexpected token (1:22)", {ecmaVersion: 6});
testFail("class default", "Unexpected token (1:6)", {ecmaVersion: 6});