diff --git a/bin/acorn b/bin/acorn index 506cdc4365..f70fe21ee6 100755 --- a/bin/acorn +++ b/bin/acorn @@ -4,28 +4,42 @@ var path = require("path"); var fs = require("fs"); var acorn = require("../acorn.js"); -var infile, parsed, options = {}, silent = false, compact = false; +var infile, infilecount = 0; +var options = {}, silent = false, compact = false; +var parsed; function help(status) { - console.log("usage: " + path.basename(process.argv[1]) + " infile [--ecma3|--ecma5] [--strictSemicolons]"); - console.log(" [--locations] [--compact] [--silent] [--help]"); + // we want to print to stderr, not stdout, on errors. + var print = (status == 0) ? console.out : console.err; + print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5] [--strictSemicolons]"); + print(" [--locations] [--compact] [--silent] [--help] [--] infile"); process.exit(status); } for (var i = 2; i < process.argv.length; ++i) { var arg = process.argv[i]; - if (arg == "--ecma3") options.ecmaVersion = 3; + if (arg[0] != "-") { + infile = arg; + ++infilecount; + continue; + } else if (arg == "--") { + if (i < process.argv.length - 2) help(1); // we have too many remaining `infile`s + infile = process.argv[i + 1]; // we want the *next* argument, not the current one + ++infilecount; + break; + } + else if (arg == "--ecma3") options.ecmaVersion = 3; else if (arg == "--ecma5") options.ecmaVersion = 5; else if (arg == "--strictSemicolons") options.strictSemicolons = true; else if (arg == "--locations") options.locations = true; else if (arg == "--silent") silent = true; else if (arg == "--compact") compact = true; else if (arg == "--help") help(0); - else if (arg[0] == "-") help(1); - else infile = arg; + else help(1); // we already took care of all arguments without a starting dash } -if (!infile) help(1); +// test against counter: we want exactly 1 file. Any more or less should error. +if (infilecount !== 1) help(1); try { var code = fs.readFileSync(infile, "utf8"); diff --git a/index.html b/index.html index 0e2d6e6361..f336e3c3af 100644 --- a/index.html +++ b/index.html @@ -188,7 +188,7 @@ we assign a variable name to it for quick comparing.
"delete": {keyword: "delete", prefix: true, beforeExpr: true}};Punctuation token types. Again, the type property is purely for debugging.
var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
- var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};Operators. These carry several kinds of properties to help the + var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _ellipsis = {type: "..."}, _question = {type: "?", beforeExpr: true};
Operators. These carry several kinds of properties to help the parser use them properly (the presence of these properties is what categorizes them as operators).
@@ -217,8 +217,8 @@ in AssignmentExpression nodes.Provide access to the token types for external users of the tokenizer.
exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,
parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
- dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof,
- num: _num, regexp: _regexp, string: _string};
+ dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
+ name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string};
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];This is a trick taken from Esprima. It turns out that, on
non-Chrome browsers, to check whether a string is in a set, a
predicate containing a big ugly switch statement is faster than
@@ -376,8 +376,14 @@ into it.
tokRegexpAllowed trick does not work. See parseStatement. function readToken_dot() {
var next = input.charCodeAt(tokPos + 1);
if (next >= 48 && next <= 57) return readNumber(true);
- ++tokPos;
- return finishToken(_dot);
+ var next2 = input.charCodeAt(tokPos + 2);
+ if (options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
+ tokPos += 3;
+ return finishToken(_ellipsis);
+ } else {
+ ++tokPos;
+ return finishToken(_dot);
+ }
}
function readToken_slash() { // '/'
@@ -448,7 +454,7 @@ into it.
function getTokenFromCode(code) {
switch(code) {The interpretation of a dot depends on whether it is followed -by a digit.
case 46: // '.'
+by a digit or another two dots. case 46: // '.'
return readToken_dot();Punctuation tokens.
case 40: ++tokPos; return finishToken(_parenL);
case 41: ++tokPos; return finishToken(_parenR);
case 59: ++tokPos; return finishToken(_semi);
@@ -1280,11 +1286,22 @@ init properties are also not allowed to be repeated. 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 = [];