ref: cb273846e4702b096feb761d26c3cff82f2f22df
parent: e01fe424ab94395713d94f46eee57f1af0a279b4
author: Tor Andersson <tor@ccxvii.net>
date: Fri Dec 27 12:56:41 EST 2013
Throw errors on future words immediately. Use the latest ECMA 262-5 list of future words.
--- a/js-lex.c
+++ b/js-lex.c
@@ -2,108 +2,66 @@
#define nelem(a) (sizeof (a) / sizeof (a)[0])
-struct {- const char *string;
- js_Token token;
-} keywords[] = {- {"abstract", JS_ABSTRACT},- {"boolean", JS_BOOLEAN},- {"break", JS_BREAK},- {"byte", JS_BYTE},- {"case", JS_CASE},- {"catch", JS_CATCH},- {"char", JS_CHAR},- {"class", JS_CLASS},- {"const", JS_CONST},- {"continue", JS_CONTINUE},- {"debugger", JS_DEBUGGER},- {"default", JS_DEFAULT},- {"delete", JS_DELETE},- {"do", JS_DO},- {"double", JS_DOUBLE},- {"else", JS_ELSE},- {"enum", JS_ENUM},- {"export", JS_EXPORT},- {"extends", JS_EXTENDS},- {"false", JS_FALSE},- {"final", JS_FINAL},- {"finally", JS_FINALLY},- {"float", JS_FLOAT},- {"for", JS_FOR},- {"function", JS_FUNCTION},- {"goto", JS_GOTO},- {"if", JS_IF},- {"implements", JS_IMPLEMENTS},- {"import", JS_IMPORT},- {"in", JS_IN},- {"instanceof", JS_INSTANCEOF},- {"int", JS_INT},- {"interface", JS_INTERFACE},- {"long", JS_LONG},- {"native", JS_NATIVE},- {"new", JS_NEW},- {"null", JS_NULL},- {"package", JS_PACKAGE},- {"private", JS_PRIVATE},- {"protected", JS_PROTECTED},- {"public", JS_PUBLIC},- {"return", JS_RETURN},- {"short", JS_SHORT},- {"static", JS_STATIC},- {"super", JS_SUPER},- {"switch", JS_SWITCH},- {"synchronized", JS_SYNCHRONIZED},- {"this", JS_THIS},- {"throw", JS_THROW},- {"throws", JS_THROWS},- {"transient", JS_TRANSIENT},- {"true", JS_TRUE},- {"try", JS_TRY},- {"typeof", JS_TYPEOF},- {"var", JS_VAR},- {"void", JS_VOID},- {"volatile", JS_VOLATILE},- {"while", JS_WHILE},- {"with", JS_WITH},+static const char *keywords[] = {+ "break", "case", "catch", "continue", "debugger", "default", "delete",
+ "do", "else", "false", "finally", "for", "function", "if", "in",
+ "instanceof", "new", "null", "return", "switch", "this", "throw",
+ "true", "try", "typeof", "var", "void", "while", "with",
};
-static inline js_Token findkeyword(const char *s)
-{- int m, l, r;
- int c;
+static const char *futurewords[] = {+ "class", "const", "enum", "export", "extends", "import", "super",
+};
- l = 0;
- r = nelem(keywords) - 1;
+static const char *strictfuturewords[] = {+ "implements", "interface", "let", "package", "private", "protected",
+ "public", "static", "yield",
+};
+static inline int findword(const char *s, const char **list, int num)
+{+ int l = 0;
+ int r = num - 1;
while (l <= r) {- m = (l + r) >> 1;
- c = strcmp(s, keywords[m].string);
+ int m = (l + r) >> 1;
+ int c = strcmp(s, list[m]);
if (c < 0)
r = m - 1;
else if (c > 0)
l = m + 1;
else
- return keywords[m].token;
+ return m;
}
+ return -1;
+}
+static inline js_Token findkeyword(js_State *J, const char *s)
+{+ int i = findword(s, keywords, nelem(keywords));
+ if (i >= 0)
+ return JS_BREAK + i;
+
+ if (findword(s, futurewords, nelem(futurewords)) >= 0)
+ return js_syntaxerror(J, "'%s' is a future reserved word", s);
+ if (J->strict && findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0)
+ return js_syntaxerror(J, "'%s' is a strict mode future reserved word", s);
+
return JS_IDENTIFIER;
}
const char *tokenstrings[] = {- "ERROR", "EOF", "(identifier)", "null", "true", "false", "(number)",
- "(string)", "(regexp)", "\\n", "{", "}", "(", ")", "[", "]", ".", ";",- ",", "<", ">", "<=", ">=", "==", "!=", "===", "!==", "+", "-", "*",
- "%", "++", "--", "<<", ">>", ">>>", "&", "|", "^", "!", "~", "&&",
- "||", "?", ":", "=", "+=", "-=", "*=", "%=", "<<=", ">>=", ">>>=",
- "&=", "|=", "^=", "/", "/=", "break", "case", "catch", "continue",
- "default", "delete", "do", "else", "finally", "for", "function", "if",
- "in", "instanceof", "new", "return", "switch", "this", "throw", "try",
- "typeof", "var", "void", "while", "with", "abstract", "boolean",
- "byte", "char", "class", "const", "debugger", "double", "enum",
- "export", "extends", "final", "float", "goto", "implements", "import",
- "int", "interface", "long", "native", "package", "private",
- "protected", "public", "short", "static", "super", "synchronized",
- "throws", "transient", "volatile",
+ "(error)", "(eof)", "(identifier)", "null", "true", "false",
+ "(number)", "(string)", "(regexp)", "(newline)",
+ "{", "}", "(", ")", "[", "]", ".", ";", ",",+ "<", ">", "<=", ">=", "==", "!=", "===", "!==",
+ "+", "-", "*", "%", "++", "--", "<<", ">>", ">>>", "&", "|",
+ "^", "!", "~", "&&", "||", "?", ":",
+ "=", "+=", "-=", "*=", "%=", "<<=", ">>=", ">>>=", "&=", "|=", "^=",
+ "/", "/=",
+ "break", "case", "catch", "continue", "debugger", "default", "delete",
+ "do", "else", "finally", "for", "function", "if", "in", "instanceof",
+ "new", "return", "switch", "this", "throw", "try", "typeof", "var",
+ "void", "while", "with",
};
const char *js_tokentostring(js_Token t)
@@ -450,7 +408,7 @@
textend(J);
- return findkeyword(J->yytext);
+ return findkeyword(J, J->yytext);
}
if (c == '.') {--- a/js.h
+++ b/js.h
@@ -93,6 +93,7 @@
JS_CASE,
JS_CATCH,
JS_CONTINUE,
+ JS_DEBUGGER,
JS_DEFAULT,
JS_DELETE,
JS_DO,
@@ -114,40 +115,6 @@
JS_VOID,
JS_WHILE,
JS_WITH,
-
- /* future reserved words */
- JS_ABSTRACT,
- JS_BOOLEAN,
- JS_BYTE,
- JS_CHAR,
- JS_CLASS,
- JS_CONST,
- JS_DEBUGGER,
- JS_DOUBLE,
- JS_ENUM,
- JS_EXPORT,
- JS_EXTENDS,
- JS_FINAL,
- JS_FLOAT,
- JS_GOTO,
- JS_IMPLEMENTS,
- JS_IMPORT,
- JS_INT,
- JS_INTERFACE,
- JS_LONG,
- JS_NATIVE,
- JS_PACKAGE,
- JS_PRIVATE,
- JS_PROTECTED,
- JS_PUBLIC,
- JS_SHORT,
- JS_STATIC,
- JS_SUPER,
- JS_SYNCHRONIZED,
- JS_THROWS,
- JS_TRANSIENT,
- JS_VOLATILE,
-
};
struct js_State
@@ -158,6 +125,7 @@
struct { int g, i, m; } yyflags;int yyline;
js_Token lasttoken;
+ int strict;
};
void js_initlex(js_State *J);
--
⑨