From 330084f9939f9492d57df69a9c4719946e6fe199 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 17 Oct 2012 16:33:38 +0200 Subject: [PATCH] Make 'this' a proper keyword --- acorn.js | 17 ++++++++--------- index.html | 19 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/acorn.js b/acorn.js index 3aea6dafa2..0799736e3e 100644 --- a/acorn.js +++ b/acorn.js @@ -212,6 +212,7 @@ var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"}; var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"}; var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true}; + var _this = {keyword: "this"}; // The keywords that denote values. @@ -232,7 +233,7 @@ "function": _function, "if": _if, "return": _return, "switch": _switch, "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with, "null": _null, "true": _true, "false": _false, "new": _new, "in": _in, - "instanceof": {keyword: "instanceof", binop: 7}, + "instanceof": {keyword: "instanceof", binop: 7}, "this": _this, "typeof": {keyword: "typeof", prefix: true}, "void": {keyword: "void", prefix: true}, "delete": {keyword: "delete", prefix: true}}; @@ -335,7 +336,7 @@ // And the keywords. - var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in"); + var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"); // ## Character categories @@ -563,7 +564,6 @@ return finishOp(code === 61 ? _eq : _prefix, 1); case 126: // '~' - if (next === 61) return finishOp(_assign, 2); return finishOp(_prefix, 1); } @@ -1400,13 +1400,12 @@ function parseExprAtom() { switch (tokType) { + case _this: + var node = startNode(); + next(); + return finishNode(node, "ThisExpression"); case _name: - if (tokVal === "this") { - var node = startNode(); - next(); - return finishNode(node, "ThisExpression"); - } else return parseIdent(); - + return parseIdent(); case _num: case _string: case _regexp: var node = startNode(); node.value = tokVal; diff --git a/index.html b/index.html index bdb451f0b2..7d30bcb18c 100644 --- a/index.html +++ b/index.html @@ -118,7 +118,8 @@ continue jumps to that label.

var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"}; var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"}; var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"}; - var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};

The keywords that denote values.

  var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
+  var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
+  var _this = {keyword: "this"};

The keywords that denote values.

  var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
   var _false = {keyword: "false", atomValue: false};

Some keywords are treated as regular operators. in sometimes (when parsing for) needs to be tested against specifically, so we assign a variable name to it for quick comparing.

  var _in = {keyword: "in", binop: 7, beforeExpr: true};

Map keyword names to token types.

  var keywordTypes = {"break": _break, "case": _case, "catch": _catch,
@@ -127,7 +128,7 @@ we assign a variable name to it for quick comparing.

"function": _function, "if": _if, "return": _return, "switch": _switch, "throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with, "null": _null, "true": _true, "false": _false, "new": _new, "in": _in, - "instanceof": {keyword: "instanceof", binop: 7}, + "instanceof": {keyword: "instanceof", binop: 7}, "this": _this, "typeof": {keyword: "typeof", prefix: true}, "void": {keyword: "void", prefix: true}, "delete": {keyword: "delete", prefix: true}};

Punctuation token types. Again, the type property is purely for debugging.

  var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
@@ -190,7 +191,7 @@ switch first dispatches on the lengths, to save on comparisons.

compareTo(words); } return new Function("str", f); - }

The ECMAScript 3 reserved word list.

  var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");

ECMAScript 5 reserved words.

  var isReservedWord5 = makePredicate("class enum extends super const export import");

The additional reserved words in strict mode.

  var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");

The forbidden variable names in strict mode.

  var isStrictBadIdWord = makePredicate("eval arguments");

And the keywords.

  var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in");

Character categories

Big ugly regular expressions that match characters in the + }

The ECMAScript 3 reserved word list.

  var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");

ECMAScript 5 reserved words.

  var isReservedWord5 = makePredicate("class enum extends super const export import");

The additional reserved words in strict mode.

  var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");

The forbidden variable names in strict mode.

  var isStrictBadIdWord = makePredicate("eval arguments");

And the keywords.

  var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this");

Character categories

Big ugly regular expressions that match characters in the whitespace, identifier, and identifier-start categories. These are only applied when a character is found to actually have a code point above 128.

  var nonASCIIwhitespace = /[\u1680\u180E\u2000-\u200A\u202F\u205F\u3000\uFEFF]/;
@@ -353,7 +354,6 @@ of the type given by its first argument.

return finishOp(code === 61 ? _eq : _prefix, 1); case 126: // '~' - if (next === 61) return finishOp(_assign, 2); return finishOp(_prefix, 1); }

If we are here, we either found a non-ASCII identifier character, or something that's entirely disallowed.

    var ch = String.fromCharCode(code);
@@ -1012,13 +1012,12 @@ expression, an expression started by a keyword like function or
 new, or an expression wrapped in punctuation like (), [],
 or {}.

  function parseExprAtom() {
     switch (tokType) {
+    case _this:
+      var node = startNode();
+      next();
+      return finishNode(node, "ThisExpression");
     case _name:
-      if (tokVal === "this") {
-        var node = startNode();
-        next();
-        return finishNode(node, "ThisExpression");
-      } else return parseIdent();
-
+      return parseIdent();
     case _num: case _string: case _regexp:
       var node = startNode();
       node.value = tokVal;