| 1 |
lars |
1 |
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
2 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
3 |
*
|
|
|
4 |
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
5 |
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
6 |
* the License. You may obtain a copy of the License at
|
|
|
7 |
* http://www.mozilla.org/MPL/
|
|
|
8 |
*
|
|
|
9 |
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
10 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
11 |
* for the specific language governing rights and limitations under the
|
|
|
12 |
* License.
|
|
|
13 |
*
|
|
|
14 |
* The Original Code is the Narcissus JavaScript engine.
|
|
|
15 |
*
|
|
|
16 |
* The Initial Developer of the Original Code is
|
|
|
17 |
* Brendan Eich <brendan@mozilla.org>.
|
|
|
18 |
* Portions created by the Initial Developer are Copyright (C) 2004
|
|
|
19 |
* the Initial Developer. All Rights Reserved.
|
|
|
20 |
*
|
|
|
21 |
* Contributor(s):
|
|
|
22 |
*
|
|
|
23 |
* Alternatively, the contents of this file may be used under the terms of
|
|
|
24 |
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
25 |
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
26 |
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
27 |
* of those above. If you wish to allow use of your version of this file only
|
|
|
28 |
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
29 |
* use your version of this file under the terms of the MPL, indicate your
|
|
|
30 |
* decision by deleting the provisions above and replace them with the notice
|
|
|
31 |
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
32 |
* the provisions above, a recipient may use your version of this file under
|
|
|
33 |
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
34 |
*
|
|
|
35 |
* ***** END LICENSE BLOCK ***** */
|
|
|
36 |
|
|
|
37 |
/*
|
|
|
38 |
* Narcissus - JS implemented in JS.
|
|
|
39 |
*
|
|
|
40 |
* Well-known constants and lookup tables. Many consts are generated from the
|
|
|
41 |
* tokens table via eval to minimize redundancy, so consumers must be compiled
|
|
|
42 |
* separately to take advantage of the simple switch-case constant propagation
|
|
|
43 |
* done by SpiderMonkey.
|
|
|
44 |
*/
|
|
|
45 |
|
|
|
46 |
// jrh
|
|
|
47 |
//module('JS.Defs');
|
|
|
48 |
|
|
|
49 |
GLOBAL = this;
|
|
|
50 |
|
|
|
51 |
var tokens = [
|
|
|
52 |
// End of source.
|
|
|
53 |
"END",
|
|
|
54 |
|
|
|
55 |
// Operators and punctuators. Some pair-wise order matters, e.g. (+, -)
|
|
|
56 |
// and (UNARY_PLUS, UNARY_MINUS).
|
|
|
57 |
"\n", ";",
|
|
|
58 |
",",
|
|
|
59 |
"=",
|
|
|
60 |
"?", ":", "CONDITIONAL",
|
|
|
61 |
"||",
|
|
|
62 |
"&&",
|
|
|
63 |
"|",
|
|
|
64 |
"^",
|
|
|
65 |
"&",
|
|
|
66 |
"==", "!=", "===", "!==",
|
|
|
67 |
"<", "<=", ">=", ">",
|
|
|
68 |
"<<", ">>", ">>>",
|
|
|
69 |
"+", "-",
|
|
|
70 |
"*", "/", "%",
|
|
|
71 |
"!", "~", "UNARY_PLUS", "UNARY_MINUS",
|
|
|
72 |
"++", "--",
|
|
|
73 |
".",
|
|
|
74 |
"[", "]",
|
|
|
75 |
"{", "}",
|
|
|
76 |
"(", ")",
|
|
|
77 |
|
|
|
78 |
// Nonterminal tree node type codes.
|
|
|
79 |
"SCRIPT", "BLOCK", "LABEL", "FOR_IN", "CALL", "NEW_WITH_ARGS", "INDEX",
|
|
|
80 |
"ARRAY_INIT", "OBJECT_INIT", "PROPERTY_INIT", "GETTER", "SETTER",
|
|
|
81 |
"GROUP", "LIST",
|
|
|
82 |
|
|
|
83 |
// Terminals.
|
|
|
84 |
"IDENTIFIER", "NUMBER", "STRING", "REGEXP",
|
|
|
85 |
|
|
|
86 |
// Keywords.
|
|
|
87 |
"break",
|
|
|
88 |
"case", "catch", "const", "continue",
|
|
|
89 |
"debugger", "default", "delete", "do",
|
|
|
90 |
"else", "enum",
|
|
|
91 |
"false", "finally", "for", "function",
|
|
|
92 |
"if", "in", "instanceof",
|
|
|
93 |
"new", "null",
|
|
|
94 |
"return",
|
|
|
95 |
"switch",
|
|
|
96 |
"this", "throw", "true", "try", "typeof",
|
|
|
97 |
"var", "void",
|
|
|
98 |
"while", "with",
|
|
|
99 |
// Extensions
|
|
|
100 |
"require", "bless", "mixin", "import"
|
|
|
101 |
];
|
|
|
102 |
|
|
|
103 |
// Operator and punctuator mapping from token to tree node type name.
|
|
|
104 |
// NB: superstring tokens (e.g., ++) must come before their substring token
|
|
|
105 |
// counterparts (+ in the example), so that the opRegExp regular expression
|
|
|
106 |
// synthesized from this list makes the longest possible match.
|
|
|
107 |
var opTypeNames = {
|
|
|
108 |
'\n': "NEWLINE",
|
|
|
109 |
';': "SEMICOLON",
|
|
|
110 |
',': "COMMA",
|
|
|
111 |
'?': "HOOK",
|
|
|
112 |
':': "COLON",
|
|
|
113 |
'||': "OR",
|
|
|
114 |
'&&': "AND",
|
|
|
115 |
'|': "BITWISE_OR",
|
|
|
116 |
'^': "BITWISE_XOR",
|
|
|
117 |
'&': "BITWISE_AND",
|
|
|
118 |
'===': "STRICT_EQ",
|
|
|
119 |
'==': "EQ",
|
|
|
120 |
'=': "ASSIGN",
|
|
|
121 |
'!==': "STRICT_NE",
|
|
|
122 |
'!=': "NE",
|
|
|
123 |
'<<': "LSH",
|
|
|
124 |
'<=': "LE",
|
|
|
125 |
'<': "LT",
|
|
|
126 |
'>>>': "URSH",
|
|
|
127 |
'>>': "RSH",
|
|
|
128 |
'>=': "GE",
|
|
|
129 |
'>': "GT",
|
|
|
130 |
'++': "INCREMENT",
|
|
|
131 |
'--': "DECREMENT",
|
|
|
132 |
'+': "PLUS",
|
|
|
133 |
'-': "MINUS",
|
|
|
134 |
'*': "MUL",
|
|
|
135 |
'/': "DIV",
|
|
|
136 |
'%': "MOD",
|
|
|
137 |
'!': "NOT",
|
|
|
138 |
'~': "BITWISE_NOT",
|
|
|
139 |
'.': "DOT",
|
|
|
140 |
'[': "LEFT_BRACKET",
|
|
|
141 |
']': "RIGHT_BRACKET",
|
|
|
142 |
'{': "LEFT_CURLY",
|
|
|
143 |
'}': "RIGHT_CURLY",
|
|
|
144 |
'(': "LEFT_PAREN",
|
|
|
145 |
')': "RIGHT_PAREN"
|
|
|
146 |
};
|
|
|
147 |
|
|
|
148 |
// Hash of keyword identifier to tokens index. NB: we must null __proto__ to
|
|
|
149 |
// avoid toString, etc. namespace pollution.
|
|
|
150 |
var keywords = {__proto__: null};
|
|
|
151 |
|
|
|
152 |
// Define const END, etc., based on the token names. Also map name to index.
|
|
|
153 |
var consts = " ";
|
|
|
154 |
for (var i = 0, j = tokens.length; i < j; i++) {
|
|
|
155 |
if (i > 0)
|
|
|
156 |
consts += "; ";
|
|
|
157 |
var t = tokens[i];
|
|
|
158 |
if (/^[a-z]/.test(t)) {
|
|
|
159 |
consts += t.toUpperCase();
|
|
|
160 |
keywords[t] = i;
|
|
|
161 |
} else {
|
|
|
162 |
consts += (/^\W/.test(t) ? opTypeNames[t] : t);
|
|
|
163 |
}
|
|
|
164 |
consts += " = " + i;
|
|
|
165 |
tokens[t] = i;
|
|
|
166 |
}
|
|
|
167 |
eval(consts + ";");
|
|
|
168 |
|
|
|
169 |
// Map assignment operators to their indexes in the tokens array.
|
|
|
170 |
var assignOps = ['|', '^', '&', '<<', '>>', '>>>', '+', '-', '*', '/', '%'];
|
|
|
171 |
|
|
|
172 |
for (i = 0, j = assignOps.length; i < j; i++) {
|
|
|
173 |
t = assignOps[i];
|
|
|
174 |
assignOps[t] = tokens[t];
|
|
|
175 |
}
|