diff --git a/README.md b/README.md index 9d4902fc83..4e5a45e1fa 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,5 @@ Deviates from [acorn](https://github.com/marijnh/acorn) in the following ways: * JSX support via [acorn-jsx](https://github.com/RReverser/acorn-jsx) * [ES7 Abstract references](https://github.com/zenparsing/es-abstract-refs) * [ES7 Async/await](https://github.com/lukehoban/ecmascript-asyncawait) - * [ES7 Object Rest/Spread](https://github.com/sebmarkbage/ecmascript-rest-spread) + * [ES7 Exponentiation operator](https://github.com/rwaldron/exponentiation-operator) + * [ES7 Object rest/spread](https://github.com/sebmarkbage/ecmascript-rest-spread) diff --git a/acorn.js b/acorn.js index 911bb7c356..19bf0b0b08 100644 --- a/acorn.js +++ b/acorn.js @@ -462,6 +462,7 @@ // '*' may be multiply or have special meaning in ES6 var _star = {binop: 10, beforeExpr: true}; + var _exponent = {binop: 10, beforeExpr: true}; // '<', '>' may be relational or have special meaning in JSX var _lt = {binop: 7, beforeExpr: true}, _gt = {binop: 7, beforeExpr: true}; @@ -475,7 +476,7 @@ name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string, arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL, star: _star, assign: _assign, xjsName: _xjsName, xjsText: _xjsText, - doubleColon: _doubleColon}; + doubleColon: _doubleColon, exponent: _exponent}; for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw]; // This is a trick taken from Esprima. It turns out that, on @@ -751,10 +752,29 @@ return finishOp(_slash, 1); } - function readToken_mult_modulo(code) { // '%*' + function readToken_modulo() { // '%' var next = input.charCodeAt(tokPos + 1); if (next === 61) return finishOp(_assign, 2); - return finishOp(code === 42 ? _star : _modulo, 1); + return finishOp(_modulo, 1); + } + + function readToken_mult() { // '*' + var type = _star; + var width = 1; + var next = input.charCodeAt(tokPos + 1); + + if (options.ecmaVersion >= 7 && next === 42) { // '*' + width++; + next = input.charCodeAt(tokPos + 2); + type = _exponent; + } + + if (next === 61) { // '=' + width++; + type = _assign; + } + + return finishOp(type, width); } function readToken_pipe_amp(code) { // '|&' @@ -907,8 +927,11 @@ case 47: // '/' return readToken_slash(); - case 37: case 42: // '%*' - return readToken_mult_modulo(code); + case 37: // '%' + return readToken_modulo(); + + case 42: // '*' + return readToken_mult(); case 124: case 38: // '|&' return readToken_pipe_amp(code); diff --git a/package.json b/package.json index d125ff7f61..6a707fd72e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "acorn-6to5", "description": "Acorn fork used by 6to5", "main": "acorn.js", - "version": "0.9.1-6", + "version": "0.9.1-7", "maintainers": [ { "name": "Marijn Haverbeke", diff --git a/test/tests-6to5.js b/test/tests-6to5.js index 01691cdf12..6ce7d4f733 100644 --- a/test/tests-6to5.js +++ b/test/tests-6to5.js @@ -4,6 +4,82 @@ if (typeof exports != "undefined") { var testAssert = require("./driver.js").testAssert; } +// ES7: Exponentiation Operator + +test('a **= 2;', { + type: "Program", + start: 0, + end: 8, + body: [{ + type: "ExpressionStatement", + start: 0, + end: 8, + expression: { + type: "AssignmentExpression", + start: 0, + end: 7, + operator: "**=", + left: { + type: "Identifier", + start: 0, + end: 1, + name: "a" + }, + right: { + type: "Literal", + start: 6, + end: 7, + value: 2 + } + } + }] +}, { + ecmaVersion: 7 +}); + +test('var squared = 2 ** 2;', { + type: "Program", + start: 0, + end: 21, + body: [{ + type: "VariableDeclaration", + start: 0, + end: 21, + declarations: [{ + type: "VariableDeclarator", + start: 4, + end: 20, + id: { + type: "Identifier", + start: 4, + end: 11, + name: "squared" + }, + init: { + type: "BinaryExpression", + start: 14, + end: 20, + left: { + type: "Literal", + start: 14, + end: 15, + value: 2 + }, + operator: "**", + right: { + type: "Literal", + start: 19, + end: 20, + value: 2 + } + } + }], + kind: "var" + }] +}, { + ecmaVersion: 7 +}); + // ES7: Object Rest/Spread test('let {...x} = z', {