Coverage Report

Created: 2025-12-24 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsSyntaxical.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 * 
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 * 
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 * 
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and  
20
 * permission notice:  
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsScript.h"
39
40
static txBoolean fxIsKeyword(txParser* parser, txSymbol* keyword);
41
static txBoolean fxIsToken(txParser* parser, txToken theToken);
42
static void fxMatchToken(txParser* parser, txToken theToken);
43
static txNode* fxPopNode(txParser* parser);
44
static void fxPushNode(txParser* parser, txNode* node);
45
static void fxPushBigIntNode(txParser* parser, txBigInt* value, txInteger line);
46
static void fxPushIndexNode(txParser* parser, txIndex value, txInteger line);
47
static void fxPushIntegerNode(txParser* parser, txInteger value, txInteger line);
48
static void fxPushNodeStruct(txParser* parser, txInteger count, txToken token, txInteger line);
49
static void fxPushNodeList(txParser* parser, txInteger count);
50
static void fxPushNULL(txParser* parser);
51
static void fxPushNumberNode(txParser* parser, txNumber value, txInteger line);
52
static void fxPushRawNode(txParser* parser, txInteger length, txString value, txInteger line);
53
static void fxPushStringNode(txParser* parser, txInteger length, txString value, txInteger line);
54
static void fxPushSymbol(txParser* parser, txSymbol* symbol);
55
static void fxSwapNodes(txParser* parser);
56
57
static void fxExportDeclaration(txParser* parser);
58
static void fxExportBinding(txParser* parser, txNode* node);
59
static void fxImportDeclaration(txParser* parser);
60
static void fxWithAttributes(txParser* parser);
61
static void fxSpecifiers(txParser* parser);
62
63
static void fxBody(txParser* parser);
64
static void fxStatements(txParser* parser);
65
static void fxBlock(txParser* parser);
66
static void fxStatement(txParser* parser, txInteger blockIt);
67
static void fxSemicolon(txParser* parser);
68
69
static void fxBreakStatement(txParser* parser);
70
static void fxContinueStatement(txParser* parser);
71
static void fxDebuggerStatement(txParser* parser);
72
static void fxDoStatement(txParser* parser);
73
static void fxForStatement(txParser* parser);
74
static void fxIfStatement(txParser* parser);
75
static void fxReturnStatement(txParser* parser);
76
static void fxSwitchStatement(txParser* parser);
77
static void fxThrowStatement(txParser* parser);
78
static void fxTryStatement(txParser* parser);
79
static void fxVariableStatement(txParser* parser, txToken theToken, txUnsigned flags);
80
static void fxWhileStatement(txParser* parser);
81
static void fxWithStatement(txParser* parser);
82
83
static void fxCommaExpression(txParser* parser);
84
static void fxAssignmentExpression(txParser* parser);
85
static void fxConditionalExpression(txParser* parser);
86
static void fxOrExpression(txParser* parser);
87
static void fxAndExpression(txParser* parser);
88
static void fxCoalesceExpression(txParser* parser);
89
static void fxBitOrExpression(txParser* parser);
90
static void fxBitXorExpression(txParser* parser);
91
static void fxBitAndExpression(txParser* parser);
92
static void fxEqualExpression(txParser* parser);
93
static void fxRelationalExpression(txParser* parser);
94
static void fxShiftExpression(txParser* parser);
95
static void fxAdditiveExpression(txParser* parser);
96
static void fxMultiplicativeExpression(txParser* parser);
97
static void fxExponentiationExpression(txParser* parser);
98
static void fxUnaryExpression(txParser* parser);
99
static void fxPrefixExpression(txParser* parser);
100
static void fxPostfixExpression(txParser* parser);
101
static void fxCallExpression(txParser* parser);
102
103
static void fxLiteralExpression(txParser* parser, txUnsigned flag);
104
static void fxArrayExpression(txParser* parser);
105
static void fxArrowExpression(txParser* parser, txUnsigned flag);
106
static void fxClassExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol);
107
static void fxFunctionExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag);
108
static void fxGeneratorExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag);
109
static void fxGroupExpression(txParser* parser, txUnsigned flag);
110
static void fxObjectExpression(txParser* parser);
111
static void fxNewExpression(txParser* parser);
112
static void fxTemplateExpression(txParser* parser);
113
static void fxYieldExpression(txParser* parser);
114
115
static void fxParameters(txParser* parser);
116
static void fxPropertyName(txParser* parser, txSymbol** theSymbol, txToken* theToken0, txToken* theToken1, txToken* theToken2, txUnsigned* flag);
117
118
static void fxBinding(txParser* parser, txToken theToken, txUnsigned flags);
119
static txNode* fxBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken);
120
static void fxArrayBinding(txParser* parser, txToken theToken);
121
static txNode* fxArrayBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken);
122
static txUnsigned fxObjectBinding(txParser* parser, txToken theToken);
123
static txNode* fxObjectBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken);
124
static void fxParametersBinding(txParser* parser);
125
static txNode* fxParametersBindingFromExpressions(txParser* parser, txNode* theNode);
126
static void fxRestBinding(txParser* parser, txToken theToken, txUnsigned flag);
127
static txNode* fxRestBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken, txUnsigned flag);
128
129
static void fxCheckArrowFunction(txParser* parser, txInteger count);
130
static void fxCheckNativeConstructor(txParser* parser);
131
static void fxCheckNativeFunction(txParser* parser);
132
static txBoolean fxCheckReference(txParser* parser, txToken theToken);
133
static void fxCheckStrictBinding(txParser* parser, txNode* node);
134
static void fxCheckStrictFunction(txParser* parser, txFunctionNode* function);
135
static void fxCheckStrictSymbol(txParser* parser, txSymbol* symbol);
136
static void fxCheckUniqueProperty(txParser* parser, txNode* base, txNode* current);
137
static void fxCheckUniquePropertyAux(txParser* parser, txNode* baseNode, txNode* currentNode);
138
139
static void fxJSONObject(txParser* parser);
140
static void fxJSONArray(txParser* parser);
141
142
static void fxJSXAttributeName(txParser* parser);
143
static void fxJSXAttributeValue(txParser* parser);
144
static void fxJSXElement(txParser* parser);
145
static void fxJSXElementName(txParser* parser);
146
static txBoolean fxJSXMatch(txParser* parser, txNode* opening, txNode* closing);
147
static txSymbol* fxJSXNamespace(txParser* parser, txSymbol* namespace, txSymbol* name);
148
149
5.84k
#define XS_TOKEN_BEGIN_STATEMENT 1
150
4.18M
#define XS_TOKEN_BEGIN_EXPRESSION 2
151
3.01M
#define XS_TOKEN_ASSIGN_EXPRESSION 4
152
2.91M
#define XS_TOKEN_EQUAL_EXPRESSION 8
153
2.99M
#define XS_TOKEN_RELATIONAL_EXPRESSION 16
154
3.01M
#define XS_TOKEN_SHIFT_EXPRESSION 32
155
7.56M
#define XS_TOKEN_ADDITIVE_EXPRESSION 64
156
7.66M
#define XS_TOKEN_MULTIPLICATIVE_EXPRESSION 128
157
7.55M
#define XS_TOKEN_EXPONENTIATION_EXPRESSION 256
158
7.77M
#define XS_TOKEN_PREFIX_EXPRESSION 512
159
6.52M
#define XS_TOKEN_POSTFIX_EXPRESSION 1024
160
553k
#define XS_TOKEN_END_STATEMENT 2048
161
#define XS_TOKEN_REFERENCE_EXPRESSION 4096
162
580k
#define XS_TOKEN_BEGIN_BINDING 16384
163
257k
#define XS_TOKEN_IDENTIFIER_NAME 32768
164
8.07M
#define XS_TOKEN_UNARY_EXPRESSION 65536
165
7.66M
#define XS_TOKEN_CALL_EXPRESSION 131072
166
167
static txTokenFlag gxTokenFlags[XS_TOKEN_COUNT] = {
168
  /* XS_NO_TOKEN */ 0,
169
  /* XS_TOKEN_ACCESS */ 0,
170
  /* XS_TOKEN_ADD */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_ADDITIVE_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION,
171
  /* XS_TOKEN_ADD_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
172
  /* XS_TOKEN_AND */ 0,
173
  /* XS_TOKEN_AND_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
174
  /* XS_TOKEN_ARG */ 0,
175
  /* XS_TOKEN_ARGUMENTS */ 0,
176
  /* XS_TOKEN_ARGUMENTS_SLOPPY */ 0,
177
  /* XS_TOKEN_ARGUMENTS_STRICT */ 0,
178
  /* XS_TOKEN_ARRAY */ 0,
179
  /* XS_TOKEN_ARRAY_BINDING */ 0,
180
  /* XS_TOKEN_ARROW */ 0,
181
  /* XS_TOKEN_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
182
  /* XS_TOKEN_AWAIT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
183
  /* XS_TOKEN_BIGINT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION,
184
  /* XS_TOKEN_BINDING */ 0,
185
  /* XS_TOKEN_BIT_AND */ 0,
186
  /* XS_TOKEN_BIT_AND_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
187
  /* XS_TOKEN_BIT_NOT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION,
188
  /* XS_TOKEN_BIT_OR */ 0,
189
  /* XS_TOKEN_BIT_OR_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
190
  /* XS_TOKEN_BIT_XOR */ 0,
191
  /* XS_TOKEN_BIT_XOR_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
192
  /* XS_TOKEN_BLOCK */ 0,
193
  /* XS_TOKEN_BODY */ 0,
194
  /* XS_TOKEN_BREAK */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
195
  /* XS_TOKEN_CALL */ 0,
196
  /* XS_TOKEN_CASE */ XS_TOKEN_IDENTIFIER_NAME,
197
  /* XS_TOKEN_CATCH */ XS_TOKEN_IDENTIFIER_NAME,
198
  /* XS_TOKEN_CHAIN */ XS_TOKEN_CALL_EXPRESSION,
199
  /* XS_TOKEN_CLASS */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
200
  /* XS_TOKEN_COALESCE */ 0,
201
  /* XS_TOKEN_COALESCE_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
202
  /* XS_TOKEN_COLON */ 0,
203
  /* XS_TOKEN_COMMA */ XS_TOKEN_END_STATEMENT,
204
  /* XS_TOKEN_CONST */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
205
  /* XS_TOKEN_CONTINUE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
206
  /* XS_TOKEN_CURRENT */ 0,
207
  /* XS_TOKEN_DEBUGGER */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
208
  /* XS_TOKEN_DECREMENT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_PREFIX_EXPRESSION | XS_TOKEN_POSTFIX_EXPRESSION,
209
  /* XS_TOKEN_DEFAULT */ XS_TOKEN_IDENTIFIER_NAME,
210
  /* XS_TOKEN_DEFINE */ 0,
211
  /* XS_TOKEN_DELEGATE */ 0,
212
  /* XS_TOKEN_DELETE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
213
  /* XS_TOKEN_DIVIDE */ XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_MULTIPLICATIVE_EXPRESSION,
214
  /* XS_TOKEN_DIVIDE_ASSIGN */ XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_ASSIGN_EXPRESSION,
215
  /* XS_TOKEN_DO */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
216
  /* XS_TOKEN_DOT */ XS_TOKEN_CALL_EXPRESSION,
217
  /* XS_TOKEN_ELISION */ 0,
218
  /* XS_TOKEN_ELSE */ XS_TOKEN_IDENTIFIER_NAME,
219
  /* XS_TOKEN_ENUM */ XS_TOKEN_IDENTIFIER_NAME,
220
  /* XS_TOKEN_EOF */ XS_TOKEN_END_STATEMENT,
221
  /* XS_TOKEN_EQUAL */ XS_TOKEN_EQUAL_EXPRESSION,
222
  /* XS_TOKEN_EVAL */ 0,
223
  /* XS_TOKEN_EXPONENTIATION */ XS_TOKEN_EXPONENTIATION_EXPRESSION,
224
  /* XS_TOKEN_EXPONENTIATION_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
225
  /* XS_TOKEN_EXPORT */ XS_TOKEN_IDENTIFIER_NAME,
226
  /* XS_TOKEN_EXPRESSIONS */ 0,
227
  /* XS_TOKEN_EXTENDS */ XS_TOKEN_IDENTIFIER_NAME,
228
  /* XS_TOKEN_FALSE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
229
  /* XS_TOKEN_FIELD */ 0,
230
  /* XS_TOKEN_FINALLY */ XS_TOKEN_IDENTIFIER_NAME | XS_TOKEN_IDENTIFIER_NAME,
231
  /* XS_TOKEN_FOR */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
232
  /* XS_TOKEN_FOR_AWAIT_OF */ 0,
233
  /* XS_TOKEN_FOR_IN */ 0,
234
  /* XS_TOKEN_FOR_OF */ 0,
235
  /* XS_TOKEN_FUNCTION */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
236
  /* XS_TOKEN_GENERATOR */ 0,
237
  /* XS_TOKEN_GETTER */ 0,
238
  /* XS_TOKEN_HOST */ XS_TOKEN_BEGIN_EXPRESSION,
239
  /* XS_TOKEN_IDENTIFIER */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_BEGIN_BINDING | XS_TOKEN_IDENTIFIER_NAME,
240
  /* XS_TOKEN_IF */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
241
  /* XS_TOKEN_IMPLEMENTS */ XS_TOKEN_IDENTIFIER_NAME,
242
  /* XS_TOKEN_IMPORT */ XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
243
  /* XS_TOKEN_IMPORT_CALL */ 0,
244
  /* XS_TOKEN_IMPORT_META */ 0,
245
  /* XS_TOKEN_IN */ XS_TOKEN_RELATIONAL_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
246
  /* XS_TOKEN_INCLUDE */ 0,
247
  /* XS_TOKEN_INCREMENT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_PREFIX_EXPRESSION | XS_TOKEN_POSTFIX_EXPRESSION,
248
  /* XS_TOKEN_INSTANCEOF */ XS_TOKEN_RELATIONAL_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
249
  /* XS_TOKEN_INTEGER */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION,
250
  /* XS_TOKEN_INTERFACE */ XS_TOKEN_IDENTIFIER_NAME,
251
  /* XS_TOKEN_ITEMS */ 0,
252
  /* XS_TOKEN_LABEL */ 0,
253
  /* XS_TOKEN_LEFT_BRACE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_BEGIN_BINDING,
254
  /* XS_TOKEN_LEFT_BRACKET */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_BEGIN_BINDING | XS_TOKEN_CALL_EXPRESSION,
255
  /* XS_TOKEN_LEFT_PARENTHESIS */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_CALL_EXPRESSION,
256
  /* XS_TOKEN_LEFT_SHIFT */ XS_TOKEN_SHIFT_EXPRESSION,
257
  /* XS_TOKEN_LEFT_SHIFT_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
258
  /* XS_TOKEN_LESS */ XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_RELATIONAL_EXPRESSION,
259
  /* XS_TOKEN_LESS_EQUAL */ XS_TOKEN_RELATIONAL_EXPRESSION,
260
  /* XS_TOKEN_LET */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
261
  /* XS_TOKEN_MEMBER */ 0,
262
  /* XS_TOKEN_MEMBER_AT */ 0,
263
  /* XS_TOKEN_MINUS */ 0,
264
  /* XS_TOKEN_MODULE */ 0,
265
  /* XS_TOKEN_MODULO */ XS_TOKEN_MULTIPLICATIVE_EXPRESSION,
266
  /* XS_TOKEN_MODULO_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
267
  /* XS_TOKEN_MORE */ XS_TOKEN_RELATIONAL_EXPRESSION,
268
  /* XS_TOKEN_MORE_EQUAL */ XS_TOKEN_RELATIONAL_EXPRESSION,
269
  /* XS_TOKEN_MULTIPLY */ XS_TOKEN_MULTIPLICATIVE_EXPRESSION,
270
  /* XS_TOKEN_MULTIPLY_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
271
  /* XS_TOKEN_NEW */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME, 
272
  /* XS_TOKEN_NOT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION,
273
  /* XS_TOKEN_NOT_EQUAL */ XS_TOKEN_EQUAL_EXPRESSION,
274
  /* XS_TOKEN_NULL */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME, 
275
  /* XS_TOKEN_NUMBER */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION,
276
  /* XS_TOKEN_OBJECT */ 0,
277
  /* XS_TOKEN_OBJECT_BINDING */ 0,
278
  /* XS_TOKEN_OPTION */ 0,
279
  /* XS_TOKEN_OR */ 0,
280
  /* XS_TOKEN_OR_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
281
  /* XS_TOKEN_PACKAGE */ XS_TOKEN_IDENTIFIER_NAME,
282
  /* XS_TOKEN_PARAMS */ 0,
283
  /* XS_TOKEN_PARAMS_BINDING */ 0,
284
  /* XS_TOKEN_PLUS */ 0,
285
  /* XS_TOKEN_PRIVATE */ XS_TOKEN_IDENTIFIER_NAME,
286
  /* XS_TOKEN_PRIVATE_IDENTIFIER */ XS_TOKEN_BEGIN_EXPRESSION,
287
  /* XS_TOKEN_PRIVATE_MEMBER */ 0,
288
  /* XS_TOKEN_PRIVATE_PROPERTY */ 0,
289
  /* XS_TOKEN_PROGRAM */ 0,
290
  /* XS_TOKEN_PROPERTY */ 0,
291
  /* XS_TOKEN_PROPERTY_AT */ 0,
292
  /* XS_TOKEN_PROPERTY_BINDING */ 0,
293
  /* XS_TOKEN_PROPERTY_BINDING_AT */ 0,
294
  /* XS_TOKEN_PROTECTED */ XS_TOKEN_IDENTIFIER_NAME,
295
  /* XS_TOKEN_PUBLIC */ XS_TOKEN_IDENTIFIER_NAME,
296
  /* XS_TOKEN_QUESTION_MARK */ 0,
297
  /* XS_TOKEN_REGEXP */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION,
298
  /* XS_TOKEN_REST_BINDING */ 0,
299
  /* XS_TOKEN_RETURN */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
300
  /* XS_TOKEN_RIGHT_BRACE */ XS_TOKEN_END_STATEMENT,
301
  /* XS_TOKEN_RIGHT_BRACKET */ 0,
302
  /* XS_TOKEN_RIGHT_PARENTHESIS */ 0,
303
  /* XS_TOKEN_SEMICOLON */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_END_STATEMENT,
304
  /* XS_TOKEN_SETTER */ 0,
305
  /* XS_TOKEN_SHORT */ 0,
306
  /* XS_TOKEN_SIGNED_RIGHT_SHIFT */ XS_TOKEN_SHIFT_EXPRESSION,
307
  /* XS_TOKEN_SIGNED_RIGHT_SHIFT_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
308
  /* XS_TOKEN_SKIP_BINDING */ 0,
309
  /* XS_TOKEN_SPECIFIER */ 0,
310
  /* XS_TOKEN_SPREAD */ XS_TOKEN_BEGIN_BINDING,
311
  /* XS_TOKEN_STATEMENT */ 0,
312
  /* XS_TOKEN_STATEMENTS */ 0,
313
  /* XS_TOKEN_STATIC */ XS_TOKEN_IDENTIFIER_NAME,
314
  /* XS_TOKEN_STRICT_EQUAL */ XS_TOKEN_EQUAL_EXPRESSION,
315
  /* XS_TOKEN_STRICT_NOT_EQUAL */ XS_TOKEN_EQUAL_EXPRESSION,
316
  /* XS_TOKEN_STRING */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION,
317
  /* XS_TOKEN_SUBTRACT */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_ADDITIVE_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION,
318
  /* XS_TOKEN_SUBTRACT_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
319
  /* XS_TOKEN_SUPER */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
320
  /* XS_TOKEN_SWITCH */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
321
  /* XS_TOKEN_TARGET */ 0,
322
  /* XS_TOKEN_TEMPLATE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_CALL_EXPRESSION,
323
  /* XS_TOKEN_TEMPLATE_HEAD */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_CALL_EXPRESSION,
324
  /* XS_TOKEN_TEMPLATE_MIDDLE */ 0,
325
  /* XS_TOKEN_TEMPLATE_TAIL */ 0,
326
  /* XS_TOKEN_THIS */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
327
  /* XS_TOKEN_THROW */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
328
  /* XS_TOKEN_TRUE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
329
  /* XS_TOKEN_TRY */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
330
  /* XS_TOKEN_TYPEOF */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
331
  /* XS_TOKEN_UNDEFINED */ 0,
332
  /* XS_TOKEN_UNSIGNED_RIGHT_SHIFT */ XS_TOKEN_SHIFT_EXPRESSION,
333
  /* XS_TOKEN_UNSIGNED_RIGHT_SHIFT_ASSIGN */ XS_TOKEN_ASSIGN_EXPRESSION,
334
  /* XS_TOKEN_USING */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
335
  /* XS_TOKEN_VAR */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
336
  /* XS_TOKEN_VOID */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_UNARY_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME,
337
  /* XS_TOKEN_WHILE */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
338
  /* XS_TOKEN_WITH */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_IDENTIFIER_NAME,
339
  /* XS_TOKEN_YIELD */ XS_TOKEN_BEGIN_STATEMENT | XS_TOKEN_BEGIN_EXPRESSION | XS_TOKEN_IDENTIFIER_NAME
340
};
341
342
static txString const gxTokenNames[XS_TOKEN_COUNT] ICACHE_FLASH_ATTR = {
343
  /* XS_NO_TOKEN */ "",
344
  /* XS_TOKEN_ACCESS */ "access",
345
  /* XS_TOKEN_ADD */ "+",
346
  /* XS_TOKEN_ADD_ASSIGN */ "+=",
347
  /* XS_TOKEN_AND */ "&&",
348
  /* XS_TOKEN_AND_ASSIGN */ "&&=",
349
  /* XS_TOKEN_ARG */ "arg",
350
  /* XS_TOKEN_ARGUMENTS */ "arguments",
351
  /* XS_TOKEN_ARGUMENTS_SLOPPY */ "arguments_sloppy",
352
  /* XS_TOKEN_ARGUMENTS_STRICT */ "arguments_strict",
353
  /* XS_TOKEN_ARRAY */ "array",
354
  /* XS_TOKEN_ARRAY_BINDING */ "array_binding",
355
  /* XS_TOKEN_ARROW */ "=>",
356
  /* XS_TOKEN_ASSIGN */ "=",
357
  /* XS_TOKEN_AWAIT */ "await",
358
  /* XS_TOKEN_BIGINT */ "bigint",
359
  /* XS_TOKEN_BINDING */ "binding",
360
  /* XS_TOKEN_BIT_AND */ "&",
361
  /* XS_TOKEN_BIT_AND_ASSIGN */ "&=",
362
  /* XS_TOKEN_BIT_NOT */ "~",
363
  /* XS_TOKEN_BIT_OR */ "|",
364
  /* XS_TOKEN_BIT_OR_ASSIGN */ "|=",
365
  /* XS_TOKEN_BIT_XOR */ "^",
366
  /* XS_TOKEN_BIT_XOR_ASSIGN */ "^=",
367
  /* XS_TOKEN_BLOCK */ "block",
368
  /* XS_TOKEN_BODY */ "body",
369
  /* XS_TOKEN_BREAK */ "break",
370
  /* XS_TOKEN_CALL */ "call",
371
  /* XS_TOKEN_CASE */ "case",
372
  /* XS_TOKEN_CATCH */ "catch",
373
  /* XS_TOKEN_CHAIN */ "?.",
374
  /* XS_TOKEN_CLASS */ "class",
375
  /* XS_TOKEN_COALESCE */ "??",
376
  /* XS_TOKEN_COALESCE_ASSIGN */ "\?\?=",
377
  /* XS_TOKEN_COLON */ ":",
378
  /* XS_TOKEN_COMMA */ ",",
379
  /* XS_TOKEN_CONST */ "const",
380
  /* XS_TOKEN_CONTINUE */ "continue",
381
  /* XS_TOKEN_CURRENT */ "current",
382
  /* XS_TOKEN_DEBUGGER */ "debugger",
383
  /* XS_TOKEN_DECREMENT */ "--",
384
  /* XS_TOKEN_DEFAULT */ "default",
385
  /* XS_TOKEN_DEFINE */ "define",
386
  /* XS_TOKEN_DELEGATE */ "delegate",
387
  /* XS_TOKEN_DELETE */ "delete",
388
  /* XS_TOKEN_DIVIDE */ "/",
389
  /* XS_TOKEN_DIVIDE_ASSIGN */ "/=",
390
  /* XS_TOKEN_DO */ "do",
391
  /* XS_TOKEN_DOT */ ".",
392
  /* XS_TOKEN_ELISION */ "elision",
393
  /* XS_TOKEN_ELSE */ "else",
394
  /* XS_TOKEN_ENUM */ "enum",
395
  /* XS_TOKEN_EOF */ "",
396
  /* XS_TOKEN_EQUAL */ "==",
397
  /* XS_TOKEN_EVAL */ "eval",
398
  /* XS_TOKEN_EXPONENTIATION */ "**",
399
  /* XS_TOKEN_EXPONENTIATION_ASSIGN */ "**=",
400
  /* XS_TOKEN_EXPORT */ "export",
401
  /* XS_TOKEN_EXPRESSIONS */ "expressions",
402
  /* XS_TOKEN_EXTENDS */ "extends",
403
  /* XS_TOKEN_FALSE */ "false",
404
  /* XS_TOKEN_FIELD */ "field",
405
  /* XS_TOKEN_FINALLY */ "finally",
406
  /* XS_TOKEN_FOR */ "for",
407
  /* XS_TOKEN_FOR_AWAIT_OF */ "for_await_of",
408
  /* XS_TOKEN_FOR_IN */ "for_in",
409
  /* XS_TOKEN_FOR_OF */ "for_of",
410
  /* XS_TOKEN_FUNCTION */ "function",
411
  /* XS_TOKEN_GENERATOR */ "generator",
412
  /* XS_TOKEN_GETTER */ "getter",
413
  /* XS_TOKEN_HOST */ "host", 
414
  /* XS_TOKEN_IDENTIFIER */ "identifier",
415
  /* XS_TOKEN_IF */ "if",
416
  /* XS_TOKEN_IMPLEMENTS */ "implements",
417
  /* XS_TOKEN_IMPORT */ "import",
418
  /* XS_TOKEN_IMPORT_CALL */ "import",
419
  /* XS_TOKEN_IMPORT_META */ "import.meta",
420
  /* XS_TOKEN_IN */ "in",
421
  /* XS_TOKEN_INCLUDE */ "include",
422
  /* XS_TOKEN_INCREMENT */ "++",
423
  /* XS_TOKEN_INSTANCEOF */ "instanceof",
424
  /* XS_TOKEN_INTEGER */ "integer",
425
  /* XS_TOKEN_INTERFACE */ "interface",
426
  /* XS_TOKEN_ITEMS */ "items",
427
  /* XS_TOKEN_LABEL */ "label",
428
  /* XS_TOKEN_LEFT_BRACE */ "{",
429
  /* XS_TOKEN_LEFT_BRACKET */ "[",
430
  /* XS_TOKEN_LEFT_PARENTHESIS */ "(",
431
  /* XS_TOKEN_LEFT_SHIFT */ "<<",
432
  /* XS_TOKEN_LEFT_SHIFT_ASSIGN */ "<<=",
433
  /* XS_TOKEN_LESS */ "<",
434
  /* XS_TOKEN_LESS_EQUAL */ "<=",
435
  /* XS_TOKEN_LET */ "let",
436
  /* XS_TOKEN_MEMBER */ "member",
437
  /* XS_TOKEN_MEMBER_AT */ "member_at",
438
  /* XS_TOKEN_MINUS */ "minus",
439
  /* XS_TOKEN_MODULE */ "module",
440
  /* XS_TOKEN_MODULO */ "%",
441
  /* XS_TOKEN_MODULO_ASSIGN */ "%=",
442
  /* XS_TOKEN_MORE */ ">",
443
  /* XS_TOKEN_MORE_EQUAL */ ">=",
444
  /* XS_TOKEN_MULTIPLY */ "*",
445
  /* XS_TOKEN_MULTIPLY_ASSIGN */ "*=",
446
  /* XS_TOKEN_NEW */ "new", 
447
  /* XS_TOKEN_NOT */ "!",
448
  /* XS_TOKEN_NOT_EQUAL */ "!=",
449
  /* XS_TOKEN_NULL */ "null", 
450
  /* XS_TOKEN_NUMBER */ "number",
451
  /* XS_TOKEN_OBJECT */ "object",
452
  /* XS_TOKEN_OBJECT_BINDING */ "object_binding",
453
  /* XS_TOKEN_OPTION */ "?.",
454
  /* XS_TOKEN_OR */ "||",
455
  /* XS_TOKEN_OR_ASSIGN */ "||=",
456
  /* XS_TOKEN_PACKAGE */ "package",
457
  /* XS_TOKEN_PARAMS */ "params",
458
  /* XS_TOKEN_PARAMS_BINDING */ "params_binding",
459
  /* XS_TOKEN_PLUS */ "plus",
460
  /* XS_TOKEN_PRIVATE */ "private",
461
  /* XS_TOKEN_PRIVATE_IDENTIFIER */ "private_identifier",
462
  /* XS_TOKEN_PRIVATE_MEMBER */ "private_member",
463
  /* XS_TOKEN_PRIVATE_PROPERTY */ "private_property",
464
  /* XS_TOKEN_PROGRAM */ "program",
465
  /* XS_TOKEN_PROPERTY */ "property",
466
  /* XS_TOKEN_PROPERTY_AT */ "property_at",
467
  /* XS_TOKEN_PROPERTY_BINDING */ "property_binding",
468
  /* XS_TOKEN_PROPERTY_BINDING_AT */ "property_binding_at",
469
  /* XS_TOKEN_PROTECTED */ "protected",
470
  /* XS_TOKEN_PUBLIC */ "public",
471
  /* XS_TOKEN_QUESTION_MARK */ "?",
472
  /* XS_TOKEN_REGEXP */ "regexp",
473
  /* XS_TOKEN_REST_BINDING */ "rest_binding",
474
  /* XS_TOKEN_RETURN */ "return",
475
  /* XS_TOKEN_RIGHT_BRACE */ "}",
476
  /* XS_TOKEN_RIGHT_BRACKET */ "]",
477
  /* XS_TOKEN_RIGHT_PARENTHESIS */ ")",
478
  /* XS_TOKEN_SEMICOLON */ ";",
479
  /* XS_TOKEN_SETTER */ "setter",
480
  /* XS_TOKEN_SHORT */ "short",
481
  /* XS_TOKEN_SIGNED_RIGHT_SHIFT */ ">>",
482
  /* XS_TOKEN_SIGNED_RIGHT_SHIFT_ASSIGN */ ">>=",
483
  /* XS_TOKEN_SKIP_BINDING */ "skip_binding",
484
  /* XS_TOKEN_SPECIFIER */ "specifier",
485
  /* XS_TOKEN_SPREAD */ "...",
486
  /* XS_TOKEN_STATEMENT */ "statement",
487
  /* XS_TOKEN_STATEMENTS */ "statements",
488
  /* XS_TOKEN_STATIC */ "static",
489
  /* XS_TOKEN_STRICT_EQUAL */ "===",
490
  /* XS_TOKEN_STRICT_NOT_EQUAL */ "!==",
491
  /* XS_TOKEN_STRING */ "string",
492
  /* XS_TOKEN_SUBTRACT */ "-",
493
  /* XS_TOKEN_SUBTRACT_ASSIGN */ "-=",
494
  /* XS_TOKEN_SUPER */ "super",
495
  /* XS_TOKEN_SWITCH */ "switch",
496
  /* XS_TOKEN_TARGET */ "target",
497
  /* XS_TOKEN_TEMPLATE */ "template",
498
  /* XS_TOKEN_TEMPLATE_HEAD */ "template_head",
499
  /* XS_TOKEN_TEMPLATE_MIDDLE */ "template_middle",
500
  /* XS_TOKEN_TEMPLATE_TAIL */ "template_tail",
501
  /* XS_TOKEN_THIS */ "this",
502
  /* XS_TOKEN_THROW */ "throw",
503
  /* XS_TOKEN_TRUE */ "true",
504
  /* XS_TOKEN_TRY */ "try",
505
  /* XS_TOKEN_TYPEOF */ "typeof",
506
  /* XS_TOKEN_UNDEFINED */ "undefined",
507
  /* XS_TOKEN_UNSIGNED_RIGHT_SHIFT */ ">>>",
508
  /* XS_TOKEN_UNSIGNED_RIGHT_SHIFT_ASSIGN */ ">>>=",
509
  /* XS_TOKEN_USIGN */ "using",
510
  /* XS_TOKEN_VAR */ "var",
511
  /* XS_TOKEN_VOID */ "void",
512
  /* XS_TOKEN_WHILE */ "while",
513
  /* XS_TOKEN_WITH */ "with",
514
  /* XS_TOKEN_YIELD */ "yield",
515
};
516
517
txBoolean fxIsKeyword(txParser* parser, txSymbol* keyword)
518
245k
{
519
245k
  txBoolean result = ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == keyword)) ? 1 : 0;
520
245k
  if (result) {
521
15.8k
    if (parser->states[0].escaped)
522
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
523
15.8k
  }
524
245k
  return result;
525
245k
}
526
527
txBoolean fxIsToken(txParser* parser, txToken theToken)
528
62.0k
{
529
62.0k
  txBoolean result = (parser->states[0].token == theToken) ? 1 : 0;
530
62.0k
  if (result) {
531
34.3k
    if (parser->states[0].escaped)
532
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
533
34.3k
  }
534
62.0k
  return result;
535
62.0k
}
536
537
void fxMatchToken(txParser* parser, txToken theToken)
538
4.08M
{
539
4.08M
  if (parser->states[0].token == theToken) {
540
4.02M
    if (parser->states[0].escaped)
541
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
542
4.02M
    fxGetNextToken(parser);
543
4.02M
  }
544
60.3k
  else
545
60.3k
    fxReportParserError(parser, parser->states[0].line, "missing %s", gxTokenNames[theToken]);
546
4.08M
}
547
548
txNode* fxPopNode(txParser* parser)
549
12.7k
{
550
12.7k
  txNode* node = parser->root;
551
12.7k
  parser->root = node->next;
552
12.7k
  node->next = NULL;
553
12.7k
  parser->nodeCount--;
554
12.7k
  return node;
555
12.7k
}
556
557
void fxPushNode(txParser* parser, txNode* node)
558
22.1M
{
559
22.1M
  node->next = parser->root;
560
22.1M
  parser->root = (txNode*)node;
561
22.1M
  parser->nodeCount++;
562
22.1M
}
563
564
void fxPushBigIntNode(txParser* parser, txBigInt* value, txInteger line)
565
68.8k
{
566
68.8k
  txBigIntNode* node = fxNewParserChunk(parser, sizeof(txBigIntNode));
567
68.8k
  node->description = &gxTokenDescriptions[XS_TOKEN_BIGINT];
568
68.8k
  node->path = parser->path;
569
68.8k
  node->line = line;
570
68.8k
  node->flags = 0;
571
68.8k
  node->value = *value;
572
68.8k
  fxPushNode(parser, (txNode*)node);
573
68.8k
}
574
575
void fxPushIndexNode(txParser* parser, txIndex value, txInteger line)
576
24.3k
{
577
24.3k
  if (((txInteger)value) >= 0)
578
24.3k
    fxPushIntegerNode(parser, (txInteger)value, line);
579
48
  else
580
48
    fxPushNumberNode(parser, value, line);
581
24.3k
}
582
583
void fxPushIntegerNode(txParser* parser, txInteger value, txInteger line)
584
4.96M
{
585
4.96M
  txIntegerNode* node = fxNewParserChunk(parser, sizeof(txIntegerNode));
586
4.96M
  node->description = &gxTokenDescriptions[XS_TOKEN_INTEGER];
587
4.96M
  node->path = parser->path;
588
4.96M
  node->line = line;
589
4.96M
  node->flags = 0;
590
4.96M
  node->value = value;
591
4.96M
  fxPushNode(parser, (txNode*)node);
592
4.96M
}
593
594
void fxPushNodeStruct(txParser* parser, txInteger count, txToken token, txInteger line)
595
11.5M
{
596
11.5M
  const txNodeDescription* description = &gxTokenDescriptions[token];
597
11.5M
  txNode* node;
598
11.5M
  if ((count > parser->nodeCount) || ((sizeof(txNode) + (count * sizeof(txNode*))) > (size_t)(description->size))) {
599
0
    fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[token]);
600
0
  }
601
11.5M
    node = fxNewParserChunkClear(parser, description->size);
602
11.5M
  node->description = description;
603
11.5M
  node->flags |= parser->flags & (mxStrictFlag | mxGeneratorFlag | mxAsyncFlag);
604
11.5M
  node->path = parser->path;
605
11.5M
  node->line = line;
606
11.5M
    parser->nodeCount -= count;
607
11.5M
  if (count) {
608
11.1M
    txNode** dst = (txNode**)&node[1];
609
11.1M
    txNode* src = parser->root;
610
29.4M
    while (count) {
611
18.2M
      txNode* next = src->next;
612
18.2M
      src->next = NULL;
613
18.2M
      count--;
614
18.2M
      if (src->description)
615
15.6M
        dst[count] = src;
616
2.65M
      else if (src->path)
617
2.39M
        dst[count] = (txNode*)(src->path);
618
18.2M
      src = next;
619
18.2M
    }
620
11.1M
    parser->root = src;
621
11.1M
  }
622
11.5M
  fxPushNode(parser, node);
623
11.5M
}
624
625
void fxPushNodeList(txParser* parser, txInteger count)
626
1.38M
{
627
1.38M
  txNodeList* list = fxNewParserChunk(parser, sizeof(txNodeList));
628
1.38M
  txNode* previous = NULL;
629
1.38M
  txNode* current = parser->root;
630
1.38M
  txNode* next;
631
1.38M
    parser->nodeCount -= count;
632
1.38M
  list->length = count;
633
3.13M
  while (count) {
634
1.74M
    next = current->next;
635
1.74M
    current->next = previous;
636
1.74M
    previous = current;
637
1.74M
    current = next;
638
1.74M
    count--;
639
1.74M
  }
640
1.38M
  parser->root = current;
641
1.38M
  list->description = &gxTokenDescriptions[XS_NO_TOKEN];
642
1.38M
  list->first = previous;
643
1.38M
  fxPushNode(parser, (txNode*)list);
644
1.38M
}
645
646
void fxPushNULL(txParser* parser)
647
495k
{
648
495k
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
649
495k
  fxPushNode(parser, (txNode*)node);
650
495k
}
651
652
void fxPushNumberNode(txParser* parser, txNumber value, txInteger line)
653
34.6k
{
654
34.6k
  txNumberNode* node = fxNewParserChunk(parser, sizeof(txNumberNode));
655
34.6k
  node->description = &gxTokenDescriptions[XS_TOKEN_NUMBER];
656
34.6k
  node->path = parser->path;
657
34.6k
  node->line = line;
658
34.6k
  node->flags = 0;
659
34.6k
  node->value = value;
660
34.6k
  fxPushNode(parser, (txNode*)node);
661
34.6k
}
662
663
void fxPushRawNode(txParser* parser, txInteger length, txString value, txInteger line)
664
353k
{
665
353k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
666
353k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
667
353k
  node->path = parser->path;
668
353k
  node->line = line;
669
353k
  node->flags = 0;
670
353k
  node->length = length;
671
353k
  node->value = value;
672
353k
  fxPushNode(parser, (txNode*)node);
673
353k
}
674
675
void fxPushStringNode(txParser* parser, txInteger length, txString value, txInteger line)
676
655k
{
677
655k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
678
655k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
679
655k
  node->path = parser->path;
680
655k
  node->line = line;
681
655k
  node->flags = parser->states[0].escaped;
682
655k
  node->length = length;
683
655k
  node->value = value;
684
655k
  fxPushNode(parser, (txNode*)node);
685
655k
}
686
687
void fxPushSymbol(txParser* parser, txSymbol* symbol)
688
2.58M
{
689
2.58M
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
690
2.58M
  node->symbol = symbol;  
691
2.58M
  fxPushNode(parser, (txNode*)node);
692
2.58M
}
693
694
void fxSwapNodes(txParser* parser)
695
55.2k
{
696
55.2k
  txNode* previous = parser->root;
697
55.2k
  txNode* current = previous->next;
698
55.2k
  previous->next = current->next;
699
55.2k
  current->next = previous;
700
55.2k
  parser->root = current;
701
55.2k
}
702
703
void fxModule(txParser* parser)
704
5.55k
{
705
5.55k
  txInteger aCount = parser->nodeCount;
706
5.55k
  txInteger aLine = parser->states[0].line;
707
17.1k
  while ((parser->states[0].token != XS_TOKEN_EOF)) {
708
11.6k
    if (parser->states[0].token == XS_TOKEN_EXPORT)
709
5.84k
      fxExportDeclaration(parser);
710
5.79k
    else if (parser->states[0].token == XS_TOKEN_IMPORT) {
711
338
      fxLookAheadOnce(parser);
712
338
      if ((parser->states[1].token == XS_TOKEN_DOT) || (parser->states[1].token == XS_TOKEN_LEFT_PARENTHESIS))
713
106
        fxStatement(parser, 1);
714
232
      else
715
232
        fxImportDeclaration(parser);
716
338
    }
717
5.45k
    else if (parser->states[0].token == XS_TOKEN_RETURN) {
718
1
      fxReportParserError(parser, parser->states[0].line, "invalid return");
719
1
      fxGetNextToken(parser);
720
1
    }
721
5.45k
    else if (parser->states[0].token == XS_TOKEN_YIELD) {
722
1
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
723
1
      fxGetNextToken(parser);
724
1
    }
725
5.45k
    else {
726
5.45k
      fxStatement(parser, 1);
727
5.45k
    }
728
11.6k
  }
729
5.55k
  aCount = parser->nodeCount - aCount;
730
5.55k
  if (aCount > 1) {
731
233
    fxPushNodeList(parser, aCount);
732
233
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
733
233
  }
734
5.31k
  else if (aCount == 0) {
735
2
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
736
2
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
737
2
  }
738
5.55k
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, aLine);
739
5.55k
  parser->root->flags = parser->flags & (mxStrictFlag | mxAwaitingFlag);
740
5.55k
}
741
742
void fxExportDeclaration(txParser* parser)
743
5.84k
{
744
5.84k
  txSymbol* symbol = C_NULL;
745
5.84k
  txInteger count;
746
5.84k
  txInteger line = parser->states[0].line;
747
5.84k
  txUnsigned flag = 0;
748
5.84k
  txToken aToken;
749
5.84k
  fxMatchToken(parser, XS_TOKEN_EXPORT);
750
5.84k
  switch (parser->states[0].token) {
751
49
  case XS_TOKEN_MULTIPLY:
752
49
    fxPushNULL(parser);
753
49
    fxGetNextToken(parser);
754
49
    if (fxIsKeyword(parser, parser->asSymbol)) {
755
34
      fxGetNextToken(parser);
756
34
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
757
33
        fxPushSymbol(parser, parser->states[0].symbol);
758
33
        fxGetNextToken(parser);
759
33
      }
760
1
      else {
761
1
        fxPushNULL(parser);
762
1
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
763
1
      }
764
34
    }
765
15
    else {
766
15
      fxPushNULL(parser);
767
15
    }
768
49
    if (fxIsKeyword(parser, parser->fromSymbol)) {
769
46
      fxGetNextToken(parser);
770
46
      if (parser->states[0].token == XS_TOKEN_STRING) {
771
45
        fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
772
45
        fxPushNodeList(parser, 1);
773
45
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
774
45
        fxGetNextToken(parser);
775
45
        if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
776
1
          fxGetNextToken(parser);
777
1
          fxWithAttributes(parser);
778
1
        }
779
44
        else
780
44
          fxPushNULL(parser);
781
45
        fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
782
45
        fxSemicolon(parser);
783
45
      }
784
1
      else
785
1
        fxReportParserError(parser, parser->states[0].line, "missing module");
786
46
    }
787
3
    else
788
3
      fxReportParserError(parser, parser->states[0].line, "missing from");
789
49
    break;
790
210
  case XS_TOKEN_DEFAULT:
791
210
    fxMatchToken(parser, XS_TOKEN_DEFAULT);
792
210
    if (parser->flags & mxDefaultFlag)
793
1
      fxReportParserError(parser, parser->states[0].line, "invalid default");
794
210
    parser->flags |= mxDefaultFlag;
795
210
    if (parser->states[0].token == XS_TOKEN_CLASS) {
796
0
      fxClassExpression(parser, line, &symbol);
797
0
      if (symbol)
798
0
        fxPushSymbol(parser, symbol);
799
0
      else
800
0
        fxPushSymbol(parser, parser->defaultSymbol);
801
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_LET, line);
802
0
      fxSwapNodes(parser);
803
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, line);
804
0
    }
805
210
    else if (parser->states[0].token == XS_TOKEN_FUNCTION) {
806
0
  again:
807
0
      fxMatchToken(parser, XS_TOKEN_FUNCTION);
808
0
      if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
809
0
        fxGetNextToken(parser);
810
0
        fxGeneratorExpression(parser, line, &symbol, flag);
811
0
      }
812
0
      else
813
0
        fxFunctionExpression(parser, line, &symbol, flag);
814
0
      if (symbol) {
815
0
        txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
816
0
        node->initializer = fxPopNode(parser);
817
0
        fxPushNode(parser, (txNode*)node);
818
0
      }
819
0
      else {
820
0
        txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, parser->defaultSymbol);
821
0
        node->initializer = fxPopNode(parser);
822
0
        fxPushNode(parser, (txNode*)node);
823
0
      }
824
0
    }
825
210
    else {
826
210
      if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped)) {
827
0
        fxLookAheadOnce(parser);
828
0
        if ((!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_FUNCTION)) {
829
0
          fxGetNextToken(parser);
830
0
          flag = mxAsyncFlag;
831
0
          goto again;         
832
0
        }
833
0
      }
834
210
      fxAssignmentExpression(parser);
835
210
      fxSemicolon(parser);
836
210
      fxPushSymbol(parser, parser->defaultSymbol);
837
210
      fxPushNULL(parser);
838
210
      fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, line);
839
210
      fxSwapNodes(parser);
840
210
      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, line);
841
210
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
842
210
    }
843
210
    if (symbol) {
844
0
      fxPushSymbol(parser, symbol);
845
0
      fxPushSymbol(parser, parser->defaultSymbol);
846
0
    }
847
210
    else {
848
210
      fxPushSymbol(parser, parser->defaultSymbol);
849
210
      fxPushNULL(parser);
850
210
    }
851
210
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
852
210
    fxPushNodeList(parser, 1);
853
210
    fxPushNULL(parser);
854
210
    fxPushNULL(parser);
855
210
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
856
210
    break;
857
0
  case XS_TOKEN_CLASS:
858
0
    fxClassExpression(parser, line, &symbol);
859
0
    if (symbol) {
860
0
      fxPushSymbol(parser, symbol);
861
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_LET, line);
862
0
      fxSwapNodes(parser);
863
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, line);
864
      
865
0
      fxPushSymbol(parser, symbol);
866
0
      fxPushNULL(parser);
867
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
868
0
      fxPushNodeList(parser, 1);
869
0
      fxPushNULL(parser);
870
0
      fxPushNULL(parser);
871
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
872
0
    }
873
0
    else
874
0
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
875
0
    break;
876
1
  case XS_TOKEN_FUNCTION:
877
1
  again2:
878
1
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
879
1
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
880
0
      fxGetNextToken(parser);
881
0
      fxGeneratorExpression(parser, line, &symbol, flag);
882
0
    }
883
1
    else
884
1
      fxFunctionExpression(parser, line, &symbol, flag);
885
1
    if (symbol) {
886
0
      txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
887
0
      node->initializer = fxPopNode(parser);
888
0
      fxPushNode(parser, (txNode*)node);
889
0
      fxPushSymbol(parser, symbol);
890
0
      fxPushNULL(parser);
891
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
892
0
      fxPushNodeList(parser, 1);
893
0
      fxPushNULL(parser);
894
0
      fxPushNULL(parser);
895
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
896
0
    }
897
1
    else
898
1
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
899
1
    break;
900
113
  case XS_TOKEN_CONST:
901
224
  case XS_TOKEN_LET:
902
293
  case XS_TOKEN_VAR:
903
293
    aToken = parser->states[0].token;
904
293
    fxVariableStatement(parser, aToken, 0);
905
293
    count = parser->nodeCount;
906
293
    fxExportBinding(parser, parser->root);
907
293
    fxPushNodeList(parser, parser->nodeCount - count);
908
293
    fxPushNULL(parser);
909
293
    fxPushNULL(parser);
910
293
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
911
293
    fxSemicolon(parser);
912
293
    break;
913
5.06k
  case XS_TOKEN_LEFT_BRACE:
914
5.06k
    count = parser->nodeCount;
915
5.06k
    fxSpecifiers(parser);
916
5.06k
    fxPushNodeList(parser, parser->nodeCount - count);
917
5.06k
    if (fxIsKeyword(parser, parser->fromSymbol)) {
918
42
      fxGetNextToken(parser);
919
42
      if (parser->states[0].token == XS_TOKEN_STRING) {
920
40
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
921
40
        fxGetNextToken(parser);
922
40
      }
923
2
      else {
924
2
        fxPushNULL(parser);
925
2
        fxReportParserError(parser, parser->states[0].line, "missing module");
926
2
      }
927
42
      if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
928
0
        fxGetNextToken(parser);
929
0
        fxWithAttributes(parser);
930
0
      }
931
42
      else
932
42
        fxPushNULL(parser);
933
42
    }
934
5.02k
    else {
935
5.02k
      fxPushNULL(parser);
936
5.02k
      fxPushNULL(parser);
937
5.02k
    }
938
5.06k
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
939
5.06k
    fxSemicolon(parser);
940
5.06k
    break;
941
233
  default:
942
233
    if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped)) {
943
0
      fxLookAheadOnce(parser);
944
0
      if ((!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_FUNCTION)) {
945
0
        fxGetNextToken(parser);
946
0
        flag = mxAsyncFlag;
947
0
        goto again2;          
948
0
      }
949
0
    }
950
233
    fxReportParserError(parser, parser->states[0].line, "invalid export %s", gxTokenNames[parser->states[0].token]);
951
233
    fxGetNextToken(parser);
952
233
    break;
953
5.84k
  }
954
5.84k
}
955
956
void fxExportBinding(txParser* parser, txNode* node)
957
549
{
958
549
  txToken token = node->description->token;
959
549
  if ((token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_VAR)) {
960
309
    fxPushSymbol(parser, ((txDeclareNode*)node)->symbol);
961
309
    fxPushNULL(parser);
962
309
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, node->line);
963
309
  }
964
240
  else if (token == XS_TOKEN_BINDING) {
965
219
    fxExportBinding(parser, ((txBindingNode*)node)->target);
966
219
  }
967
21
  else if (token == XS_TOKEN_ARRAY_BINDING) {
968
0
    node = ((txArrayBindingNode*)node)->items->first;
969
0
    while (node) {
970
0
      fxExportBinding(parser, node);
971
0
      node = node->next;
972
0
    }
973
0
  }
974
21
  else if (token == XS_TOKEN_OBJECT_BINDING) {
975
4
    node = ((txObjectBindingNode*)node)->items->first;
976
8
    while (node) {
977
4
      fxExportBinding(parser, node);
978
4
      node = node->next;
979
4
    }
980
4
  }
981
17
  else if (token == XS_TOKEN_PROPERTY_BINDING)
982
3
    fxExportBinding(parser, ((txPropertyBindingNode*)node)->binding);
983
14
  else if (token == XS_TOKEN_PROPERTY_BINDING_AT)
984
1
    fxExportBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
985
13
  else if (token == XS_TOKEN_REST_BINDING)
986
0
    fxExportBinding(parser, ((txRestBindingNode*)node)->binding);
987
13
  else if (token == XS_TOKEN_STATEMENTS) {
988
13
    node = ((txStatementsNode*)node)->items->first;
989
43
    while (node) {
990
30
      fxExportBinding(parser, node);
991
30
      node = node->next;
992
30
    }
993
13
  }
994
549
}
995
996
997
void fxImportDeclaration(txParser* parser)
998
232
{
999
232
  txBoolean asFlag = 1;
1000
232
  txBoolean fromFlag = 0;
1001
232
  txInteger count = parser->nodeCount;
1002
232
  fxMatchToken(parser, XS_TOKEN_IMPORT);
1003
232
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1004
109
    fxPushSymbol(parser, parser->defaultSymbol);
1005
109
    fxPushSymbol(parser, parser->states[0].symbol);
1006
109
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1007
109
    fxGetNextToken(parser);
1008
109
    if (parser->states[0].token == XS_TOKEN_COMMA)
1009
1
      fxGetNextToken(parser);
1010
108
    else
1011
108
      asFlag = 0;
1012
109
    fromFlag = 1;
1013
109
  }
1014
232
  if (asFlag) {
1015
124
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1016
51
      fxGetNextToken(parser);
1017
51
      if (fxIsKeyword(parser, parser->asSymbol)) {
1018
49
        fxGetNextToken(parser);
1019
49
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1020
48
          fxPushNULL(parser);
1021
48
          fxPushSymbol(parser, parser->states[0].symbol);
1022
48
          fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1023
48
          fxGetNextToken(parser);
1024
48
        }
1025
1
        else {
1026
1
          fxReportParserError(parser, parser->states[0].line, "missing identifier");
1027
1
        }
1028
49
      }
1029
2
      else {
1030
2
        fxReportParserError(parser, parser->states[0].line, "missing as");
1031
2
      }
1032
51
      fromFlag = 1;
1033
51
    }
1034
73
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
1035
37
      fxSpecifiers(parser);
1036
37
      fromFlag = 1;
1037
37
    }
1038
124
  }
1039
232
  fxPushNodeList(parser, parser->nodeCount - count);
1040
232
  if (fromFlag) {
1041
193
    if (fxIsKeyword(parser, parser->fromSymbol)) {
1042
188
      fxGetNextToken(parser);
1043
188
      if (parser->states[0].token == XS_TOKEN_STRING) {
1044
187
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1045
187
        fxGetNextToken(parser);
1046
187
      }
1047
1
      else {
1048
1
        fxPushNULL(parser);
1049
1
        fxReportParserError(parser, parser->states[0].line, "missing module");
1050
1
      }
1051
188
    }
1052
5
    else {
1053
5
      fxPushNULL(parser);
1054
5
      fxReportParserError(parser, parser->states[0].line, "missing from");
1055
5
    }
1056
193
  }
1057
39
  else if (parser->states[0].token == XS_TOKEN_STRING) {
1058
32
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1059
32
    fxGetNextToken(parser);
1060
32
  }
1061
7
  else {
1062
7
    fxPushNULL(parser);
1063
7
    fxReportParserError(parser, parser->states[0].line, "missing module");
1064
7
  }
1065
232
  if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
1066
1
    fxGetNextToken(parser);
1067
1
    fxWithAttributes(parser);
1068
1
  }
1069
231
  else
1070
231
    fxPushNULL(parser);
1071
232
  fxPushNodeStruct(parser, 3, XS_TOKEN_IMPORT, parser->states[0].line);
1072
232
  fxSemicolon(parser);
1073
232
}
1074
1075
void fxSpecifiers(txParser* parser)
1076
5.09k
{
1077
//  txInteger aCount = 0;
1078
5.09k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1079
6.08k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1080
5.09k
    fxPushSymbol(parser, parser->states[0].symbol);
1081
5.09k
    fxGetNextToken(parser);
1082
5.09k
    if (fxIsKeyword(parser, parser->asSymbol)) {
1083
2.78k
      fxGetNextToken(parser);
1084
2.78k
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1085
1.80k
        fxPushSymbol(parser, parser->states[0].symbol);
1086
1.80k
        fxGetNextToken(parser);
1087
1.80k
      }
1088
973
      else {
1089
973
        fxPushNULL(parser);
1090
973
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
1091
973
      }
1092
2.78k
    }
1093
2.31k
    else
1094
2.31k
      fxPushNULL(parser);
1095
5.09k
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1096
//    aCount++;
1097
5.09k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
1098
4.10k
      break;
1099
990
    fxGetNextToken(parser);
1100
990
  }
1101
5.09k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1102
5.09k
}
1103
1104
void fxWithAttributes(txParser* parser)
1105
2
{
1106
2
  txBoolean flag = 0;
1107
2
  txString string;
1108
2
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1109
2
  while (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
1110
0
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME))
1111
0
      string = parser->states[0].symbol->string;
1112
0
    else if (parser->states[0].token == XS_TOKEN_STRING)
1113
0
      string = parser->states[0].string;
1114
0
    else {
1115
0
      fxReportParserError(parser, parser->states[0].line, "missing attribute key");
1116
0
      break;
1117
0
    }
1118
0
    if (c_strcmp(string, "type"))
1119
0
      fxReportParserError(parser, parser->states[0].line, "invalid attribute key");
1120
0
    else if (flag)
1121
0
      fxReportParserError(parser, parser->states[0].line, "duplicate attribute");
1122
0
    fxGetNextToken(parser);
1123
0
    if (parser->states[0].token != XS_TOKEN_COLON) {
1124
0
      fxReportParserError(parser, parser->states[0].line, "missing :");
1125
0
      break;
1126
0
    }
1127
0
        fxGetNextToken(parser);
1128
0
    if (parser->states[0].token == XS_TOKEN_STRING)
1129
0
      string = parser->states[0].string;
1130
0
    else {
1131
0
      fxReportParserError(parser, parser->states[0].line, "missing attribute value");
1132
0
      break;
1133
0
    }
1134
0
    if (c_strcmp(string, "json"))
1135
0
      fxReportParserError(parser, parser->states[0].line, "invalid attribute value");
1136
0
    flag = 1;
1137
0
    fxGetNextToken(parser);
1138
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
1139
0
      break;
1140
0
    fxGetNextToken(parser);
1141
0
  }
1142
2
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1143
2
  if (flag)
1144
0
    fxPushSymbol(parser, parser->jsonSymbol);
1145
2
  else
1146
2
    fxPushNULL(parser);
1147
2
}
1148
1149
void fxProgram(txParser* parser)
1150
594k
{
1151
594k
  txInteger count = parser->nodeCount;
1152
594k
  txInteger line = parser->states[0].line;
1153
594k
  txNode* node;
1154
842k
  while (parser->states[0].token != XS_TOKEN_EOF) {
1155
605k
    fxStatement(parser, -1);
1156
605k
    node = parser->root;
1157
605k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1158
64.0k
      break;
1159
540k
    node = ((txStatementNode*)node)->expression;
1160
540k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1161
292k
      break;
1162
248k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1163
10.3k
      if (!(parser->flags & mxStrictFlag)) {
1164
10.2k
        parser->flags |= mxStrictFlag;
1165
10.2k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1166
9.39k
          fxCheckStrictKeyword(parser);
1167
10.2k
      }
1168
10.3k
    }
1169
248k
  }
1170
1.07M
  while (parser->states[0].token != XS_TOKEN_EOF) {
1171
475k
    fxStatement(parser, -1);
1172
475k
  }
1173
594k
  count = parser->nodeCount - count;
1174
594k
  if (count > 1) {
1175
36.7k
    fxPushNodeList(parser, count);
1176
36.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1177
36.7k
  }
1178
557k
  else if (count == 0) {
1179
1.07k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1180
1.07k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1181
1.07k
  }
1182
594k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PROGRAM, line);
1183
594k
  if (parser->flags & mxFieldFlag)
1184
0
    if (parser->flags & mxArgumentsFlag)
1185
0
      fxReportParserError(parser, parser->states[0].line, "invalid arguments");
1186
594k
  parser->root->flags = parser->flags & mxStrictFlag;
1187
594k
}
1188
1189
void fxBody(txParser* parser)
1190
292k
{
1191
292k
  txInteger count = parser->nodeCount;
1192
292k
  txInteger line = parser->states[0].line;
1193
292k
  txNode* node;
1194
292k
    fxCheckParserStack(parser, line);
1195
385k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1196
272k
    fxStatement(parser, 1);
1197
272k
    node = parser->root;
1198
272k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1199
60.3k
      break;
1200
212k
    node = ((txStatementNode*)node)->expression;
1201
212k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1202
119k
      break;
1203
92.5k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1204
7.52k
      if (parser->flags & mxNotSimpleParametersFlag)
1205
1
        fxReportParserError(parser, parser->states[0].line, "invalid directive");
1206
7.52k
      if (!(parser->flags & mxStrictFlag)) {
1207
7.46k
        parser->flags |= mxStrictFlag;
1208
7.46k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1209
1.82k
          fxCheckStrictKeyword(parser);
1210
7.46k
      }
1211
7.52k
    }
1212
92.5k
  }
1213
553k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1214
260k
    fxStatement(parser, 1);
1215
260k
  }
1216
292k
  count = parser->nodeCount - count;
1217
292k
  if (count > 1) {
1218
24.7k
    fxPushNodeList(parser, count);
1219
24.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1220
24.7k
  }
1221
268k
  else if (count == 0) {
1222
30.8k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1223
30.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1224
30.8k
  }
1225
292k
}
1226
1227
void fxBlock(txParser* parser)
1228
93.2k
{
1229
93.2k
  txInteger aLine = parser->states[0].line;
1230
93.2k
  fxCheckParserStack(parser, aLine);
1231
93.2k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1232
93.2k
  fxStatements(parser);
1233
93.2k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1234
93.2k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BLOCK, aLine);
1235
93.2k
}
1236
1237
void fxStatements(txParser* parser)
1238
127k
{
1239
127k
  txInteger count = parser->nodeCount;
1240
127k
  txInteger line = parser->states[0].line;
1241
265k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1242
137k
    fxStatement(parser, 1);
1243
137k
  }
1244
127k
  count = parser->nodeCount - count;
1245
127k
  fxPushNodeList(parser, count);
1246
127k
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1247
127k
}
1248
1249
void fxStatement(txParser* parser, txInteger blockIt)
1250
1.90M
{
1251
1.90M
  txInteger line = parser->states[0].line;
1252
1.90M
  txSymbol* symbol = C_NULL;
1253
1.90M
  txUnsigned flag = 0;
1254
1.90M
  switch (parser->states[0].token) {
1255
//  case XS_TOKEN_COMMA:
1256
87.6k
  case XS_TOKEN_SEMICOLON:
1257
87.6k
    fxGetNextToken(parser);
1258
87.6k
    if (!blockIt) {
1259
914
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1260
914
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1261
914
    }
1262
87.6k
    break;
1263
3.85k
  case XS_TOKEN_BREAK:
1264
3.85k
    fxBreakStatement(parser);
1265
3.85k
    fxSemicolon(parser);
1266
3.85k
    break;
1267
49.3k
  case XS_TOKEN_CLASS:
1268
49.3k
    if (!blockIt)
1269
200
      fxReportParserError(parser, parser->states[0].line, "no block");
1270
49.3k
    fxClassExpression(parser, line, &symbol);
1271
49.3k
    if (symbol) {
1272
4.81k
      fxPushSymbol(parser, symbol);
1273
4.81k
      fxPushNodeStruct(parser, 1, XS_TOKEN_LET, line);
1274
4.81k
      fxSwapNodes(parser);
1275
4.81k
      fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, line);
1276
4.81k
    }
1277
44.5k
    else
1278
44.5k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1279
49.3k
    break;
1280
21.9k
  case XS_TOKEN_CONST:
1281
21.9k
    if (!blockIt)
1282
8
      fxReportParserError(parser, parser->states[0].line, "no block");
1283
21.9k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1284
21.9k
    fxSemicolon(parser);
1285
21.9k
    break;
1286
6.92k
  case XS_TOKEN_CONTINUE:
1287
6.92k
    fxContinueStatement(parser);
1288
6.92k
    fxSemicolon(parser);
1289
6.92k
    break;
1290
582
  case XS_TOKEN_DEBUGGER:
1291
582
    fxDebuggerStatement(parser);
1292
582
    fxSemicolon(parser);
1293
582
    break;
1294
53.0k
  case XS_TOKEN_DO:
1295
53.0k
    fxDoStatement(parser);
1296
53.0k
    break;
1297
56.2k
  case XS_TOKEN_FOR:
1298
56.2k
    fxForStatement(parser);
1299
56.2k
    break;
1300
3.80k
  case XS_TOKEN_FUNCTION:
1301
    //if ((parser->flags & mxStrictFlag) && !blockIt) BROWSER
1302
4.30k
  again:
1303
4.30k
    if (!blockIt)
1304
382
      fxReportParserError(parser, parser->states[0].line, "no block (strict code)");
1305
4.30k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
1306
4.30k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1307
712
      fxGetNextToken(parser);
1308
712
      fxGeneratorExpression(parser, line, &symbol, flag);
1309
712
    }
1310
3.59k
    else
1311
3.59k
      fxFunctionExpression(parser, line, &symbol, flag);
1312
4.30k
    if (symbol) {
1313
2.75k
      txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
1314
2.75k
      node->initializer = fxPopNode(parser);
1315
2.75k
      fxPushNode(parser, (txNode*)node);
1316
2.75k
    }
1317
1.55k
    else
1318
1.55k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1319
4.30k
    break;
1320
9.00k
  case XS_TOKEN_IF:
1321
9.00k
    fxIfStatement(parser);
1322
9.00k
    break;
1323
14.4k
  case XS_TOKEN_RETURN:
1324
14.4k
    if (!(parser->flags & (mxArrowFlag | mxFunctionFlag | mxGeneratorFlag)))
1325
378
      fxReportParserError(parser, parser->states[0].line, "invalid return");
1326
14.4k
    fxReturnStatement(parser);
1327
14.4k
    fxSemicolon(parser);
1328
14.4k
    break;
1329
85.2k
  case XS_TOKEN_LEFT_BRACE:
1330
85.2k
    fxBlock(parser);
1331
85.2k
    break;
1332
3.02k
  case XS_TOKEN_LET:
1333
3.02k
    if (!blockIt)
1334
3
      fxReportParserError(parser, parser->states[0].line, "no block");
1335
3.02k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1336
3.02k
    fxSemicolon(parser);
1337
3.02k
    break;
1338
6.28k
  case XS_TOKEN_SWITCH:
1339
6.28k
    fxSwitchStatement(parser);
1340
6.28k
    break;
1341
17.5k
  case XS_TOKEN_THROW:
1342
17.5k
    fxThrowStatement(parser);
1343
17.5k
    fxSemicolon(parser);
1344
17.5k
    break;
1345
8.35k
  case XS_TOKEN_TRY:
1346
8.35k
    fxTryStatement(parser);
1347
8.35k
    break;
1348
90.7k
  case XS_TOKEN_VAR:
1349
90.7k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1350
90.7k
    fxSemicolon(parser);
1351
90.7k
    break;
1352
2.69k
  case XS_TOKEN_WHILE:
1353
2.69k
    fxWhileStatement(parser);
1354
2.69k
    break;
1355
5.04k
  case XS_TOKEN_WITH:
1356
5.04k
    if (parser->flags & mxStrictFlag)
1357
49
      fxReportParserError(parser, parser->states[0].line, "with (strict code)");
1358
5.04k
    fxWithStatement(parser);
1359
5.04k
    break;
1360
0
#if mxExplicitResourceManagement
1361
89
  case XS_TOKEN_AWAIT:
1362
89
    fxLookAheadOnce(parser);
1363
89
    if ((!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_IDENTIFIER) && (parser->states[1].symbol == parser->usingSymbol) && (!parser->states[1].escaped)) {
1364
0
      fxLookAheadTwice(parser);
1365
0
      if ((!parser->states[2].crlf) && ((parser->states[2].token == XS_TOKEN_IDENTIFIER) || (parser->states[2].token == XS_TOKEN_AWAIT) || (parser->states[2].token == XS_TOKEN_YIELD))) {
1366
0
        fxGetNextToken(parser);
1367
0
        parser->states[0].token = XS_TOKEN_USING;
1368
0
        if (blockIt <= 0)
1369
0
          fxReportParserError(parser, parser->states[0].line, "no block");
1370
0
        fxVariableStatement(parser, XS_TOKEN_USING, mxAwaitingFlag);
1371
0
        parser->flags |= mxAwaitingFlag;
1372
0
        fxSemicolon(parser);
1373
0
        break;
1374
0
      }
1375
0
    }
1376
89
    fxCommaExpression(parser);
1377
89
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1378
89
    fxSemicolon(parser);
1379
89
    break;
1380
0
#endif
1381
871k
  case XS_TOKEN_IDENTIFIER:
1382
871k
    fxLookAheadOnce(parser);
1383
871k
    if (parser->states[1].token == XS_TOKEN_COLON) {
1384
41.6k
      fxPushSymbol(parser, parser->states[0].symbol);
1385
41.6k
      fxGetNextToken(parser);
1386
41.6k
      fxMatchToken(parser, XS_TOKEN_COLON);
1387
      //if ((parser->flags & mxStrictFlag) && (parser->states[0].token == XS_TOKEN_FUNCTION)) BROWSER
1388
      //  fxReportParserError(parser, parser->states[0].line, "labeled function (strict code)");
1389
41.6k
      if (parser->states[0].token == XS_TOKEN_FUNCTION)
1390
701
        fxReportParserError(parser, parser->states[0].line, "labeled function");
1391
41.6k
      fxCheckParserStack(parser, line);
1392
41.6k
      fxStatement(parser, 0);
1393
41.6k
      fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, line);
1394
41.6k
      break;
1395
41.6k
    }
1396
829k
    if ((parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped) 
1397
656
        && (!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_FUNCTION)) {
1398
505
      fxGetNextToken(parser);
1399
505
      flag = mxAsyncFlag;
1400
505
      goto again;
1401
505
    }
1402
829k
    if ((parser->states[0].symbol == parser->letSymbol) && (!parser->states[0].escaped) 
1403
44.3k
        && ((gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING) || (parser->states[1].token == XS_TOKEN_AWAIT) || (parser->states[1].token == XS_TOKEN_YIELD))
1404
41.7k
        && (blockIt || (!parser->states[1].crlf) || (parser->states[1].token == XS_TOKEN_LEFT_BRACKET))) {
1405
41.7k
      parser->states[0].token = XS_TOKEN_LET;
1406
41.7k
      if (!blockIt)
1407
12
        fxReportParserError(parser, parser->states[0].line, "no block");
1408
41.7k
      fxVariableStatement(parser, XS_TOKEN_LET, 0);
1409
41.7k
      fxSemicolon(parser);
1410
41.7k
      break;
1411
41.7k
    }
1412
787k
#if mxExplicitResourceManagement
1413
787k
    if ((parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1414
1.12k
        && (!parser->states[1].crlf) && ((parser->states[1].token == XS_TOKEN_IDENTIFIER) || (parser->states[1].token == XS_TOKEN_AWAIT) || (parser->states[1].token == XS_TOKEN_YIELD))) {
1415
571
      parser->states[0].token = XS_TOKEN_USING;
1416
571
      if (blockIt <= 0)
1417
80
        fxReportParserError(parser, parser->states[0].line, "no block");
1418
571
      fxVariableStatement(parser, XS_TOKEN_USING, 0);
1419
571
      fxSemicolon(parser);
1420
571
      break;
1421
571
    }
1422
786k
#endif
1423
    /* continue */
1424
1.29M
  default:
1425
1.29M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1426
1.23M
      fxCommaExpression(parser);
1427
1.23M
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1428
1.23M
      fxSemicolon(parser);
1429
1.23M
    }
1430
65.3k
    else {
1431
65.3k
      fxReportParserError(parser, parser->states[0].line, "invalid token %s", gxTokenNames[parser->states[0].token]);
1432
65.3k
      fxPushNULL(parser);
1433
65.3k
      fxGetNextToken(parser);
1434
65.3k
    }
1435
1.29M
    break;
1436
1.90M
  }
1437
1.90M
}
1438
1439
void fxSemicolon(txParser* parser)
1440
1.08M
{
1441
1.08M
  if ((parser->states[0].crlf) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_END_STATEMENT)) {
1442
1.03M
    if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1443
322k
      fxGetNextToken(parser);
1444
1.03M
  }
1445
49.7k
  else
1446
49.7k
    fxReportParserError(parser, parser->states[0].line, "missing ;");
1447
1.08M
}
1448
1449
void fxBreakStatement(txParser* parser)
1450
3.85k
{
1451
3.85k
  txInteger aLine = parser->states[0].line;
1452
3.85k
  fxMatchToken(parser, XS_TOKEN_BREAK);
1453
3.85k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1454
633
    fxPushSymbol(parser, parser->states[0].symbol);
1455
633
    fxGetNextToken(parser);
1456
633
  }
1457
3.22k
  else {
1458
3.22k
    fxPushNULL(parser);
1459
3.22k
  }
1460
3.85k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BREAK, aLine);
1461
3.85k
}
1462
1463
void fxContinueStatement(txParser* parser)
1464
6.92k
{
1465
6.92k
  txInteger aLine = parser->states[0].line;
1466
6.92k
  fxMatchToken(parser, XS_TOKEN_CONTINUE);
1467
6.92k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1468
1.58k
    fxPushSymbol(parser, parser->states[0].symbol);
1469
1.58k
    fxGetNextToken(parser);
1470
1.58k
  }
1471
5.34k
  else {
1472
5.34k
    fxPushNULL(parser);
1473
5.34k
  }
1474
6.92k
  fxPushNodeStruct(parser, 1, XS_TOKEN_CONTINUE, aLine);
1475
6.92k
}
1476
1477
void fxDebuggerStatement(txParser* parser)
1478
582
{
1479
582
  txInteger aLine = parser->states[0].line;
1480
582
  fxMatchToken(parser, XS_TOKEN_DEBUGGER);
1481
582
  fxPushNodeStruct(parser, 0, XS_TOKEN_DEBUGGER, aLine);
1482
582
}
1483
1484
void fxDoStatement(txParser* parser)
1485
53.0k
{
1486
53.0k
  txInteger aLine = parser->states[0].line;
1487
53.0k
  fxCheckParserStack(parser, aLine);
1488
53.0k
  fxPushNULL(parser);
1489
53.0k
  fxMatchToken(parser, XS_TOKEN_DO);
1490
53.0k
  fxStatement(parser, 0);
1491
53.0k
  fxMatchToken(parser, XS_TOKEN_WHILE);
1492
53.0k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1493
53.0k
  fxCommaExpression(parser);
1494
53.0k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1495
53.0k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1496
75
    fxGetNextToken(parser);
1497
53.0k
  fxPushNodeStruct(parser, 2, XS_TOKEN_DO, aLine);
1498
53.0k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1499
53.0k
}
1500
1501
void fxForStatement(txParser* parser)
1502
56.2k
{
1503
56.2k
  txInteger aLine = parser->states[0].line;
1504
56.2k
  txBoolean awaitFlag = 0;
1505
56.2k
  txBoolean expressionFlag = 0;
1506
56.2k
  txToken aToken;
1507
56.2k
  fxPushNULL(parser);
1508
56.2k
  fxMatchToken(parser, XS_TOKEN_FOR);
1509
56.2k
  if (parser->states[0].token == XS_TOKEN_AWAIT) {
1510
13
    awaitFlag = 1;
1511
13
    fxMatchToken(parser, XS_TOKEN_AWAIT);
1512
13
  }
1513
56.2k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1514
56.2k
  fxLookAheadOnce(parser);
1515
56.2k
  parser->flags |= mxForFlag;
1516
56.2k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON) {
1517
180
    fxPushNULL(parser);
1518
180
  }
1519
56.0k
  else if (parser->states[0].token == XS_TOKEN_CONST) {
1520
1.40k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1521
1.40k
  }
1522
54.6k
  else if (parser->states[0].token == XS_TOKEN_LET) {
1523
11
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1524
11
  }
1525
54.6k
  else if (fxIsKeyword(parser, parser->letSymbol) && (gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING)) {
1526
1.28k
    parser->states[0].token = XS_TOKEN_LET;
1527
1.28k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1528
1.28k
  }
1529
53.3k
#if mxExplicitResourceManagement
1530
53.3k
  else if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1531
9
        && (!parser->states[1].crlf) && ((parser->states[1].token == XS_TOKEN_IDENTIFIER) || (parser->states[1].token == XS_TOKEN_AWAIT) || (parser->states[1].token == XS_TOKEN_YIELD))) {
1532
4
    parser->states[0].token = XS_TOKEN_USING;
1533
4
    fxVariableStatement(parser, XS_TOKEN_USING, 0);
1534
4
  }
1535
53.3k
  else if ((parser->states[0].token == XS_TOKEN_AWAIT)
1536
182
        && (!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_IDENTIFIER) && (parser->states[1].symbol == parser->usingSymbol) && (!parser->states[1].escaped)) {
1537
0
    fxLookAheadTwice(parser);
1538
0
    if ((!parser->states[2].crlf) && ((parser->states[2].token == XS_TOKEN_IDENTIFIER) || (parser->states[2].token == XS_TOKEN_AWAIT) || (parser->states[2].token == XS_TOKEN_YIELD))) {
1539
0
      fxGetNextToken(parser);
1540
0
      parser->states[0].token = XS_TOKEN_USING;
1541
0
      fxVariableStatement(parser, XS_TOKEN_USING, mxAwaitingFlag);
1542
0
      parser->flags |= mxAwaitingFlag;
1543
0
    }
1544
0
    else {
1545
0
      fxCommaExpression(parser);
1546
0
      expressionFlag = 1;
1547
0
    }
1548
0
  }
1549
53.3k
#endif
1550
53.3k
  else if (parser->states[0].token == XS_TOKEN_VAR) {
1551
22.1k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1552
22.1k
  }
1553
31.2k
  else {
1554
31.2k
    fxCommaExpression(parser);
1555
31.2k
    expressionFlag = 1;
1556
31.2k
  }
1557
56.2k
  parser->flags &= ~mxForFlag;
1558
56.2k
  if (awaitFlag && !fxIsKeyword(parser, parser->ofSymbol))
1559
2
    fxReportParserError(parser, parser->states[0].line, "invalid for await");
1560
56.2k
  if (fxIsToken(parser, XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)) {
1561
18.3k
    if (expressionFlag) {
1562
1.26k
      if (!fxCheckReference(parser, XS_TOKEN_ASSIGN)) {
1563
74
        fxReportParserError(parser, parser->states[0].line, "no reference");
1564
74
      }
1565
1.26k
    }
1566
17.1k
    else {
1567
17.1k
      aToken = parser->root->description->token;
1568
17.1k
      if (aToken == XS_TOKEN_BINDING) {
1569
1
        if (((txBindingNode*)(parser->root))->initializer)
1570
1
          fxReportParserError(parser, parser->states[0].line, "invalid binding initializer");
1571
1
      }
1572
17.1k
      if (fxIsToken(parser, XS_TOKEN_IN) && (aToken == XS_TOKEN_USING))
1573
1
        fxReportParserError(parser, parser->states[0].line, "invalid using in");
1574
      
1575
//      else if (aToken == XS_TOKEN_ARRAY_BINDING) {
1576
//        if (((txArrayBindingNode*)(parser->root))->initializer)
1577
//          fxReportParserError(parser, parser->states[0].line, "invalid array binding initializer");
1578
//      }
1579
//      else if (aToken == XS_TOKEN_OBJECT_BINDING) {
1580
//        if (((txObjectBindingNode*)(parser->root))->initializer)
1581
//          fxReportParserError(parser, parser->states[0].line, "invalid object binding initializer");
1582
//      }
1583
//      else
1584
//        fxReportParserError(parser, parser->states[0].line, "no reference %s", gxTokenNames[aToken]);
1585
17.1k
    }
1586
18.3k
    aToken = parser->states[0].token;
1587
18.3k
    fxGetNextToken(parser);
1588
18.3k
    if (aToken == XS_TOKEN_IN)
1589
17.7k
      fxCommaExpression(parser);
1590
659
    else
1591
659
      fxAssignmentExpression(parser);
1592
18.3k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1593
18.3k
    fxStatement(parser, 0);
1594
18.3k
    if (awaitFlag)
1595
9
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_AWAIT_OF, aLine);
1596
18.3k
    else if (aToken == XS_TOKEN_IN)
1597
17.5k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_IN, aLine);
1598
792
    else
1599
792
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_OF, aLine);
1600
18.3k
  }
1601
37.8k
  else {
1602
37.8k
    if (expressionFlag)
1603
24.8k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1604
37.8k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1605
37.8k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1606
25.2k
      fxCommaExpression(parser);
1607
25.2k
    }
1608
12.5k
    else {
1609
12.5k
      fxPushNULL(parser);
1610
12.5k
    }
1611
37.8k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1612
37.8k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1613
23.7k
      fxCommaExpression(parser);
1614
23.7k
    }
1615
14.1k
    else {
1616
14.1k
      fxPushNULL(parser);
1617
14.1k
    }
1618
37.8k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1619
37.8k
    fxCheckParserStack(parser, aLine);
1620
37.8k
    fxStatement(parser, 0);
1621
37.8k
    fxPushNodeStruct(parser, 4, XS_TOKEN_FOR, aLine);
1622
37.8k
  }
1623
56.2k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1624
56.2k
}
1625
1626
void fxIfStatement(txParser* parser)
1627
9.00k
{
1628
9.00k
  txInteger aLine = parser->states[0].line;
1629
9.00k
  fxMatchToken(parser, XS_TOKEN_IF);
1630
9.00k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1631
9.00k
  fxCommaExpression(parser);
1632
9.00k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1633
9.00k
  fxStatement(parser, 0);
1634
9.00k
  if (parser->states[0].token == XS_TOKEN_ELSE) {
1635
446
    fxMatchToken(parser, XS_TOKEN_ELSE);
1636
446
    fxStatement(parser, 0);
1637
446
  }
1638
8.56k
  else {
1639
8.56k
    fxPushNULL(parser);
1640
8.56k
  }
1641
9.00k
  fxPushNodeStruct(parser, 3, XS_TOKEN_IF, aLine);
1642
9.00k
}
1643
1644
void fxReturnStatement(txParser* parser)
1645
14.1k
{
1646
14.1k
  txInteger aLine = parser->states[0].line;
1647
14.1k
  fxMatchToken(parser, XS_TOKEN_RETURN);
1648
14.1k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1649
7.29k
    fxCommaExpression(parser);
1650
7.29k
  }
1651
6.81k
  else {
1652
6.81k
    fxPushNULL(parser);
1653
6.81k
  }
1654
14.1k
  fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
1655
14.1k
}
1656
1657
void fxSwitchStatement(txParser* parser)
1658
6.28k
{
1659
6.28k
  txInteger aCount = 0;
1660
6.28k
  txBoolean aDefaultFlag = 0;
1661
6.28k
  txInteger aLine = parser->states[0].line;
1662
6.28k
  fxMatchToken(parser, XS_TOKEN_SWITCH);
1663
6.28k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1664
6.28k
  fxCommaExpression(parser);
1665
6.28k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1666
6.28k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1667
9.13k
  while ((parser->states[0].token == XS_TOKEN_CASE) || (parser->states[0].token == XS_TOKEN_DEFAULT)) {
1668
2.85k
    txInteger aCaseCount;
1669
2.85k
    txInteger aCaseLine = parser->states[0].line;
1670
2.85k
    if (parser->states[0].token == XS_TOKEN_CASE) {
1671
2.79k
      fxMatchToken(parser, XS_TOKEN_CASE);
1672
2.79k
      fxCommaExpression(parser);
1673
2.79k
      fxMatchToken(parser, XS_TOKEN_COLON);
1674
2.79k
      aCaseCount = parser->nodeCount;
1675
5.65k
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1676
2.86k
        fxStatement(parser, 1);
1677
2.79k
      aCaseCount = parser->nodeCount - aCaseCount;
1678
2.79k
      if (aCaseCount > 1) {
1679
263
        fxPushNodeList(parser, aCaseCount);
1680
263
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aCaseLine);
1681
263
      }
1682
2.52k
      else if (aCaseCount == 0) {
1683
592
        fxPushNULL(parser);
1684
592
      }
1685
2.79k
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1686
2.79k
    }
1687
60
    else {
1688
60
      fxMatchToken(parser, XS_TOKEN_DEFAULT);
1689
60
      if (aDefaultFlag) 
1690
1
        fxReportParserError(parser, parser->states[0].line, "invalid default");
1691
60
      fxPushNULL(parser);
1692
60
      fxMatchToken(parser, XS_TOKEN_COLON);
1693
60
      aCaseCount = parser->nodeCount;
1694
197
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1695
137
        fxStatement(parser, 1);
1696
60
      aCaseCount = parser->nodeCount - aCaseCount;
1697
60
      if (aCaseCount > 1) {
1698
7
        fxPushNodeList(parser, aCaseCount);
1699
7
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1700
7
      }
1701
53
      else if (aCaseCount == 0) {
1702
1
        fxPushNULL(parser);
1703
1
      }
1704
60
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1705
60
      aDefaultFlag = 1;
1706
60
    }
1707
2.85k
    aCount++;
1708
2.85k
  }
1709
6.28k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1710
6.28k
  fxPushNodeList(parser, aCount);
1711
6.28k
  fxPushNodeStruct(parser, 2, XS_TOKEN_SWITCH, aLine);
1712
6.28k
}
1713
1714
void fxThrowStatement(txParser* parser)
1715
17.5k
{
1716
17.5k
  txInteger aLine = parser->states[0].line;
1717
17.5k
  fxMatchToken(parser, XS_TOKEN_THROW);
1718
17.5k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1719
17.0k
    fxCommaExpression(parser);
1720
17.0k
  }
1721
554
  else {
1722
554
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1723
554
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
1724
554
  }
1725
17.5k
  fxPushNodeStruct(parser, 1, XS_TOKEN_THROW, aLine);
1726
17.5k
}
1727
1728
void fxTryStatement(txParser* parser)
1729
8.35k
{
1730
8.35k
  txInteger aLine = parser->states[0].line;
1731
8.35k
  txBoolean ok = 0;
1732
8.35k
  fxMatchToken(parser, XS_TOKEN_TRY);
1733
8.35k
  fxBlock(parser);
1734
8.35k
  if (parser->states[0].token == XS_TOKEN_CATCH) {
1735
3.57k
    txInteger aCatchLine = parser->states[0].line;
1736
3.57k
    fxMatchToken(parser, XS_TOKEN_CATCH);
1737
3.57k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
1738
3.47k
      fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1739
3.47k
      fxBinding(parser, XS_TOKEN_LET, 1);
1740
3.47k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1741
3.47k
    }
1742
97
    else
1743
97
      fxPushNULL(parser);
1744
3.57k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1745
3.57k
    fxStatements(parser);
1746
3.57k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1747
3.57k
    fxPushNodeStruct(parser, 2, XS_TOKEN_CATCH, aCatchLine);
1748
3.57k
    ok = 1;
1749
3.57k
  }
1750
4.78k
  else {
1751
4.78k
    fxPushNULL(parser);
1752
4.78k
  }
1753
8.35k
  if (parser->states[0].token == XS_TOKEN_FINALLY) {
1754
56
    fxMatchToken(parser, XS_TOKEN_FINALLY);
1755
56
    fxBlock(parser);
1756
56
    ok = 1;
1757
56
  }
1758
8.30k
  else {
1759
8.30k
    fxPushNULL(parser);
1760
8.30k
  }
1761
8.35k
  if (!ok)
1762
1.58k
    fxReportParserError(parser, parser->states[0].line, "missing catch or finally");
1763
8.35k
  fxPushNodeStruct(parser, 3, XS_TOKEN_TRY, aLine);
1764
8.35k
}
1765
1766
void fxVariableStatement(txParser* parser, txToken theToken, txUnsigned flags)
1767
183k
{
1768
183k
  txBoolean commaFlag = 0;
1769
183k
  txInteger aCount = 0;
1770
183k
  txInteger aLine = parser->states[0].line;
1771
183k
  fxMatchToken(parser, theToken);
1772
193k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
1773
180k
    commaFlag = 0;
1774
180k
    fxBinding(parser, theToken, 1 | flags);
1775
//    if (parser->states[0].token == XS_TOKEN_ASSIGN) {
1776
//      parser->flags &= ~mxForFlag;
1777
//      fxGetNextToken(parser);
1778
//      fxAssignmentExpression(parser);
1779
//      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, aLine);
1780
//      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1781
//    }
1782
180k
    aCount++;
1783
180k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
1784
10.7k
      parser->flags &= ~mxForFlag;
1785
10.7k
      fxGetNextToken(parser);
1786
10.7k
      commaFlag = 1;
1787
10.7k
    }
1788
170k
    else
1789
170k
      break;
1790
180k
  }
1791
183k
    if ((aCount == 0) || commaFlag) {
1792
3.52k
    fxPushNULL(parser);
1793
3.52k
    fxPushNULL(parser);
1794
3.52k
    fxPushNodeStruct(parser, 2, theToken, aLine);
1795
3.52k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
1796
3.52k
  }
1797
183k
  if (aCount > 1) {
1798
4.05k
    fxPushNodeList(parser, aCount);
1799
4.05k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1800
4.05k
  }
1801
183k
}
1802
1803
void fxWhileStatement(txParser* parser)
1804
2.69k
{
1805
2.69k
  txInteger aLine = parser->states[0].line;
1806
2.69k
  fxPushNULL(parser);
1807
2.69k
  fxMatchToken(parser, XS_TOKEN_WHILE);
1808
2.69k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1809
2.69k
  fxCommaExpression(parser);
1810
2.69k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1811
2.69k
  fxStatement(parser, 0);
1812
2.69k
  fxPushNodeStruct(parser, 2, XS_TOKEN_WHILE, aLine);
1813
2.69k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1814
2.69k
}
1815
1816
void fxWithStatement(txParser* parser)
1817
4.99k
{
1818
4.99k
  txInteger aLine = parser->states[0].line;
1819
4.99k
  fxMatchToken(parser, XS_TOKEN_WITH);
1820
4.99k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1821
4.99k
  fxCommaExpression(parser);
1822
4.99k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1823
4.99k
  fxStatement(parser, 0);
1824
4.99k
  fxPushNodeStruct(parser, 2, XS_TOKEN_WITH, aLine);
1825
4.99k
}
1826
1827
void fxCommaExpression(txParser* parser)
1828
1.40M
{
1829
1.40M
  txInteger aCount = 0;
1830
1.40M
  txInteger aLine = parser->states[0].line;
1831
1.40M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1832
1.40M
    fxAssignmentExpression(parser);
1833
1.40M
    aCount++;
1834
1.43M
    while (parser->states[0].token == XS_TOKEN_COMMA) {
1835
37.2k
      fxGetNextToken(parser);
1836
37.2k
      fxAssignmentExpression(parser);
1837
37.2k
      aCount++;
1838
37.2k
    }
1839
1.40M
  }
1840
1.40M
  if (aCount > 1) {
1841
20.3k
    fxPushNodeList(parser, aCount);
1842
20.3k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
1843
20.3k
  }
1844
1.38M
  else if (aCount == 0) {
1845
395
    fxPushNULL(parser);
1846
395
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1847
395
  }
1848
1.40M
}
1849
1850
void fxAssignmentExpression(txParser* parser)
1851
2.84M
{
1852
2.84M
  if (parser->states[0].token == XS_TOKEN_YIELD)
1853
7.10k
    fxYieldExpression(parser);
1854
2.84M
  else {
1855
2.84M
    fxConditionalExpression(parser);
1856
3.01M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ASSIGN_EXPRESSION) {
1857
175k
      txToken aToken = parser->states[0].token;
1858
175k
      txInteger aLine = parser->states[0].line;
1859
175k
      if (!fxCheckReference(parser, aToken)) 
1860
5.89k
        fxReportParserError(parser, parser->states[0].line, "no reference");
1861
175k
      fxGetNextToken(parser);
1862
175k
      fxAssignmentExpression(parser);
1863
175k
      fxPushNodeStruct(parser, 2, aToken, aLine);
1864
175k
    }
1865
2.84M
  }
1866
2.84M
}
1867
1868
void fxConditionalExpression(txParser* parser)
1869
2.84M
{
1870
2.84M
  fxCoalesceExpression(parser);
1871
2.84M
  if (parser->states[0].token == XS_TOKEN_QUESTION_MARK) {
1872
6.76k
    txInteger aLine = parser->states[0].line;
1873
6.76k
    txUnsigned flags;
1874
6.76k
    fxCheckArrowFunction(parser, 1);
1875
6.76k
    fxGetNextToken(parser);
1876
6.76k
    flags = parser->flags & mxForFlag;
1877
6.76k
    parser->flags &= ~mxForFlag;
1878
6.76k
    fxAssignmentExpression(parser);
1879
6.76k
    parser->flags |= flags;
1880
6.76k
    fxMatchToken(parser, XS_TOKEN_COLON);
1881
6.76k
    fxAssignmentExpression(parser);
1882
6.76k
    fxPushNodeStruct(parser, 3, XS_TOKEN_QUESTION_MARK, aLine);
1883
6.76k
  }
1884
2.84M
}
1885
1886
void fxCoalesceExpression(txParser* parser)
1887
2.84M
{
1888
2.84M
  fxOrExpression(parser);
1889
2.84M
  while (parser->states[0].token == XS_TOKEN_COALESCE) {
1890
3.65k
    txInteger aLine = parser->states[0].line;
1891
3.65k
    fxGetNextToken(parser);
1892
3.65k
    fxOrExpression(parser);
1893
3.65k
    fxCheckArrowFunction(parser, 2);
1894
3.65k
    fxPushNodeStruct(parser, 2, XS_TOKEN_COALESCE, aLine);
1895
3.65k
  }
1896
2.84M
}
1897
1898
void fxOrExpression(txParser* parser)
1899
2.84M
{
1900
2.84M
  fxAndExpression(parser);
1901
2.85M
  while (parser->states[0].token == XS_TOKEN_OR) {
1902
7.92k
    txInteger aLine = parser->states[0].line;
1903
7.92k
    fxGetNextToken(parser);
1904
7.92k
    fxAndExpression(parser);
1905
7.92k
    fxCheckArrowFunction(parser, 2);
1906
7.92k
    fxPushNodeStruct(parser, 2, XS_TOKEN_OR, aLine);
1907
7.92k
  }
1908
2.84M
}
1909
1910
void fxAndExpression(txParser* parser)
1911
2.85M
{
1912
2.85M
  fxBitOrExpression(parser);
1913
2.86M
  while (parser->states[0].token == XS_TOKEN_AND) {
1914
14.6k
    txInteger aLine = parser->states[0].line;
1915
14.6k
    fxGetNextToken(parser);
1916
14.6k
    fxBitOrExpression(parser);
1917
14.6k
    fxCheckArrowFunction(parser, 2);
1918
14.6k
    fxPushNodeStruct(parser, 2, XS_TOKEN_AND, aLine);
1919
14.6k
  }
1920
2.85M
}
1921
1922
void fxBitOrExpression(txParser* parser)
1923
2.86M
{
1924
2.86M
  fxBitXorExpression(parser);
1925
2.88M
  while (parser->states[0].token == XS_TOKEN_BIT_OR) {
1926
16.7k
    txInteger aLine = parser->states[0].line;
1927
16.7k
    fxGetNextToken(parser);
1928
16.7k
    fxBitXorExpression(parser);
1929
16.7k
    fxCheckArrowFunction(parser, 2);
1930
16.7k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_OR, aLine);
1931
16.7k
  }
1932
2.86M
}
1933
1934
void fxBitXorExpression(txParser* parser)
1935
2.87M
{
1936
2.87M
  fxBitAndExpression(parser);
1937
2.88M
  while (parser->states[0].token == XS_TOKEN_BIT_XOR) {
1938
11.7k
    txInteger aLine = parser->states[0].line;
1939
11.7k
    fxGetNextToken(parser);
1940
11.7k
    fxBitAndExpression(parser);
1941
11.7k
    fxCheckArrowFunction(parser, 2);
1942
11.7k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_XOR, aLine);
1943
11.7k
  }
1944
2.87M
}
1945
1946
void fxBitAndExpression(txParser* parser)
1947
2.88M
{
1948
2.88M
  fxEqualExpression(parser);
1949
2.90M
  while (parser->states[0].token == XS_TOKEN_BIT_AND) {
1950
18.2k
    txInteger aLine = parser->states[0].line;
1951
18.2k
    fxGetNextToken(parser);
1952
18.2k
    fxEqualExpression(parser);
1953
18.2k
    fxCheckArrowFunction(parser, 2);
1954
18.2k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_AND, aLine);
1955
18.2k
  }
1956
2.88M
}
1957
1958
void fxEqualExpression(txParser* parser)
1959
2.90M
{
1960
2.90M
  fxRelationalExpression(parser);
1961
2.91M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EQUAL_EXPRESSION) {
1962
9.31k
    txToken aToken = parser->states[0].token;
1963
9.31k
    txInteger aLine = parser->states[0].line;
1964
9.31k
    fxGetNextToken(parser);
1965
9.31k
    fxRelationalExpression(parser);
1966
9.31k
    fxCheckArrowFunction(parser, 2);
1967
9.31k
    fxPushNodeStruct(parser, 2, aToken, aLine);
1968
9.31k
  }
1969
2.90M
}
1970
1971
void fxRelationalExpression(txParser* parser)
1972
2.91M
{
1973
2.91M
  if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
1974
5.03k
    txInteger aLine = parser->states[0].line;
1975
5.03k
    fxPushSymbol(parser, parser->states[0].symbol);
1976
5.03k
    fxGetNextToken(parser);
1977
5.03k
    fxMatchToken(parser, XS_TOKEN_IN);
1978
5.03k
    if (parser->flags & mxForFlag)
1979
1
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[XS_TOKEN_IN]);
1980
5.03k
    fxShiftExpression(parser);
1981
5.03k
    fxCheckArrowFunction(parser, 2);
1982
5.03k
    fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_IDENTIFIER, aLine);
1983
5.03k
  }
1984
2.91M
  else {
1985
2.91M
    fxShiftExpression(parser);
1986
2.91M
    if ((parser->flags & mxForFlag) && ((parser->states[0].token == XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)))
1987
1.27k
      return;
1988
2.99M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_RELATIONAL_EXPRESSION) {
1989
86.5k
      txToken aToken = parser->states[0].token;
1990
86.5k
      txInteger aLine = parser->states[0].line;
1991
86.5k
      fxMatchToken(parser, aToken);
1992
86.5k
      fxShiftExpression(parser);
1993
86.5k
      fxCheckArrowFunction(parser, 2);
1994
86.5k
      fxPushNodeStruct(parser, 2, aToken, aLine);
1995
86.5k
    }
1996
2.91M
  }
1997
2.91M
}
1998
1999
void fxShiftExpression(txParser* parser)
2000
2.99M
{
2001
2.99M
  fxAdditiveExpression(parser);
2002
3.01M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_SHIFT_EXPRESSION) {
2003
12.9k
    txToken aToken = parser->states[0].token;
2004
12.9k
    txInteger aLine = parser->states[0].line;
2005
12.9k
    fxGetNextToken(parser);
2006
12.9k
    fxAdditiveExpression(parser);
2007
12.9k
    fxCheckArrowFunction(parser, 2);
2008
12.9k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2009
12.9k
  }
2010
2.99M
}
2011
2012
void fxAdditiveExpression(txParser* parser)
2013
3.01M
{
2014
3.01M
  fxMultiplicativeExpression(parser);
2015
7.56M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ADDITIVE_EXPRESSION) {
2016
4.55M
    txToken aToken = parser->states[0].token;
2017
4.55M
    txInteger aLine = parser->states[0].line;
2018
4.55M
    fxGetNextToken(parser);
2019
4.55M
    fxMultiplicativeExpression(parser);
2020
4.55M
    fxCheckArrowFunction(parser, 2);
2021
4.55M
    fxPushNodeStruct(parser, 2, aToken, aLine);
2022
4.55M
  }
2023
3.01M
}
2024
2025
void fxMultiplicativeExpression(txParser* parser)
2026
7.56M
{
2027
7.56M
  fxExponentiationExpression(parser);
2028
7.66M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_MULTIPLICATIVE_EXPRESSION) {
2029
105k
    txToken aToken = parser->states[0].token;
2030
105k
    txInteger aLine = parser->states[0].line;
2031
105k
    fxGetNextToken(parser);
2032
105k
    fxExponentiationExpression(parser);
2033
105k
    fxCheckArrowFunction(parser, 2);
2034
105k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2035
105k
  }
2036
7.56M
}
2037
2038
void fxExponentiationExpression(txParser* parser)
2039
7.66M
{
2040
7.66M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION)
2041
117k
    fxUnaryExpression(parser);
2042
7.55M
  else {
2043
7.55M
    fxPrefixExpression(parser);
2044
7.55M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EXPONENTIATION_EXPRESSION) {
2045
3.00k
      txToken aToken = parser->states[0].token;
2046
3.00k
      txInteger aLine = parser->states[0].line;
2047
3.00k
      fxGetNextToken(parser);
2048
3.00k
            fxExponentiationExpression(parser);
2049
3.00k
      fxCheckArrowFunction(parser, 2);
2050
3.00k
      fxPushNodeStruct(parser, 2, aToken, aLine);
2051
3.00k
    }
2052
7.55M
  }
2053
7.66M
}
2054
2055
void fxUnaryExpression(txParser* parser)
2056
407k
{
2057
407k
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION) {
2058
291k
    txToken aToken = parser->states[0].token;
2059
291k
    txInteger aLine = parser->states[0].line;
2060
291k
    fxCheckParserStack(parser, aLine);
2061
291k
    fxMatchToken(parser, aToken);
2062
291k
    fxUnaryExpression(parser);
2063
291k
    fxCheckArrowFunction(parser, 1);
2064
291k
    if (aToken == XS_TOKEN_ADD)
2065
10.4k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PLUS, aLine);
2066
280k
    else if (aToken == XS_TOKEN_SUBTRACT)
2067
56.2k
      fxPushNodeStruct(parser, 1, XS_TOKEN_MINUS, aLine);
2068
224k
    else if (aToken == XS_TOKEN_DELETE) {
2069
      //if ((parser->flags & mxStrictFlag) && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2070
      //  fxReportParserError(parser, parser->states[0].line, "no reference (strict mode)");
2071
      //}
2072
15.2k
      if (!fxCheckReference(parser, aToken)) 
2073
0
        fxReportParserError(parser, parser->states[0].line, "no reference");
2074
15.2k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2075
15.2k
    }
2076
209k
    else if (aToken == XS_TOKEN_AWAIT) {
2077
768
      if ((parser->flags & mxGeneratorFlag) && !(parser->flags & mxYieldFlag))
2078
5
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2079
763
      else
2080
763
        parser->flags |= mxAwaitingFlag;
2081
768
      fxPushNodeStruct(parser, 1, aToken, aLine);
2082
768
    }
2083
208k
    else
2084
208k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2085
      
2086
291k
  }
2087
116k
  else
2088
116k
    fxPrefixExpression(parser);
2089
407k
}
2090
2091
void fxPrefixExpression(txParser* parser)
2092
7.77M
{
2093
7.77M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_PREFIX_EXPRESSION) {
2094
108k
    txToken aToken = parser->states[0].token;
2095
108k
    txInteger aLine = parser->states[0].line;
2096
108k
    fxCheckParserStack(parser, aLine);
2097
108k
    fxGetNextToken(parser);
2098
108k
    fxPrefixExpression(parser);
2099
108k
    fxCheckArrowFunction(parser, 1);
2100
108k
    if (!fxCheckReference(parser, aToken)) 
2101
1.36k
      fxReportParserError(parser, parser->states[0].line, "no reference");
2102
108k
    fxPushNodeStruct(parser, 1, aToken, aLine);
2103
108k
    parser->root->flags = mxExpressionNoValue;
2104
108k
  }
2105
7.66M
  else
2106
7.66M
    fxPostfixExpression(parser);
2107
7.77M
}
2108
2109
void fxPostfixExpression(txParser* parser)
2110
7.66M
{
2111
7.66M
  fxCallExpression(parser);
2112
7.66M
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_POSTFIX_EXPRESSION)) {
2113
31.8k
    fxCheckArrowFunction(parser, 1);
2114
31.8k
    if (!fxCheckReference(parser, parser->states[0].token)) 
2115
3.31k
      fxReportParserError(parser, parser->states[0].line, "no reference");
2116
31.8k
    fxPushNodeStruct(parser, 1, parser->states[0].token, parser->states[0].line);
2117
31.8k
    fxGetNextToken(parser);
2118
31.8k
  }
2119
7.66M
}
2120
2121
void fxCallExpression(txParser* parser)
2122
7.66M
{
2123
7.66M
  txInteger chainLine = parser->states[0].line;
2124
7.66M
  fxLiteralExpression(parser, 0);
2125
7.66M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_CALL_EXPRESSION) {
2126
398k
    txBoolean chainFlag = 0;
2127
398k
    fxCheckArrowFunction(parser, 1);
2128
1.23M
    for (;;) {
2129
1.23M
      txInteger aLine = parser->states[0].line;
2130
1.23M
      if (parser->states[0].token == XS_TOKEN_DOT) {
2131
301k
        fxGetNextToken(parser);
2132
301k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2133
296k
          fxPushSymbol(parser, parser->states[0].symbol);
2134
296k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2135
296k
          fxGetNextToken(parser);
2136
296k
        }
2137
5.34k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2138
3.93k
          if (parser->root->flags & mxSuperFlag)
2139
0
            fxReportParserError(parser, parser->states[0].line, "invalid super");
2140
3.93k
          fxPushSymbol(parser, parser->states[0].symbol);
2141
3.93k
          fxSwapNodes(parser);
2142
3.93k
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2143
3.93k
          fxGetNextToken(parser);
2144
3.93k
        }
2145
1.40k
        else
2146
1.40k
          fxReportParserError(parser, parser->states[0].line, "missing property");
2147
301k
      }
2148
      //else if (parser->states[0].crlf)
2149
      //  break;
2150
932k
      else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2151
22.4k
        fxGetNextToken(parser);
2152
22.4k
        fxCommaExpression(parser);
2153
22.4k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2154
22.4k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2155
22.4k
      }
2156
909k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2157
277k
        txUnsigned nativeFlags = 0;
2158
277k
        txAccessNode* access = NULL;
2159
277k
        if (parser->root->description && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2160
81.6k
          access = (txAccessNode*)parser->root;
2161
81.6k
          if (access->symbol == parser->evalSymbol) {
2162
5.89k
            parser->flags |= mxEvalFlag;
2163
5.89k
          }
2164
75.7k
          else if (parser->flags & mxCFlag) {
2165
0
            if (access->symbol == parser->NativeSymbol) {
2166
0
              nativeFlags = mxNativeConstructorFlag;
2167
0
            }
2168
0
            else if (access->symbol == parser->nativeSymbol) {
2169
0
              nativeFlags = mxNativeFunctionFlag;
2170
0
              parser->flags |= mxNativeFlag;
2171
0
            }
2172
0
          }
2173
81.6k
        }
2174
277k
        fxParameters(parser);
2175
277k
        if (nativeFlags) {
2176
0
          txParamsNode* params = (txParamsNode*)parser->root;
2177
0
          if (params->items->length == 0)
2178
0
             fxReportParserError(parser, aLine, "%s: no argument", access->symbol->string);
2179
0
          if (params->items->length > 1)
2180
0
             fxReportParserError(parser, aLine, "%s: too many arguments", access->symbol->string);
2181
0
          txStringNode* param = (txStringNode*)(params->items->first);
2182
0
          if (param->description->token != XS_TOKEN_STRING)
2183
0
             fxReportParserError(parser, aLine, "%s: argument is no string literal", access->symbol->string);
2184
0
          fxPopNode(parser);
2185
0
          fxPopNode(parser);
2186
0
          if (nativeFlags & mxNativeFunctionFlag) {
2187
0
            fxPushNULL(parser);
2188
0
            fxPushNodeList(parser, 0);
2189
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2190
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2191
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2192
0
          }
2193
0
          else {
2194
0
            fxPushNULL(parser);
2195
2196
0
            fxPushNULL(parser);
2197
0
            fxPushNULL(parser);
2198
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2199
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2200
            
2201
0
            fxPushNodeList(parser, 0);
2202
            
2203
0
            fxPushNULL(parser);
2204
0
            fxPushNULL(parser);
2205
            
2206
0
            fxPushNULL(parser);
2207
0
            fxPushNodeList(parser, 0);
2208
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2209
0
            fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2210
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2211
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2212
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2213
0
            parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2214
            
2215
0
            fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2216
0
          }
2217
0
        }
2218
277k
        else
2219
277k
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2220
277k
      }
2221
632k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
2222
310k
        if (chainFlag)
2223
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2224
310k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2225
310k
        fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2226
310k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2227
310k
        fxGetNextToken(parser);
2228
310k
        fxPushNodeList(parser, 1);
2229
310k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2230
310k
      }
2231
322k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
2232
375
        if (chainFlag)
2233
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2234
375
        fxTemplateExpression(parser);
2235
375
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2236
375
      }
2237
321k
      else if (parser->states[0].token == XS_TOKEN_CHAIN) {
2238
8.67k
        fxGetNextToken(parser);
2239
8.67k
        chainFlag = 1;
2240
8.67k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2241
5.29k
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2242
5.29k
          fxPushSymbol(parser, parser->states[0].symbol);
2243
5.29k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2244
5.29k
          fxGetNextToken(parser);
2245
5.29k
        }
2246
3.38k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2247
136
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2248
136
          fxPushSymbol(parser, parser->states[0].symbol);
2249
136
          fxSwapNodes(parser);
2250
136
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2251
136
          fxGetNextToken(parser);
2252
136
        }
2253
3.24k
        else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2254
329
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2255
329
          fxGetNextToken(parser);
2256
329
          fxCommaExpression(parser);
2257
329
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2258
329
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2259
329
        }
2260
2.91k
        else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2261
106
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2262
106
          fxParameters(parser);
2263
106
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2264
106
        }
2265
2.81k
        else
2266
2.81k
          fxReportParserError(parser, parser->states[0].line, "invalid ?.");
2267
8.67k
      }
2268
312k
      else
2269
312k
        break;
2270
1.23M
    } 
2271
398k
    if (chainFlag)
2272
4.82k
      fxPushNodeStruct(parser, 1, XS_TOKEN_CHAIN, chainLine);
2273
398k
  } 
2274
7.66M
}
2275
2276
void fxLiteralExpression(txParser* parser, txUnsigned flag)
2277
7.71M
{
2278
7.71M
  int escaped;
2279
7.71M
  txSymbol* aSymbol;
2280
7.71M
  txInteger aLine = parser->states[0].line;
2281
7.71M
  txUnsigned flags = 0;
2282
7.71M
  char c = 0;
2283
7.71M
  fxCheckParserStack(parser, aLine);
2284
7.71M
  switch (parser->states[0].token) {
2285
7.28k
  case XS_TOKEN_NULL:
2286
16.8k
  case XS_TOKEN_TRUE:
2287
23.8k
  case XS_TOKEN_FALSE:
2288
23.8k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2289
23.8k
    fxMatchToken(parser, parser->states[0].token);
2290
23.8k
    break;
2291
4.96k
  case XS_TOKEN_IMPORT:
2292
4.96k
    fxMatchToken(parser, XS_TOKEN_IMPORT);
2293
4.96k
    if (!flag && (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)) {
2294
2.23k
      txUnsigned flags = parser->flags & mxForFlag;
2295
2.23k
      fxGetNextToken(parser);
2296
2.23k
      parser->flags &= ~mxForFlag;
2297
2.23k
      fxAssignmentExpression(parser);
2298
2.23k
      if (parser->states[0].token == XS_TOKEN_COMMA) {
2299
33
        fxGetNextToken(parser);
2300
33
        if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
2301
23
          fxAssignmentExpression(parser);
2302
23
          if (parser->states[0].token == XS_TOKEN_COMMA)
2303
3
            fxGetNextToken(parser);
2304
23
        }
2305
10
        else
2306
10
          fxPushNULL(parser);
2307
33
      }
2308
2.20k
      else
2309
2.20k
        fxPushNULL(parser);
2310
2.23k
      parser->flags |= flags;
2311
2.23k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
2312
2.23k
      fxPushNodeStruct(parser, 2, XS_TOKEN_IMPORT_CALL, aLine);
2313
2.23k
    }
2314
2.73k
    else if (parser->states[0].token == XS_TOKEN_DOT) {
2315
1.74k
      fxGetNextToken(parser);
2316
1.74k
      if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->metaSymbol) && (!parser->states[0].escaped)) { 
2317
1.62k
        fxGetNextToken(parser);
2318
1.62k
        if (parser->flags & mxProgramFlag)
2319
1.51k
          fxReportParserError(parser, parser->states[0].line, "invalid import.meta");
2320
106
        else
2321
106
          fxPushNodeStruct(parser, 0, XS_TOKEN_IMPORT_META, aLine);
2322
1.62k
      }
2323
123
      else
2324
123
        fxReportParserError(parser, parser->states[0].line, "invalid import.");
2325
1.74k
    }
2326
987
    else
2327
987
      fxReportParserError(parser, parser->states[0].line, "invalid import");
2328
4.96k
    break;
2329
3.80k
  case XS_TOKEN_SUPER:
2330
3.80k
    fxMatchToken(parser, XS_TOKEN_SUPER);
2331
3.80k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2332
22
      if (parser->flags & mxDerivedFlag) {
2333
21
        fxParameters(parser);
2334
21
        fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2335
21
      }
2336
1
      else {
2337
1
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2338
1
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2339
1
      }
2340
22
    }
2341
3.78k
    else if ((parser->states[0].token == XS_TOKEN_DOT) || (parser->states[0].token == XS_TOKEN_LEFT_BRACKET)) {
2342
2.29k
      if (parser->flags & mxSuperFlag) {
2343
401
        fxPushNodeStruct(parser, 0, XS_TOKEN_THIS, aLine);
2344
401
        parser->root->flags |= parser->flags & (mxDerivedFlag | mxSuperFlag);
2345
401
      }
2346
1.89k
      else {
2347
1.89k
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2348
1.89k
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2349
1.89k
      }
2350
2.29k
    }
2351
1.48k
    else
2352
1.48k
      fxReportParserError(parser, parser->states[0].line, "invalid super");
2353
3.80k
    parser->flags |= mxSuperFlag;
2354
3.80k
    break;
2355
15.1k
  case XS_TOKEN_THIS:
2356
15.1k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2357
15.1k
    parser->root->flags |= parser->flags & mxDerivedFlag;
2358
15.1k
    fxMatchToken(parser, XS_TOKEN_THIS);
2359
15.1k
    break;
2360
4.93M
  case XS_TOKEN_INTEGER:
2361
4.93M
    fxPushIntegerNode(parser, parser->states[0].integer, aLine);
2362
4.93M
    fxGetNextToken(parser);
2363
4.93M
    break;
2364
34.5k
  case XS_TOKEN_NUMBER:
2365
34.5k
    fxPushNumberNode(parser, parser->states[0].number, aLine);
2366
34.5k
    fxGetNextToken(parser);
2367
34.5k
    break;
2368
68.8k
  case XS_TOKEN_BIGINT:
2369
68.8k
    fxPushBigIntNode(parser, &parser->states[0].bigint, aLine);
2370
68.8k
    fxGetNextToken(parser);
2371
68.8k
    break;
2372
3.04k
  case XS_TOKEN_DIVIDE_ASSIGN:
2373
3.04k
    c = '=';
2374
    // continue
2375
27.9k
  case XS_TOKEN_DIVIDE:
2376
27.9k
    fxGetNextRegExp(parser, c);
2377
27.9k
    fxPushStringNode(parser, parser->states[0].modifierLength, parser->states[0].modifier, aLine);
2378
27.9k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2379
27.9k
    fxPushNodeStruct(parser, 2, XS_TOKEN_REGEXP, aLine);
2380
27.9k
    fxGetNextToken(parser);
2381
27.9k
    break;
2382
256k
  case XS_TOKEN_STRING:
2383
256k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2384
256k
    fxGetNextToken(parser);
2385
256k
    break;
2386
1.43M
  case XS_TOKEN_IDENTIFIER:
2387
1.43M
    escaped = parser->states[0].escaped;
2388
1.43M
    aSymbol = parser->states[0].symbol;
2389
1.43M
    fxGetNextToken(parser);
2390
//    if (aSymbol == parser->undefinedSymbol) {
2391
//      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2392
//      break;
2393
//    }
2394
1.43M
    flags = 0;
2395
1.43M
    if ((aSymbol == parser->asyncSymbol) && (!escaped) && (!parser->states[0].crlf)) {
2396
6.12k
      if (parser->states[0].token == XS_TOKEN_FUNCTION) {
2397
554
        fxMatchToken(parser, XS_TOKEN_FUNCTION);
2398
554
        if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2399
95
          fxGetNextToken(parser);
2400
95
          fxGeneratorExpression(parser, aLine, C_NULL, mxAsyncFlag);
2401
95
        }
2402
459
        else
2403
459
          fxFunctionExpression(parser, aLine, C_NULL, mxAsyncFlag);
2404
554
        break;
2405
554
      }
2406
5.57k
      if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2407
1.61k
        fxGroupExpression(parser, mxAsyncFlag);
2408
1.61k
        break;
2409
1.61k
      }
2410
3.96k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2411
//        if (!(parser->flags & mxForFlag) || !fxIsKeyword(parser, parser->ofSymbol)) {
2412
1.01k
          aSymbol = parser->states[0].symbol;
2413
1.01k
          fxGetNextToken(parser);
2414
1.01k
          flags = mxAsyncFlag;
2415
//        }
2416
1.01k
      }
2417
3.96k
    }
2418
1.43M
    if (aSymbol == parser->awaitSymbol)
2419
2.35k
      parser->flags |= mxAwaitingFlag;
2420
1.43M
    if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
2421
23.0k
      fxCheckStrictSymbol(parser, aSymbol);
2422
23.0k
      if (flags && (aSymbol == parser->awaitSymbol))
2423
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2424
23.0k
      fxPushSymbol(parser, aSymbol);
2425
23.0k
      fxPushNULL(parser);
2426
23.0k
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2427
23.0k
      fxPushNodeList(parser, 1);
2428
23.0k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2429
23.0k
      fxArrowExpression(parser, flags);
2430
23.0k
      break;
2431
23.0k
    }
2432
1.41M
    if (aSymbol == parser->argumentsSymbol)
2433
3.92k
      parser->flags |= mxArgumentsFlag;
2434
1.41M
    fxPushSymbol(parser, aSymbol);
2435
1.41M
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2436
1.41M
    break;
2437
22.7k
  case XS_TOKEN_CLASS:
2438
22.7k
    flags = parser->flags & mxForFlag;
2439
22.7k
    parser->flags &= ~mxForFlag;
2440
22.7k
    fxClassExpression(parser, aLine, C_NULL);
2441
22.7k
    parser->flags |= flags;
2442
22.7k
    break;
2443
266k
  case XS_TOKEN_FUNCTION:
2444
266k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
2445
266k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2446
4.46k
      fxGetNextToken(parser);
2447
4.46k
      fxGeneratorExpression(parser, aLine, C_NULL, 0);
2448
4.46k
    }
2449
261k
    else
2450
261k
      fxFunctionExpression(parser, aLine, C_NULL, 0);
2451
266k
    break;
2452
42.6k
  case XS_TOKEN_NEW:
2453
42.6k
    fxNewExpression(parser);
2454
42.6k
    break;
2455
77.9k
  case XS_TOKEN_LEFT_BRACE:
2456
77.9k
    flags = parser->flags & mxForFlag;
2457
77.9k
    parser->flags &= ~mxForFlag;
2458
77.9k
    fxObjectExpression(parser);
2459
77.9k
    parser->flags |= flags;
2460
77.9k
    break;
2461
149k
  case XS_TOKEN_LEFT_BRACKET:
2462
149k
    flags = parser->flags & mxForFlag;
2463
149k
    parser->flags &= ~mxForFlag;
2464
149k
    fxArrayExpression(parser);
2465
149k
    parser->flags |= flags;
2466
149k
    break;
2467
247k
  case XS_TOKEN_LEFT_PARENTHESIS:
2468
247k
    fxGroupExpression(parser, 0);
2469
247k
    break;
2470
37.1k
  case XS_TOKEN_TEMPLATE:
2471
37.1k
    fxPushNULL(parser);
2472
37.1k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2473
37.1k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2474
37.1k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2475
37.1k
    fxGetNextToken(parser);
2476
37.1k
    fxPushNodeList(parser, 1);
2477
37.1k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2478
37.1k
    break;
2479
863
  case XS_TOKEN_TEMPLATE_HEAD:
2480
863
    fxPushNULL(parser);
2481
863
    fxTemplateExpression(parser);
2482
863
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2483
863
    break;
2484
0
  case XS_TOKEN_HOST:
2485
0
    fxGetNextToken(parser);
2486
0
    fxPushNULL(parser);
2487
0
    fxPushNULL(parser);
2488
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2489
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2490
0
      fxGetNextToken(parser);
2491
0
    }
2492
0
    else {
2493
0
      fxReportParserError(parser, parser->states[0].line, "invalid host object");
2494
0
      fxPushNULL(parser);
2495
0
    }
2496
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2497
0
    break;
2498
37.4k
  case XS_TOKEN_LESS:
2499
37.4k
    fxGetNextToken(parser);
2500
37.4k
    fxJSXElement(parser);
2501
37.4k
    fxGetNextToken(parser);
2502
37.4k
    break;
2503
14.8k
  default:
2504
14.8k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2505
14.8k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
2506
14.8k
    break;
2507
7.71M
  }
2508
7.71M
}
2509
2510
void fxArrayExpression(txParser* parser)
2511
149k
{
2512
149k
  txInteger aCount = 0;
2513
149k
  int elision = 1;
2514
149k
  txInteger aLine = parser->states[0].line;
2515
149k
  txBoolean aSpreadFlag = 0;
2516
149k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
2517
820k
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2518
670k
    txInteger anItemLine = parser->states[0].line;
2519
670k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
2520
346k
      fxGetNextToken(parser);
2521
346k
      if (elision) {
2522
165k
        fxPushNodeStruct(parser, 0, XS_TOKEN_ELISION, anItemLine);
2523
165k
        aCount++;
2524
165k
      }
2525
181k
      else
2526
181k
        elision = 1;
2527
346k
    }
2528
323k
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
2529
2.58k
      fxGetNextToken(parser);
2530
2.58k
      if (!elision)
2531
1.56k
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2532
2.58k
      fxAssignmentExpression(parser);
2533
2.58k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, anItemLine);
2534
2.58k
      aCount++;
2535
2.58k
      elision = 0;
2536
2.58k
      aSpreadFlag = 1;
2537
2.58k
    }
2538
321k
    else {
2539
321k
      if (!elision)
2540
847
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2541
321k
      fxAssignmentExpression(parser);
2542
321k
      aCount++;
2543
321k
      elision = 0;
2544
321k
    }
2545
670k
  }
2546
149k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2547
149k
  fxPushNodeList(parser, aCount);
2548
149k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
2549
149k
  if (aCount && elision)
2550
2.11k
    parser->root->flags |= mxElisionFlag;
2551
149k
  if (aSpreadFlag)
2552
709
    parser->root->flags |= mxSpreadFlag;
2553
149k
}
2554
2555
void fxArrowExpression(txParser* parser, txUnsigned flag)
2556
45.5k
{
2557
45.5k
  txInteger aLine = parser->states[0].line;
2558
45.5k
  txUnsigned flags = parser->flags;
2559
45.5k
  parser->flags &= ~(mxAsyncFlag | mxGeneratorFlag);
2560
45.5k
  parser->flags |= mxArrowFlag | flag;
2561
45.5k
  fxMatchToken(parser, XS_TOKEN_ARROW);
2562
45.5k
  fxPushNULL(parser);
2563
45.5k
  fxSwapNodes(parser);  
2564
45.5k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2565
17.6k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2566
17.6k
    fxBody(parser);
2567
17.6k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2568
17.6k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2569
17.6k
  }
2570
27.8k
  else {
2571
27.8k
    fxAssignmentExpression(parser);
2572
27.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
2573
27.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2574
27.8k
    if (!(flags & mxAsyncFlag) && (flag & mxAsyncFlag)) {
2575
807
      if (parser->states[0].token == XS_TOKEN_AWAIT) {
2576
1
        parser->states[0].token = XS_TOKEN_IDENTIFIER;
2577
1
      }
2578
807
    }
2579
27.8k
  }
2580
45.5k
  fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2581
45.5k
  parser->root->flags = parser->flags & (mxStrictFlag | mxFieldFlag | mxNotSimpleParametersFlag | mxArrowFlag | mxSuperFlag | flag);
2582
45.5k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2583
623
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2584
45.5k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag | mxEvalFlag));
2585
45.5k
}
2586
2587
void fxClassExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol)
2588
71.9k
{
2589
71.9k
  txBoolean heritageFlag = 0;
2590
//  txBoolean hostFlag = 0;
2591
71.9k
  txNode* constructor = NULL;
2592
71.9k
  txInteger aCount = 0;
2593
71.9k
  txInteger aLine = parser->states[0].line;
2594
71.9k
  txUnsigned flags = parser->flags;
2595
71.9k
  txUnsigned constructorFlags = mxSuperFlag;
2596
71.9k
  txInteger constructorInitCount = 0;
2597
71.9k
  txInteger instanceInitCount = 0;
2598
71.9k
  parser->flags |= mxStrictFlag;
2599
71.9k
  fxMatchToken(parser, XS_TOKEN_CLASS);
2600
71.9k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2601
16.0k
    fxPushSymbol(parser, parser->states[0].symbol);
2602
16.0k
    if (theSymbol)
2603
12.4k
      *theSymbol = parser->states[0].symbol;
2604
16.0k
    fxGetNextToken(parser);
2605
16.0k
  }
2606
55.9k
  else
2607
55.9k
    fxPushNULL(parser);
2608
71.9k
  if (parser->states[0].token == XS_TOKEN_EXTENDS) {
2609
514
    fxMatchToken(parser, XS_TOKEN_EXTENDS);
2610
514
    fxCallExpression(parser);
2611
514
    fxCheckArrowFunction(parser, 1);
2612
514
    fxCheckNativeConstructor(parser);
2613
514
    flags |= parser->flags & mxAwaitingFlag;
2614
514
    constructorFlags |= mxDerivedFlag;
2615
514
    if (parser->root->description->token == XS_TOKEN_HOST)
2616
0
      constructorFlags |= mxHostFlag;
2617
514
    heritageFlag = 1;
2618
514
  }
2619
71.4k
  else if (parser->states[0].token == XS_TOKEN_HOST) {
2620
0
    fxGetNextToken(parser);
2621
0
    fxPushNULL(parser);
2622
0
    fxPushNULL(parser);
2623
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2624
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2625
0
      fxGetNextToken(parser);
2626
0
    }
2627
0
    else {
2628
0
      fxReportParserError(parser, parser->states[0].line, "invalid host class");
2629
0
      fxPushNULL(parser);
2630
0
    }
2631
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2632
0
    constructorFlags |= mxBaseFlag | mxHostFlag;
2633
//    hostFlag = 1;
2634
0
  }
2635
71.4k
  else {
2636
71.4k
    fxPushNULL(parser);
2637
71.4k
    constructorFlags |= mxBaseFlag;
2638
71.4k
  }
2639
71.9k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2640
66.5k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2641
130k
    for (;;) {
2642
130k
      txBoolean aStaticFlag;
2643
130k
      txInteger aPropertyLine = parser->states[0].line;
2644
130k
      txSymbol* aSymbol;
2645
130k
      txToken aToken0;
2646
130k
      txToken aToken1;
2647
130k
      txToken aToken2;
2648
130k
      txUnsigned flag;
2649
142k
      while (parser->states[0].token == XS_TOKEN_SEMICOLON)
2650
11.7k
        fxGetNextToken(parser);
2651
130k
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
2652
11.6k
        break;
2653
118k
      aStaticFlag = 0;
2654
118k
      if ((parser->states[0].token == XS_TOKEN_STATIC) && (!parser->states[0].escaped)) {
2655
49.8k
        fxGetNextToken(parser);
2656
49.8k
        if ((parser->states[0].token == XS_TOKEN_ASSIGN) || parser->states[0].token == XS_TOKEN_SEMICOLON) {
2657
8.20k
          fxPushSymbol(parser, parser->staticSymbol);
2658
8.20k
          aToken1 = XS_TOKEN_PROPERTY;
2659
8.20k
          goto field;
2660
8.20k
        }
2661
41.6k
        if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2662
32.8k
          txUnsigned flags = parser->flags;
2663
32.8k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag | mxAsyncFlag;
2664
32.8k
          fxCheckParserStack(parser, aPropertyLine);
2665
32.8k
          fxGetNextToken(parser);
2666
32.8k
          fxStatements(parser);
2667
32.8k
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2668
32.8k
          fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aPropertyLine);
2669
32.8k
          if (parser->flags & mxArgumentsFlag)
2670
0
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2671
32.8k
          if (parser->flags & mxAwaitingFlag)
2672
0
            fxReportParserError(parser, parser->states[0].line, "invalid await");
2673
32.8k
          parser->flags = flags;
2674
32.8k
          parser->root->flags |= mxStaticFlag;
2675
32.8k
          constructorInitCount++;
2676
32.8k
          aCount++;
2677
32.8k
          continue;
2678
32.8k
        }
2679
8.76k
        aStaticFlag = 1;
2680
8.76k
      }
2681
77.7k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flag);
2682
77.7k
      if ((aStaticFlag == 0) && (aSymbol == parser->constructorSymbol)) {
2683
179
        fxPopNode(parser); // symbol
2684
179
        if (constructor || (aToken2 == XS_TOKEN_GENERATOR) || (aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER) || (flag & mxAsyncFlag)) 
2685
3
          fxReportParserError(parser, parser->states[0].line, "invalid constructor");
2686
179
        fxFunctionExpression(parser, aPropertyLine, C_NULL, constructorFlags);
2687
179
        constructor = fxPopNode(parser);
2688
179
      }
2689
77.5k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2690
7.61k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2691
1
          fxReportParserError(parser, parser->states[0].line, "invalid method: #constructor");
2692
7.61k
        if (aStaticFlag && (aSymbol == parser->prototypeSymbol))
2693
0
          fxReportParserError(parser, parser->states[0].line, "invalid static method: prototype");
2694
7.61k
        if (aStaticFlag)
2695
3.38k
          flag |= mxStaticFlag;
2696
7.61k
        if (aToken2 == XS_TOKEN_GETTER) 
2697
251
          flag |= mxGetterFlag;
2698
7.36k
        else if (aToken2 == XS_TOKEN_SETTER) 
2699
76
          flag |= mxSetterFlag;
2700
7.28k
        else
2701
7.28k
          flag |= mxMethodFlag;
2702
7.61k
        if (aToken2 == XS_TOKEN_GENERATOR)
2703
2.54k
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2704
5.06k
        else
2705
5.06k
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2706
7.61k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2707
7.61k
        parser->root->flags |= flag & (mxStaticFlag | mxGetterFlag | mxSetterFlag | mxMethodFlag);
2708
7.61k
        if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
2709
745
          if (aStaticFlag)
2710
12
            constructorInitCount++;
2711
733
          else
2712
733
            instanceInitCount++;
2713
745
        }
2714
7.61k
        aCount++;
2715
7.61k
      }
2716
69.9k
      else {
2717
69.9k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2718
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: #constructor");
2719
69.9k
        if (aSymbol == parser->constructorSymbol)
2720
0
          fxReportParserError(parser, parser->states[0].line, "invalid field: constructor");
2721
69.9k
        if (aSymbol == parser->prototypeSymbol)
2722
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: prototype");
2723
72.0k
      field:
2724
72.0k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
2725
9.25k
          txUnsigned flags = parser->flags;
2726
9.25k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag;
2727
9.25k
          fxGetNextToken(parser);
2728
9.25k
          fxAssignmentExpression(parser);
2729
9.25k
          if (parser->flags & mxArgumentsFlag)
2730
1
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2731
9.25k
          parser->flags = flags;
2732
9.25k
        }
2733
62.7k
        else {
2734
62.7k
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2735
62.7k
        }
2736
72.0k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2737
72.0k
        if (aStaticFlag) {
2738
2.88k
          parser->root->flags |= mxStaticFlag;
2739
2.88k
          constructorInitCount++;
2740
2.88k
        }
2741
69.1k
        else
2742
69.1k
          instanceInitCount++;
2743
72.0k
        fxSemicolon(parser);
2744
72.0k
        aCount++;
2745
72.0k
      }
2746
77.7k
    }
2747
66.5k
  }
2748
65.8k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2749
65.8k
  fxPushNodeList(parser, aCount);
2750
  
2751
65.8k
  if (constructorInitCount || instanceInitCount) {
2752
7.67k
    txNodeList* itemsList = (txNodeList*)(parser->root);
2753
7.67k
    txNodeList* constructorInitList = C_NULL;
2754
7.67k
    txNode** constructorInitAddress = C_NULL;
2755
7.67k
    txNodeList* instanceInitList = C_NULL;
2756
7.67k
    txNode** instanceInitAddress = C_NULL;
2757
7.67k
    txNode** address;
2758
7.67k
    txNode* item;
2759
7.67k
    if (constructorInitCount) {
2760
1.46k
      fxPushNULL(parser);
2761
1.46k
      fxPushNodeList(parser, 0);
2762
1.46k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2763
1.46k
      fxPushNodeList(parser, 0);
2764
1.46k
      constructorInitList = (txNodeList*)(parser->root);
2765
1.46k
      constructorInitList->length = constructorInitCount;
2766
1.46k
      constructorInitAddress = &(((txNodeList*)(parser->root))->first);
2767
1.46k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2768
1.46k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2769
1.46k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2770
1.46k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2771
1.46k
    }
2772
6.20k
    else 
2773
6.20k
      fxPushNULL(parser);
2774
7.67k
    if (instanceInitCount) {
2775
6.23k
      fxPushNULL(parser);
2776
6.23k
      fxPushNodeList(parser, 0);
2777
6.23k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2778
6.23k
      fxPushNodeList(parser, 0);
2779
6.23k
      instanceInitList = (txNodeList*)(parser->root);
2780
6.23k
      instanceInitList->length = instanceInitCount;
2781
6.23k
      instanceInitAddress = &(((txNodeList*)(parser->root))->first);
2782
6.23k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2783
6.23k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2784
6.23k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2785
6.23k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2786
6.23k
    }
2787
1.43k
    else 
2788
1.43k
      fxPushNULL(parser);
2789
7.67k
    address = &(itemsList->first);
2790
35.5k
    while ((item = *address)) {
2791
27.8k
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2792
1.31k
        if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) {
2793
736
          txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2794
736
          field->item = item;
2795
736
          if (item->flags & mxStaticFlag) {
2796
8
            *constructorInitAddress = (txNode*)field;
2797
8
            constructorInitAddress = &field->next;
2798
8
          }
2799
728
          else {
2800
728
            *instanceInitAddress = (txNode*)field;
2801
728
            instanceInitAddress = &field->next;
2802
728
          }
2803
736
        }
2804
1.31k
      }
2805
27.8k
      address = &(item->next);
2806
27.8k
    }
2807
7.67k
    address = &(itemsList->first);
2808
35.5k
    while ((item = *address)) {
2809
27.8k
      if (item->description->token == XS_TOKEN_BODY) {
2810
1.27k
        *address = item->next;
2811
1.27k
        item->next = C_NULL;
2812
1.27k
        itemsList->length--;
2813
1.27k
        *constructorInitAddress = (txNode*)item;
2814
1.27k
        constructorInitAddress = &item->next;
2815
1.27k
      }
2816
26.5k
      else if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2817
1.31k
        address = &(item->next);
2818
1.31k
      }
2819
25.2k
      else {
2820
25.2k
        txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2821
25.2k
        field->item = item;
2822
25.2k
        if (item->description->token == XS_TOKEN_PROPERTY) {
2823
11.8k
          field->value = ((txPropertyNode*)item)->value;
2824
11.8k
          ((txPropertyNode*)item)->value = C_NULL;
2825
11.8k
        }
2826
13.3k
        else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
2827
10.2k
          field->value = ((txPropertyAtNode*)item)->value;
2828
10.2k
          ((txPropertyAtNode*)item)->value = C_NULL;
2829
10.2k
        }
2830
3.09k
        else {
2831
3.09k
          field->value = ((txPrivatePropertyNode*)item)->value;
2832
3.09k
          ((txPrivatePropertyNode*)item)->value = C_NULL;
2833
3.09k
        }
2834
25.2k
        if (item->flags & mxStaticFlag) {
2835
185
          *constructorInitAddress = (txNode*)field;
2836
185
          constructorInitAddress = &field->next;
2837
185
        }
2838
25.0k
        else {
2839
25.0k
          *instanceInitAddress = (txNode*)field;
2840
25.0k
          instanceInitAddress = &field->next;
2841
25.0k
        }
2842
25.2k
        address = &(item->next);
2843
25.2k
      }
2844
27.8k
    }
2845
7.67k
  }
2846
58.1k
  else {
2847
58.1k
    fxPushNULL(parser);
2848
58.1k
    fxPushNULL(parser);
2849
58.1k
  }
2850
65.8k
  if (constructor) {
2851
168
    fxPushNode(parser, constructor);
2852
168
  }
2853
65.6k
  else {
2854
65.6k
    if (heritageFlag) {
2855
345
      fxPushNULL(parser);
2856
    
2857
345
      fxPushSymbol(parser, parser->argsSymbol);
2858
345
      fxPushNULL(parser);
2859
345
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2860
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
2861
345
      fxPushNodeList(parser, 1);
2862
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2863
      
2864
345
      fxPushSymbol(parser, parser->argsSymbol);
2865
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2866
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2867
345
      fxPushNodeList(parser, 1);
2868
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
2869
345
      parser->root->flags |= mxSpreadFlag;
2870
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2871
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2872
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2873
      
2874
345
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2875
345
      parser->root->flags = mxStrictFlag | mxDerivedFlag | mxMethodFlag | mxTargetFlag | mxSuperFlag;
2876
345
    }
2877
65.3k
    else {
2878
65.3k
      fxPushNULL(parser);
2879
    
2880
65.3k
      fxPushNodeList(parser, 0);
2881
65.3k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2882
      
2883
65.3k
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2884
65.3k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2885
65.3k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2886
      
2887
65.3k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2888
65.3k
      parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2889
65.3k
    }
2890
65.6k
  }
2891
65.8k
  fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2892
65.8k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag));
2893
65.8k
}
2894
2895
void fxFunctionExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2896
274k
{
2897
274k
  txUnsigned flags = parser->flags;
2898
274k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxFunctionFlag | mxTargetFlag | flag;
2899
274k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2900
69.2k
      || ((flags & mxGeneratorFlag) && !(flags & mxStrictFlag) && (parser->states[0].token == XS_TOKEN_YIELD))
2901
205k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2902
205k
    fxPushSymbol(parser, parser->states[0].symbol);
2903
205k
    if (theSymbol)
2904
2.63k
      *theSymbol = parser->states[0].symbol;
2905
205k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2906
205k
    fxGetNextToken(parser);
2907
205k
  }
2908
69.2k
  else
2909
69.2k
    fxPushNULL(parser);
2910
274k
  fxParametersBinding(parser);
2911
274k
  if (parser->states[0].token == XS_TOKEN_HOST) {
2912
0
    fxGetNextToken(parser);
2913
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2914
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, theLine);
2915
0
      fxGetNextToken(parser);
2916
0
    }
2917
0
    else {
2918
0
      fxReportParserError(parser, parser->states[0].line, "invalid host function");
2919
0
      fxPushNULL(parser);
2920
0
    }
2921
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, theLine);
2922
0
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2923
0
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2924
0
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2925
0
        parser->flags = flags;
2926
0
  }
2927
274k
  else {
2928
274k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2929
274k
    fxBody(parser);
2930
274k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2931
274k
    fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, theLine);
2932
274k
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2933
274k
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2934
3.99k
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2935
274k
        if (parser->flags & mxNativeFlag) {
2936
0
          fxCheckNativeFunction(parser);
2937
0
        }     
2938
274k
        parser->flags = flags;
2939
274k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2940
274k
  }
2941
274k
}
2942
2943
void fxGeneratorExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2944
8.40k
{
2945
8.40k
  txUnsigned flags = parser->flags;
2946
8.40k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxGeneratorFlag | mxTargetFlag | flag;
2947
8.40k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2948
5.15k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2949
5.15k
    fxPushSymbol(parser, parser->states[0].symbol);
2950
5.15k
    if (theSymbol)
2951
711
      *theSymbol = parser->states[0].symbol;
2952
4.44k
    else if (parser->states[0].symbol == parser->yieldSymbol)
2953
1
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
2954
4.44k
    else if ((parser->flags & mxAsyncFlag) && (parser->states[0].symbol == parser->awaitSymbol))
2955
0
      fxReportParserError(parser, parser->states[0].line, "invalid await");
2956
5.15k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2957
5.15k
    fxGetNextToken(parser);
2958
5.15k
  }
2959
3.24k
  else
2960
3.24k
    fxPushNULL(parser);
2961
8.40k
  fxParametersBinding(parser);
2962
8.40k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2963
8.40k
  parser->flags |= mxYieldFlag;
2964
8.40k
    fxBody(parser);
2965
8.40k
  parser->flags &= ~mxYieldFlag;
2966
8.40k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2967
8.40k
  fxPushNodeStruct(parser, 3, XS_TOKEN_GENERATOR, theLine);
2968
8.40k
  parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxGeneratorFlag | mxArgumentsFlag | mxEvalFlag | flag);
2969
8.40k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2970
153
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2971
8.40k
  parser->flags = flags;
2972
8.40k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2973
8.40k
}
2974
2975
void fxGroupExpression(txParser* parser, txUnsigned flag)
2976
248k
{
2977
248k
  txBoolean commaFlag = 0;
2978
248k
  txBoolean spreadFlag = 0;
2979
248k
  txInteger aCount = 0;
2980
248k
  txInteger aLine;
2981
248k
  txUnsigned formerAwaitingYieldingFlags = parser->flags & (mxAwaitingFlag | mxYieldingFlag);
2982
248k
  parser->flags &= ~(mxAwaitingFlag | mxYieldingFlag);
2983
248k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
2984
401k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2985
228k
    aLine = parser->states[0].line;
2986
228k
    commaFlag = 0;
2987
228k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
2988
53
      fxGetNextToken(parser);
2989
53
      fxAssignmentExpression(parser);
2990
53
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2991
53
      spreadFlag = 1;
2992
53
    }
2993
228k
    else
2994
228k
      fxAssignmentExpression(parser);
2995
228k
    aCount++;
2996
228k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
2997
75.6k
      break;
2998
153k
    fxGetNextToken(parser);
2999
153k
    commaFlag = 1;
3000
153k
  }
3001
248k
  aLine = parser->states[0].line;
3002
248k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3003
248k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
3004
22.5k
    fxPushNodeList(parser, aCount);
3005
22.5k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3006
22.5k
    if (commaFlag && spreadFlag)
3007
1
      fxReportParserError(parser, parser->states[0].line, "invalid parameters");
3008
22.5k
    if (!fxParametersBindingFromExpressions(parser, parser->root))
3009
97
      fxReportParserError(parser, parser->states[0].line, "no parameters");
3010
22.5k
    fxCheckStrictBinding(parser, parser->root);
3011
22.5k
    parser->root->flags |= flag;
3012
22.5k
    if (parser->flags & mxAwaitingFlag) {
3013
10
      if (flag || (parser->flags & mxAsyncFlag))
3014
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
3015
10
      else
3016
10
        formerAwaitingYieldingFlags |= mxAwaitingFlag;
3017
10
    }
3018
22.5k
    if (parser->flags & mxYieldingFlag)
3019
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
3020
22.5k
    fxArrowExpression(parser, flag);
3021
22.5k
  }
3022
226k
  else if (flag) {
3023
834
    fxPushNodeList(parser, aCount);
3024
834
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3025
834
    if (spreadFlag)
3026
0
      parser->root->flags |= mxSpreadFlag;
3027
    
3028
834
    fxPushSymbol(parser, parser->asyncSymbol);
3029
834
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
3030
834
    fxSwapNodes(parser);
3031
834
    fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
3032
834
  }
3033
225k
  else {
3034
225k
        if ((aCount == 0) || commaFlag) {
3035
1.48k
            fxPushNULL(parser);
3036
1.48k
      fxReportParserError(parser, parser->states[0].line, "missing expression");
3037
1.48k
        }
3038
223k
    else /*if (aCount > 1)*/ {
3039
223k
      fxPushNodeList(parser, aCount);
3040
223k
      fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3041
223k
    }
3042
225k
  }
3043
248k
  parser->flags |= formerAwaitingYieldingFlags;
3044
248k
}
3045
3046
void fxNewExpression(txParser* parser)
3047
42.6k
{
3048
42.6k
  txInteger aLine = parser->states[0].line;
3049
42.6k
  fxMatchToken(parser, XS_TOKEN_NEW);
3050
42.6k
  if (parser->states[0].token == XS_TOKEN_DOT) {
3051
512
    fxGetNextToken(parser);
3052
512
    if (fxIsKeyword(parser, parser->targetSymbol)) {
3053
15
      if (!(parser->flags & mxTargetFlag))
3054
3
        fxReportParserError(parser, parser->states[0].line, "invalid new.target");
3055
15
      fxGetNextToken(parser);
3056
15
      fxPushNodeStruct(parser, 0, XS_TOKEN_TARGET, aLine);
3057
15
    }
3058
497
    else
3059
497
      fxReportParserError(parser, parser->states[0].line, "missing target");
3060
512
    return;
3061
512
  }
3062
42.1k
  fxLiteralExpression(parser, 1);
3063
42.1k
  fxCheckArrowFunction(parser, 1);
3064
46.6k
  for (;;) {
3065
46.6k
    txInteger aMemberLine = parser->states[0].line;
3066
46.6k
    if (parser->states[0].token == XS_TOKEN_DOT) {
3067
4.99k
      fxGetNextToken(parser);
3068
4.99k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3069
4.98k
        fxPushSymbol(parser, parser->states[0].symbol);
3070
4.98k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aMemberLine);
3071
4.98k
        fxGetNextToken(parser);
3072
4.98k
      }
3073
12
      else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3074
10
        fxPushSymbol(parser, parser->states[0].symbol);
3075
10
        fxSwapNodes(parser);
3076
10
        fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aMemberLine);
3077
10
        fxGetNextToken(parser);
3078
10
      }
3079
2
      else
3080
2
        fxReportParserError(parser, parser->states[0].line, "missing property");
3081
4.99k
    }
3082
41.6k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3083
27
      fxGetNextToken(parser);
3084
27
      fxCommaExpression(parser);
3085
27
      fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aMemberLine);
3086
27
      fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3087
27
    }
3088
41.6k
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
3089
403
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3090
403
      fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3091
403
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3092
403
      fxGetNextToken(parser);
3093
403
      fxPushNodeList(parser, 1);
3094
403
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3095
403
    }
3096
41.2k
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
3097
6
      fxTemplateExpression(parser);
3098
6
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3099
6
    }
3100
41.2k
    else
3101
41.2k
      break;
3102
46.6k
  } 
3103
42.1k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3104
34.4k
    fxParameters(parser);
3105
7.69k
  else {
3106
7.69k
    fxPushNodeList(parser, 0);
3107
7.69k
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3108
7.69k
  }
3109
42.1k
  fxPushNodeStruct(parser, 2, XS_TOKEN_NEW, aLine);
3110
42.1k
}
3111
3112
void fxObjectExpression(txParser* parser)
3113
77.9k
{
3114
77.9k
  txInteger aCount = 0;
3115
77.9k
  txSymbol* aSymbol;
3116
77.9k
  txToken aToken0;
3117
77.9k
  txToken aToken1;
3118
77.9k
  txToken aToken2;
3119
77.9k
  txInteger aLine = parser->states[0].line;
3120
77.9k
  txNode* base = parser->root;
3121
77.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3122
147k
  for (;;) {
3123
147k
    txInteger aPropertyLine = parser->states[0].line;
3124
147k
    txUnsigned flags = 0;
3125
147k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3126
24.7k
            break;
3127
122k
        if (parser->states[0].token == XS_TOKEN_SPREAD) {
3128
1.27k
      fxGetNextToken(parser);
3129
1.27k
      fxAssignmentExpression(parser);
3130
1.27k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aPropertyLine);
3131
1.27k
        }
3132
121k
        else {
3133
121k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flags);
3134
121k
      if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
3135
1.32k
        fxReportParserError(parser, parser->states[0].line, "invalid private property");
3136
1.32k
      }
3137
120k
      else if ((aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER)) {
3138
532
        flags |= mxShorthandFlag;
3139
532
        if (aToken2 == XS_TOKEN_GETTER)
3140
378
          flags |= mxGetterFlag;
3141
154
        else if (aToken2 == XS_TOKEN_SETTER)
3142
154
          flags |= mxSetterFlag;
3143
532
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3144
531
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag);
3145
1
        else
3146
1
          fxReportParserError(parser, parser->states[0].line, "missing (");
3147
532
      }
3148
119k
      else if (aToken2 == XS_TOKEN_GENERATOR) {
3149
1.82k
        flags |= mxShorthandFlag | mxMethodFlag;
3150
1.82k
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3151
582
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3152
1.24k
        else
3153
1.24k
          fxReportParserError(parser, parser->states[0].line, "missing (");
3154
1.82k
      }
3155
117k
      else if (aToken2 == XS_TOKEN_FUNCTION) {
3156
47
        flags |= mxShorthandFlag | mxMethodFlag;
3157
47
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3158
44
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3159
3
        else
3160
3
          fxReportParserError(parser, parser->states[0].line, "missing (");
3161
47
      }
3162
117k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3163
2.99k
        flags |= mxShorthandFlag | mxMethodFlag;
3164
2.99k
        fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3165
2.99k
      }
3166
114k
      else if (parser->states[0].token == XS_TOKEN_COLON) {
3167
105k
        fxGetNextToken(parser);
3168
105k
        fxAssignmentExpression(parser);
3169
105k
      }
3170
8.89k
      else if (aToken1 == XS_TOKEN_PROPERTY) {
3171
6.10k
        flags |= mxShorthandFlag;
3172
6.10k
        fxPushSymbol(parser, aSymbol);
3173
6.10k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
3174
2.05k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3175
2.05k
          fxGetNextToken(parser);
3176
2.05k
          fxAssignmentExpression(parser);
3177
2.05k
          fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aPropertyLine);
3178
2.05k
        }
3179
4.04k
        else if (aToken0 == XS_TOKEN_IDENTIFIER) {
3180
2.36k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3181
2.36k
        }
3182
1.68k
        else {
3183
1.68k
          fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3184
1.68k
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3185
1.68k
        }
3186
6.10k
      }
3187
2.79k
      else {
3188
2.79k
        fxReportParserError(parser, parser->states[0].line, "missing :");
3189
2.79k
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3190
2.79k
      }
3191
121k
      fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
3192
121k
      parser->root->flags |= flags;
3193
121k
      fxCheckUniqueProperty(parser, base, parser->root); 
3194
121k
    }
3195
122k
    aCount++;
3196
122k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3197
31.2k
            break;
3198
91.3k
    fxMatchToken(parser, XS_TOKEN_COMMA);
3199
91.3k
  }
3200
77.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3201
77.9k
  fxPushNodeList(parser, aCount);
3202
77.9k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
3203
77.9k
}
3204
3205
void fxTemplateExpression(txParser* parser)
3206
1.24k
{
3207
1.24k
  txInteger aCount = 0;
3208
1.24k
  txInteger aLine = parser->states[0].line;
3209
1.24k
  fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3210
1.24k
  fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3211
1.24k
  fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3212
1.24k
  aCount++;
3213
3.80k
  for (;;) {
3214
3.80k
    fxGetNextToken(parser);
3215
3.80k
        if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3216
2.82k
            fxCommaExpression(parser);
3217
2.82k
            aCount++;
3218
2.82k
        }
3219
3.80k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3220
3
      fxReportParserError(parser, parser->states[0].line, "missing }");
3221
3
    }
3222
3.80k
    fxGetNextTokenTemplate(parser);
3223
3.80k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3224
3.80k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3225
3.80k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3226
3.80k
    aCount++;
3227
3.80k
    if (parser->states[0].token == XS_TOKEN_TEMPLATE_TAIL) {
3228
1.21k
      fxGetNextToken(parser);
3229
1.21k
      break;
3230
1.21k
    }
3231
3.80k
  }
3232
1.24k
  fxPushNodeList(parser, aCount);
3233
1.24k
}
3234
3235
void fxYieldExpression(txParser* parser)
3236
7.10k
{
3237
7.10k
  txInteger aLine = parser->states[0].line;
3238
7.10k
  if (!(parser->flags & mxYieldFlag))
3239
25
    fxReportParserError(parser, parser->states[0].line, "invalid yield");
3240
7.08k
  else
3241
7.08k
    parser->flags |= mxYieldingFlag;
3242
7.10k
  fxMatchToken(parser, XS_TOKEN_YIELD);
3243
7.10k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_MULTIPLY)) {
3244
44
    fxGetNextToken(parser);
3245
44
    fxAssignmentExpression(parser);
3246
44
    fxPushNodeStruct(parser, 1, XS_TOKEN_DELEGATE, aLine);
3247
44
    return;
3248
44
  }
3249
7.06k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3250
6.82k
    fxAssignmentExpression(parser);
3251
6.82k
  }
3252
241
  else {
3253
241
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
3254
241
  }
3255
7.06k
  fxPushNodeStruct(parser, 1, XS_TOKEN_YIELD, aLine);
3256
7.06k
}
3257
3258
void fxParameters(txParser* parser)
3259
311k
{
3260
311k
  txInteger aCount = 0;
3261
311k
  txInteger aLine = parser->states[0].line;
3262
311k
  txBoolean aSpreadFlag = 0;
3263
311k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
3264
752k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3265
440k
    txInteger aParamLine = parser->states[0].line;
3266
440k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3267
238
      fxGetNextToken(parser);
3268
238
      fxAssignmentExpression(parser);
3269
238
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aParamLine);
3270
238
      aSpreadFlag = 1;
3271
238
    }
3272
440k
    else
3273
440k
      fxAssignmentExpression(parser);
3274
440k
    aCount++;
3275
440k
    if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3276
192k
      fxMatchToken(parser, XS_TOKEN_COMMA);
3277
440k
  }
3278
311k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3279
311k
  fxPushNodeList(parser, aCount);
3280
311k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3281
311k
  if (aSpreadFlag)
3282
174
    parser->root->flags |= mxSpreadFlag;
3283
311k
}
3284
3285
void fxPropertyName(txParser* parser, txSymbol** theSymbol, txToken* theToken0, txToken* theToken1, txToken* theToken2, txUnsigned* flag)
3286
197k
{
3287
197k
  txSymbol* aSymbol = C_NULL;
3288
197k
  txToken aToken0 = XS_NO_TOKEN;
3289
197k
  txToken aToken1 = XS_NO_TOKEN;
3290
197k
  txToken aToken2 = XS_NO_TOKEN;
3291
197k
  txInteger aLine = parser->states[0].line;
3292
197k
  txIndex index;
3293
197k
  *flag = 0;
3294
197k
  fxLookAheadOnce(parser);
3295
197k
  aToken0 = parser->states[0].token;
3296
197k
  if ((gxTokenFlags[aToken0] & XS_TOKEN_IDENTIFIER_NAME)) {
3297
138k
    aSymbol = parser->states[0].symbol;
3298
138k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3299
98.9k
      fxPushSymbol(parser, aSymbol);
3300
98.9k
      aToken1 = XS_TOKEN_PROPERTY;
3301
98.9k
    }
3302
39.7k
    else if (fxIsKeyword(parser, parser->asyncSymbol) && (!parser->states[1].crlf)) {
3303
4.43k
      *flag = mxAsyncFlag;
3304
4.43k
      fxGetNextToken(parser);
3305
4.43k
      if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3306
2.90k
        aToken2 = XS_TOKEN_GENERATOR;
3307
2.90k
        fxGetNextToken(parser);
3308
2.90k
      }
3309
1.52k
      else
3310
1.52k
        aToken2 = XS_TOKEN_FUNCTION;
3311
4.43k
    }
3312
35.3k
    else if (fxIsKeyword(parser, parser->getSymbol)) {
3313
977
      aToken2 = XS_TOKEN_GETTER;
3314
977
      fxGetNextToken(parser);
3315
977
    }
3316
34.3k
    else if (fxIsKeyword(parser, parser->setSymbol)) {
3317
5.12k
      aToken2 = XS_TOKEN_SETTER;
3318
5.12k
      fxGetNextToken(parser);
3319
5.12k
    }
3320
29.2k
    else {
3321
29.2k
      fxPushSymbol(parser, aSymbol);
3322
29.2k
      aToken1 = XS_TOKEN_PROPERTY;
3323
29.2k
    }
3324
138k
  }
3325
59.0k
  else if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3326
7.41k
    aToken2 = XS_TOKEN_GENERATOR;
3327
7.41k
    fxGetNextToken(parser);
3328
7.41k
  }
3329
51.6k
  else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3330
5.82k
    aSymbol = parser->states[0].symbol;
3331
5.82k
    fxPushSymbol(parser, aSymbol);
3332
5.82k
    aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3333
5.82k
  }
3334
45.8k
  else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3335
13.2k
    if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3336
13.2k
      fxPushIndexNode(parser, index, aLine);
3337
13.2k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3338
13.2k
    }
3339
0
    else {
3340
0
      aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3341
0
      fxPushSymbol(parser, aSymbol);
3342
0
      aToken1 = XS_TOKEN_PROPERTY;
3343
0
    }
3344
13.2k
  }
3345
32.5k
  else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3346
466
    if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3347
44
      fxPushIndexNode(parser, index, aLine);
3348
44
      aToken1 = XS_TOKEN_PROPERTY_AT;
3349
44
    }
3350
422
    else {
3351
422
      aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3352
422
      fxPushSymbol(parser, aSymbol);
3353
422
      aToken1 = XS_TOKEN_PROPERTY;
3354
422
    }
3355
466
  }
3356
32.0k
  else if (parser->states[0].token == XS_TOKEN_STRING) {
3357
23.3k
    if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3358
5.20k
      fxPushIndexNode(parser, index, aLine);
3359
5.20k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3360
5.20k
    }
3361
18.1k
    else {
3362
18.1k
      aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3363
18.1k
      fxPushSymbol(parser, aSymbol);
3364
18.1k
      aToken1 = XS_TOKEN_PROPERTY;
3365
18.1k
    }
3366
23.3k
  }
3367
8.73k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3368
4.36k
    fxGetNextToken(parser);
3369
4.36k
    fxCommaExpression(parser);
3370
4.36k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3371
743
      fxReportParserError(parser, parser->states[0].line, "missing ]");
3372
743
    }
3373
4.36k
    aToken1 = XS_TOKEN_PROPERTY_AT;
3374
4.36k
  }
3375
4.37k
  else {
3376
4.37k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3377
4.37k
    fxPushNULL(parser);
3378
4.37k
  }
3379
197k
  if (aToken2 != XS_NO_TOKEN) {
3380
17.9k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3381
6.04k
      aSymbol = parser->states[0].symbol;
3382
6.04k
      fxPushSymbol(parser, aSymbol);
3383
6.04k
      aToken1 = XS_TOKEN_PROPERTY;
3384
6.04k
      fxGetNextToken(parser);
3385
6.04k
    }
3386
11.9k
    else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3387
2.42k
      aSymbol = parser->states[0].symbol;
3388
2.42k
      fxPushSymbol(parser, aSymbol);
3389
2.42k
      aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3390
2.42k
      fxGetNextToken(parser);
3391
2.42k
    }
3392
9.48k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3393
1.11k
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3394
1.11k
        fxPushIndexNode(parser, index, aLine);
3395
1.11k
        aToken1 = XS_TOKEN_PROPERTY_AT;
3396
1.11k
      }
3397
0
      else {
3398
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3399
0
        fxPushSymbol(parser, aSymbol);
3400
0
        aToken1 = XS_TOKEN_PROPERTY;
3401
0
      }
3402
1.11k
      fxGetNextToken(parser);
3403
1.11k
    }
3404
8.37k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3405
3.82k
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3406
3.81k
        fxPushIndexNode(parser, index, aLine);
3407
3.81k
        aToken1 = XS_TOKEN_PROPERTY_AT;
3408
3.81k
      }
3409
5
      else {
3410
5
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3411
5
        fxPushSymbol(parser, aSymbol);
3412
5
        aToken1 = XS_TOKEN_PROPERTY;
3413
5
      }
3414
3.82k
      fxGetNextToken(parser);
3415
3.82k
    }
3416
4.55k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3417
627
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3418
34
        fxPushIndexNode(parser, index, aLine);
3419
34
        aToken1 = XS_TOKEN_PROPERTY_AT;
3420
34
      }
3421
593
      else {
3422
593
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3423
593
        fxPushSymbol(parser, aSymbol);
3424
593
        aToken1 = XS_TOKEN_PROPERTY;
3425
593
      }
3426
627
      fxGetNextToken(parser);
3427
627
    }
3428
3.92k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3429
53
      fxGetNextToken(parser);
3430
53
      fxCommaExpression(parser);
3431
53
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3432
1
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3433
1
      }
3434
53
      aToken1 = XS_TOKEN_PROPERTY_AT;
3435
53
      fxGetNextToken(parser);
3436
53
    }
3437
3.87k
    else if (aToken2 == XS_TOKEN_GETTER) {
3438
345
      fxPushSymbol(parser, aSymbol);
3439
345
      aToken1 = XS_TOKEN_PROPERTY;
3440
345
      aToken2 = XS_NO_TOKEN;
3441
345
    }
3442
3.52k
    else if (aToken2 == XS_TOKEN_SETTER) {
3443
2.47k
      fxPushSymbol(parser, aSymbol);
3444
2.47k
      aToken1 = XS_TOKEN_PROPERTY;
3445
2.47k
      aToken2 = XS_NO_TOKEN;
3446
2.47k
    }
3447
1.05k
    else {
3448
1.05k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3449
1.05k
      fxPushNULL(parser);
3450
1.05k
    }
3451
17.9k
  }
3452
179k
  else
3453
179k
    fxGetNextToken(parser);
3454
197k
  *theSymbol = aSymbol;
3455
197k
  *theToken0 = aToken0;
3456
197k
  *theToken1 = aToken1;
3457
197k
  *theToken2 = aToken2;
3458
197k
}
3459
3460
void fxBinding(txParser* parser, txToken theToken, txUnsigned flags)
3461
219k
{
3462
219k
  txInteger aLine = parser->states[0].line;
3463
219k
  fxCheckParserStack(parser, aLine);
3464
219k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3465
178k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
3466
178k
    if (((theToken == XS_TOKEN_CONST) || (theToken == XS_TOKEN_LET) || (theToken == XS_TOKEN_USING)) && (parser->states[0].symbol == parser->letSymbol))
3467
1.27k
      fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3468
178k
    fxPushSymbol(parser, parser->states[0].symbol);
3469
178k
    fxPushNodeStruct(parser, 1, theToken, aLine);
3470
178k
    if (flags & mxAwaitingFlag)
3471
0
      parser->root->flags |= mxAwaitingFlag;
3472
178k
    fxGetNextToken(parser);
3473
178k
  }
3474
40.8k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
3475
10.2k
    if (theToken == XS_TOKEN_USING)
3476
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3477
10.2k
    fxObjectBinding(parser, theToken);
3478
10.2k
  }
3479
30.6k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3480
29.3k
    if (theToken == XS_TOKEN_USING)
3481
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3482
29.3k
    fxArrayBinding(parser, theToken);
3483
29.3k
  }
3484
1.29k
  else {
3485
1.29k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3486
1.29k
    fxPushNULL(parser);
3487
1.29k
  }
3488
219k
  if ((flags & 1) && (parser->states[0].token == XS_TOKEN_ASSIGN)) {
3489
90.6k
    parser->flags &= ~mxForFlag;
3490
90.6k
    fxGetNextToken(parser);
3491
90.6k
    fxAssignmentExpression(parser);
3492
90.6k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aLine);
3493
90.6k
  }
3494
219k
}
3495
3496
txNode* fxBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3497
10.3k
{
3498
10.3k
  txToken aToken = (theNode && theNode->description) ? theNode->description->token : XS_NO_TOKEN;
3499
10.3k
  txNode* binding;
3500
10.4k
again:
3501
10.4k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
3502
244
    txNode* item = ((txExpressionsNode*)theNode)->items->first;
3503
244
    if (item && !item->next) {
3504
243
      aToken = item->description->token;
3505
243
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3506
157
        item->next = theNode->next;
3507
157
        theNode = item;
3508
157
      }
3509
86
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
3510
85
        item->next = theNode->next;
3511
85
        theNode = item;
3512
85
        goto again;
3513
85
      }
3514
1
      else
3515
1
        return NULL;
3516
243
    }
3517
244
  }
3518
10.3k
  if (aToken == XS_TOKEN_BINDING) {
3519
628
    binding = fxBindingFromExpression(parser, ((txBindingNode*)theNode)->target, theToken);
3520
628
    ((txBindingNode*)theNode)->target = binding;
3521
//    fxCheckStrictBinding(parser, theNode);
3522
//    fxCheckStrictSymbol(parser, ((txBindingNode*)theNode)->symbol);
3523
//    theNode->description = &gxTokenDescriptions[theToken];
3524
628
    return theNode;
3525
628
  }
3526
9.76k
  if (aToken == XS_TOKEN_ARRAY_BINDING) {
3527
300
    txNodeList* list = ((txArrayBindingNode*)theNode)->items;
3528
300
    txNode** address = &(list->first);
3529
300
    txNode* item;
3530
3.99k
    while ((item = *address)) {
3531
3.69k
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3532
3.69k
      binding->next = item->next;
3533
3.69k
      address = &(binding->next);
3534
3.69k
    }
3535
300
    return theNode;
3536
300
  }
3537
9.46k
  if (aToken == XS_TOKEN_OBJECT_BINDING) {
3538
29
    txNodeList* list = ((txObjectBindingNode*)theNode)->items;
3539
29
    txNode** address = &(list->first);
3540
29
    txNode* item;
3541
43
    while ((item = *address)) {
3542
14
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3543
14
      binding->next = item->next;
3544
14
      address = &(binding->next);
3545
14
    }
3546
29
    return theNode;
3547
29
  }
3548
9.43k
  if (aToken == XS_TOKEN_PROPERTY_BINDING) {
3549
12
    ((txPropertyBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingNode*)theNode)->binding, theToken);
3550
12
    return theNode;
3551
12
  }
3552
9.42k
  if (aToken == XS_TOKEN_PROPERTY_BINDING_AT) {
3553
1
    ((txPropertyBindingAtNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingAtNode*)theNode)->binding, theToken);
3554
1
    return theNode;
3555
1
  }
3556
9.42k
  if (aToken == XS_TOKEN_REST_BINDING) {
3557
31
    ((txRestBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txRestBindingNode*)theNode)->binding, theToken);
3558
31
    return theNode;
3559
31
  }
3560
9.39k
  if (aToken == XS_TOKEN_SKIP_BINDING)
3561
2.74k
    return theNode;
3562
  
3563
6.65k
  if (aToken == XS_TOKEN_ACCESS) {
3564
5.37k
    fxCheckStrictSymbol(parser, ((txAccessNode*)theNode)->symbol);
3565
5.37k
    if (theToken == XS_TOKEN_ACCESS)
3566
2.36k
      return theNode;
3567
3.00k
    fxPushSymbol(parser, ((txAccessNode*)theNode)->symbol);
3568
3.00k
    fxPushNodeStruct(parser, 1, theToken, ((txAccessNode*)theNode)->line);
3569
3.00k
    return fxPopNode(parser);
3570
5.37k
  }
3571
1.27k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3572
212
    return theNode;
3573
212
  }
3574
1.06k
  if (aToken == XS_TOKEN_ASSIGN) {
3575
249
    binding = fxBindingFromExpression(parser, ((txAssignNode*)theNode)->reference, theToken);
3576
249
    if (!binding)
3577
0
      return NULL;
3578
249
    ((txBindingNode*)theNode)->description = &gxTokenDescriptions[XS_TOKEN_BINDING];
3579
249
    ((txBindingNode*)theNode)->target = binding;
3580
249
    ((txBindingNode*)theNode)->initializer = ((txAssignNode*)theNode)->value;
3581
249
    return theNode;
3582
249
  }
3583
  
3584
818
  if (aToken == XS_TOKEN_ARRAY)
3585
348
    return fxArrayBindingFromExpression(parser, theNode, theToken);
3586
470
  if (aToken == XS_TOKEN_OBJECT)
3587
166
    return fxObjectBindingFromExpression(parser, theNode, theToken);
3588
304
  return NULL;
3589
470
}
3590
3591
void fxArrayBinding(txParser* parser, txToken theToken)
3592
29.3k
{
3593
29.3k
  txInteger aCount = 0;
3594
29.3k
  txInteger aLine = parser->states[0].line;
3595
29.3k
  int elision = 1;
3596
29.3k
  fxCheckParserStack(parser, aLine);
3597
29.3k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
3598
82.9k
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING)) {
3599
53.6k
    txInteger anItemLine = parser->states[0].line;
3600
53.6k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
3601
40.2k
      fxGetNextToken(parser);
3602
40.2k
      if (elision) {
3603
28.8k
        fxPushNodeStruct(parser, 0, XS_TOKEN_SKIP_BINDING, anItemLine);
3604
28.8k
        aCount++;
3605
28.8k
      }
3606
11.3k
      else
3607
11.3k
        elision = 1;
3608
40.2k
    }
3609
13.4k
    else {
3610
13.4k
      if (!elision)
3611
506
        fxReportParserError(parser, parser->states[0].line, "missing ,");
3612
13.4k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3613
20
        fxRestBinding(parser, theToken, 0);
3614
20
        aCount++;
3615
20
        break;
3616
20
      }
3617
13.4k
      fxBinding(parser, theToken, 1);
3618
13.4k
      aCount++;
3619
13.4k
      elision = 0;
3620
13.4k
    }
3621
53.6k
  }
3622
29.3k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3623
29.3k
  fxPushNodeList(parser, aCount);
3624
29.3k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, aLine);
3625
29.3k
}
3626
3627
txNode* fxArrayBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3628
794
{
3629
794
  txNodeList* list = ((txArrayNode*)theNode)->items;
3630
794
  txNode** address = &(list->first);
3631
794
  txNode* item;
3632
794
  txNode* binding;
3633
3.51k
  while ((item = *address)) {
3634
2.86k
        if (!item->description) {
3635
0
            parser->errorSymbol = parser->SyntaxErrorSymbol;
3636
0
            return NULL;
3637
0
        }
3638
2.86k
    if (item->description->token == XS_TOKEN_SPREAD) {
3639
42
      if (theNode->flags & mxElisionFlag) {
3640
1
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3641
1
        return NULL;
3642
1
      }
3643
41
      binding = fxRestBindingFromExpression(parser, item, theToken, 0);
3644
41
      if (!binding) {
3645
4
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3646
4
        return NULL;
3647
4
      }
3648
37
      break;
3649
41
    }
3650
2.82k
    if (item->description->token == XS_TOKEN_ELISION) {
3651
1.26k
      item->description = &gxTokenDescriptions[XS_TOKEN_SKIP_BINDING];
3652
1.26k
    }
3653
1.55k
    else {
3654
//      if ((theToken == XS_TOKEN_BINDING) && ((item->description->token== XS_TOKEN_MEMBER) || (item->description->token == XS_TOKEN_MEMBER_AT)))
3655
//        binding = item;
3656
//      else {      
3657
1.55k
        binding = fxBindingFromExpression(parser, item, theToken);
3658
1.55k
        if (!binding) {
3659
103
          parser->errorSymbol = parser->SyntaxErrorSymbol;
3660
103
          return NULL;
3661
103
        }
3662
1.45k
        binding->next = item->next;
3663
1.45k
        item = *address = binding;
3664
//      }
3665
1.45k
    }
3666
2.71k
    address = &(item->next);
3667
2.71k
  }
3668
686
  fxPushNode(parser, (txNode*)list);
3669
686
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, theNode->line);
3670
686
  return fxPopNode(parser);
3671
794
}
3672
3673
txUnsigned fxObjectBinding(txParser* parser, txToken theToken)
3674
10.2k
{
3675
10.2k
  txUnsigned flags = 0;
3676
10.2k
  txInteger aCount = 0;
3677
10.2k
  txInteger aLine = parser->states[0].line;
3678
10.2k
  txSymbol* aSymbol;
3679
10.2k
  txToken aToken;
3680
10.2k
  txIndex index;
3681
10.2k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3682
11.9k
  for (;;) {
3683
11.9k
    txInteger aPropertyLine = parser->states[0].line;
3684
11.9k
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3685
87
      break;
3686
11.8k
    aSymbol = NULL;
3687
11.8k
    aToken = XS_TOKEN_PROPERTY_BINDING;
3688
11.8k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3689
4.09k
      aSymbol = parser->states[0].symbol;
3690
4.09k
      fxPushSymbol(parser, aSymbol);
3691
4.09k
      aToken = XS_TOKEN_PROPERTY_BINDING;
3692
4.09k
    }
3693
7.79k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3694
867
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3695
867
        fxPushIndexNode(parser, index, aPropertyLine);
3696
867
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3697
867
      }
3698
0
      else {
3699
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3700
0
        fxPushSymbol(parser, aSymbol);
3701
0
        aToken = XS_TOKEN_PROPERTY_BINDING;
3702
0
      }
3703
867
    }
3704
6.93k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3705
2.35k
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3706
4
        fxPushIndexNode(parser, index, aPropertyLine);
3707
4
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3708
4
      }
3709
2.34k
      else {
3710
2.34k
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3711
2.34k
        fxPushSymbol(parser, aSymbol);
3712
2.34k
        aToken = XS_TOKEN_PROPERTY_BINDING;
3713
2.34k
      }
3714
2.35k
    }
3715
4.57k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3716
222
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3717
3
        fxPushIndexNode(parser, index, aPropertyLine);
3718
3
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3719
3
      }
3720
219
      else {
3721
219
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3722
219
        fxPushSymbol(parser, aSymbol);
3723
219
        aToken = XS_TOKEN_PROPERTY_BINDING;
3724
219
      }
3725
222
    }
3726
4.35k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3727
2.44k
      fxGetNextToken(parser);
3728
2.44k
      fxCommaExpression(parser);
3729
2.44k
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3730
703
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3731
703
      }
3732
2.44k
      aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3733
2.44k
    }
3734
1.91k
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
3735
103
      flags |= mxSpreadFlag;
3736
103
      fxRestBinding(parser, theToken, 1);
3737
103
      aCount++;
3738
103
            break;
3739
103
    }
3740
1.81k
    else {
3741
1.81k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3742
1.81k
      fxPushNULL(parser);
3743
1.81k
    }
3744
11.7k
    fxLookAheadOnce(parser);
3745
11.7k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3746
230
      fxGetNextToken(parser);
3747
230
      fxGetNextToken(parser);
3748
230
      fxBinding(parser, theToken, 1);
3749
230
    }
3750
11.5k
    else if (aSymbol) {
3751
4.84k
      fxBinding(parser, theToken, 1);
3752
4.84k
    }
3753
6.71k
    else {
3754
6.71k
      fxReportParserError(parser, parser->states[0].line, "missing :");
3755
6.71k
      fxPushNULL(parser);
3756
6.71k
    }
3757
11.7k
    fxPushNodeStruct(parser, 2, aToken, aPropertyLine);
3758
11.7k
    aCount++;
3759
11.7k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3760
220
            break;
3761
11.5k
    if (parser->states[0].token == XS_TOKEN_COMMA)
3762
1.74k
      fxGetNextToken(parser);
3763
9.83k
    else
3764
9.83k
            break;
3765
11.5k
  }
3766
10.2k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3767
10.2k
  fxPushNodeList(parser, aCount);
3768
10.2k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, aLine);
3769
10.2k
  parser->root->flags |= flags;
3770
10.2k
  return flags;
3771
10.2k
}
3772
3773
txNode* fxObjectBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3774
6.10k
{
3775
6.10k
  txNodeList* list = ((txObjectNode*)theNode)->items;
3776
6.10k
  txNode* property = list->first;
3777
6.10k
  txNode* binding;
3778
6.10k
  txUnsigned flags = 0;
3779
7.20k
  while (property) {
3780
1.62k
    if (!property->description) {
3781
0
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3782
0
      return NULL;
3783
0
    }
3784
1.62k
    if (property->description->token == XS_TOKEN_PROPERTY) {
3785
1.09k
      binding = fxBindingFromExpression(parser, ((txPropertyNode*)property)->value, theToken);
3786
1.09k
      if (!binding) {
3787
200
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3788
200
        return NULL;
3789
200
      }
3790
895
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING];
3791
895
      ((txPropertyBindingNode*)property)->binding = binding;
3792
895
    }
3793
534
    else if (property->description->token == XS_TOKEN_PROPERTY_AT) {
3794
204
      binding = fxBindingFromExpression(parser, ((txPropertyAtNode*)property)->value, theToken);
3795
204
      if (!binding) {
3796
1
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3797
1
        return NULL;
3798
1
      }
3799
203
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING_AT];
3800
203
      ((txPropertyBindingAtNode*)property)->binding = binding;
3801
203
    }
3802
330
    else if (property->description->token == XS_TOKEN_SPREAD) {
3803
330
      binding = fxRestBindingFromExpression(parser, property, theToken, 1);
3804
330
      if (!binding) {
3805
2
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3806
2
        return NULL;
3807
2
      }
3808
328
      flags |= mxSpreadFlag;
3809
328
      break;
3810
330
    }
3811
1.09k
    property = property->next;
3812
1.09k
  }
3813
5.90k
  fxPushNode(parser, (txNode*)list);
3814
5.90k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, theNode->line);
3815
5.90k
  parser->root->flags |= flags;
3816
5.90k
  return fxPopNode(parser);
3817
6.10k
}
3818
3819
void fxParametersBinding(txParser* parser)
3820
282k
{
3821
282k
  txInteger aCount = 0;
3822
282k
  txInteger aLine = parser->states[0].line;
3823
282k
  txBindingNode* binding;
3824
282k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3825
281k
    fxGetNextToken(parser);
3826
298k
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
3827
17.0k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3828
225
        parser->flags |= mxNotSimpleParametersFlag;
3829
225
        fxRestBinding(parser, XS_TOKEN_ARG, 0);
3830
225
        aCount++;
3831
225
        break;
3832
225
      }
3833
16.8k
      fxBinding(parser, XS_TOKEN_ARG, 1);
3834
16.8k
      binding = (txBindingNode*)parser->root;
3835
16.8k
      if (binding->description->token != XS_TOKEN_ARG)
3836
1.13k
        parser->flags |= mxNotSimpleParametersFlag;
3837
16.8k
      aCount++;
3838
16.8k
      if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3839
7.39k
        fxMatchToken(parser, XS_TOKEN_COMMA);
3840
16.8k
    }
3841
281k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3842
281k
  }
3843
687
  else
3844
687
    fxReportParserError(parser, parser->states[0].line, "missing (");
3845
282k
  fxPushNodeList(parser, aCount);
3846
282k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
3847
282k
}
3848
3849
txNode* fxParametersBindingFromExpressions(txParser* parser, txNode* theNode)
3850
22.5k
{
3851
22.5k
  txNodeList* list = ((txParamsNode*)theNode)->items;
3852
22.5k
  txNode** address = &(list->first);
3853
22.5k
  txNode* item;
3854
22.5k
  txBindingNode* binding;
3855
24.9k
  while ((item = *address)) {
3856
2.54k
    txToken aToken = (item && item->description) ? item->description->token : XS_NO_TOKEN;
3857
2.54k
    if (aToken == XS_TOKEN_SPREAD) {
3858
12
      binding = (txBindingNode*)fxRestBindingFromExpression(parser, item, XS_TOKEN_ARG, 0);
3859
12
      if (!binding)
3860
2
        return NULL;
3861
10
      parser->flags |= mxNotSimpleParametersFlag;
3862
10
      break;
3863
12
    }
3864
2.53k
    binding = (txBindingNode*)fxBindingFromExpression(parser, item, XS_TOKEN_ARG);
3865
2.53k
    if (!binding)
3866
95
      return NULL;
3867
2.44k
    if (binding->description->token != XS_TOKEN_ARG)
3868
196
      parser->flags |= mxNotSimpleParametersFlag;
3869
2.44k
    binding->next = item->next;
3870
2.44k
    item = *address = (txNode*)binding;
3871
2.44k
    address = &(item->next);
3872
2.44k
  }
3873
22.4k
  theNode->description = &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING];
3874
22.4k
  return theNode;
3875
22.5k
}
3876
3877
void fxRestBinding(txParser* parser, txToken theToken, txUnsigned flag)
3878
348
{
3879
348
  txInteger aLine = parser->states[0].line;
3880
348
  fxMatchToken(parser, XS_TOKEN_SPREAD);
3881
348
  fxBinding(parser, theToken, 0);
3882
348
  if (flag && ((parser->root->description->token == XS_TOKEN_ARRAY_BINDING) || (parser->root->description->token == XS_TOKEN_OBJECT_BINDING))) {
3883
9
    fxReportParserError(parser, parser->states[0].line, "invalid rest");
3884
9
  }
3885
348
  fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
3886
348
}
3887
3888
txNode* fxRestBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken, txUnsigned flag)
3889
383
{
3890
383
  txNode* expression = ((txSpreadNode*)theNode)->expression;
3891
383
  txNode* binding;
3892
383
  if (theNode->next) {
3893
3
    parser->errorSymbol = parser->SyntaxErrorSymbol;
3894
3
    return NULL;
3895
3
  }
3896
380
  if (!expression)
3897
0
    return NULL;
3898
//  if ((theToken == XS_TOKEN_BINDING) && ((expression->description->token == XS_TOKEN_MEMBER) || (expression->description->token == XS_TOKEN_MEMBER_AT)))
3899
//    binding = expression;
3900
//  else {      
3901
380
    binding = fxBindingFromExpression(parser, expression, theToken);
3902
380
    if (!binding) {
3903
5
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3904
5
      return NULL;
3905
5
    }
3906
375
    if (binding->description->token == XS_TOKEN_BINDING) {
3907
67
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3908
67
      return NULL;
3909
67
    }
3910
308
    if (flag && ((binding->description->token == XS_TOKEN_ARRAY_BINDING) || (binding->description->token == XS_TOKEN_OBJECT_BINDING))) {
3911
53
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3912
53
      return NULL;
3913
53
    }
3914
//  }
3915
255
  theNode->description = &gxTokenDescriptions[XS_TOKEN_REST_BINDING];
3916
255
  ((txRestBindingNode*)theNode)->binding = binding;
3917
255
  return theNode;
3918
308
}
3919
3920
void fxCheckArrowFunction(txParser* parser, txInteger count)
3921
5.36M
{
3922
5.36M
  txNode* node = parser->root;
3923
15.4M
  while (count) {
3924
10.1M
    if (node->flags & mxArrowFlag)
3925
11.3k
      fxReportParserError(parser, parser->states[0].line, "invalid arrow function");
3926
10.1M
    count--;
3927
10.1M
    node = node->next;
3928
10.1M
  }
3929
5.36M
}
3930
3931
static void fxReportWarning(txParser* parser, txInteger line, txString theFormat, ...)
3932
0
{
3933
0
  c_va_list arguments;
3934
0
  c_va_start(arguments, theFormat);
3935
0
    (*parser->reportWarning)(parser->console, parser->path ? parser->path->string : C_NULL, line, theFormat, arguments);
3936
0
  c_va_end(arguments);
3937
0
}
3938
3939
void fxCheckNativeConstructor(txParser* parser)
3940
504
{
3941
504
  txClassNode* root = (txClassNode*)(parser->root);
3942
504
  if (root->description != &gxTokenDescriptions[XS_TOKEN_CLASS])
3943
487
    return;
3944
17
  if (root->symbol != C_NULL)
3945
4
    return;
3946
13
  txHostNode* host = (txHostNode*)(root->heritage);
3947
13
  if (host == C_NULL)
3948
12
    return;
3949
1
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
3950
1
    return;
3951
0
  if (root->constructorInit != C_NULL)
3952
0
    return;
3953
0
  if (root->instanceInit != C_NULL)
3954
0
    return;
3955
0
  txFunctionNode* constructor = (txFunctionNode*)(root->constructor);
3956
0
  if (constructor->description != &gxTokenDescriptions[XS_TOKEN_FUNCTION])
3957
0
    return;
3958
0
  txParamsBindingNode* args = (txParamsBindingNode*)(constructor->params);
3959
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
3960
0
    return;
3961
0
  if (args->items->length != 0)
3962
0
    return;
3963
0
  txBodyNode* body = (txBodyNode*)(constructor->body);
3964
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3965
0
    return;
3966
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3967
0
  if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
3968
0
    return;
3969
0
  txNode* undefined = (txNode*)(statement->expression);
3970
0
  if (undefined->description != &gxTokenDescriptions[XS_TOKEN_UNDEFINED])
3971
0
    return;
3972
0
  fxPopNode(parser);
3973
0
  fxPushNode(parser, (txNode*)host);
3974
0
}
3975
3976
void fxCheckNativeFunction(txParser* parser)
3977
0
{
3978
0
  txFunctionNode* function = (txFunctionNode*)(parser->root);
3979
0
  txBodyNode* body = (txBodyNode*)(function->body);
3980
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3981
0
    goto bail;
3982
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3983
0
  if ((function->flags & mxDerivedFlag) && (function->flags & mxHostFlag)) {
3984
0
    txStatementsNode* statements = (txStatementsNode*)(statement);
3985
0
    if (statements->description != &gxTokenDescriptions[XS_TOKEN_STATEMENTS])
3986
0
      goto bail;
3987
0
    if (statements->items->length != 2)
3988
0
      goto bail;
3989
0
    statement = (txStatementNode*)(statements->items->first);
3990
0
    if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
3991
0
      goto bail;
3992
0
    txSuperNode* super = (txSuperNode*)(statement->expression);
3993
0
    if (super->description != &gxTokenDescriptions[XS_TOKEN_SUPER])
3994
0
      goto bail;
3995
0
    txParamsNode* params = (txParamsNode*)(super->params);
3996
0
    if (params->items->length != 0)
3997
0
      goto bail;
3998
0
    statement = (txStatementNode*)(statement->next);
3999
0
  }
4000
0
  if ((statement->description != &gxTokenDescriptions[XS_TOKEN_RETURN]) && (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT]))
4001
0
    goto bail;
4002
0
  txCallNewNode* call = (txCallNewNode*)(statement->expression);
4003
0
  if (call->description != &gxTokenDescriptions[XS_TOKEN_CALL])
4004
0
    goto bail;
4005
0
  txMemberNode* member = (txMemberNode*)(call->reference);
4006
0
  if (member->description != &gxTokenDescriptions[XS_TOKEN_MEMBER])
4007
0
    goto bail;
4008
0
  if (member->symbol != parser->callSymbol)
4009
0
    goto bail;
4010
0
  txHostNode* host = (txHostNode*)(member->reference);
4011
0
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
4012
0
    goto bail;
4013
0
  txParamsNode* params = (txParamsNode*)(call->params);
4014
0
  if (params->description != &gxTokenDescriptions[XS_TOKEN_PARAMS])
4015
0
    goto bail;
4016
0
  txParamsBindingNode* args = (txParamsBindingNode*)(function->params);
4017
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
4018
0
    goto bail;
4019
0
  if (params->items->length != args->items->length + 1)
4020
0
    goto bail;
4021
0
  txNode* arg = args->items->first;
4022
0
  txNode* param = params->items->first;
4023
0
  if (param->description != &gxTokenDescriptions[XS_TOKEN_THIS])
4024
0
    goto bail;
4025
0
  param = param->next;
4026
0
  while (arg) {
4027
0
    txDeclareNode* binding;
4028
0
    txAccessNode* access;
4029
0
    if (arg->description == &gxTokenDescriptions[XS_TOKEN_REST_BINDING]) {
4030
0
      if (param->description != &gxTokenDescriptions[XS_TOKEN_SPREAD])
4031
0
        goto bail;
4032
0
      binding = (txDeclareNode*)(((txRestBindingNode*)arg)->binding);
4033
0
      access = (txAccessNode*)(((txSpreadNode*)param)->expression);
4034
0
    }
4035
0
    else {
4036
0
      binding = (txDeclareNode*)arg;
4037
0
      access = (txAccessNode*)param;
4038
0
    }
4039
0
    if (binding->description != &gxTokenDescriptions[XS_TOKEN_ARG])
4040
0
      goto bail;
4041
0
    if (access->description != &gxTokenDescriptions[XS_TOKEN_ACCESS])
4042
0
      goto bail;
4043
0
    if (binding->symbol != access->symbol)
4044
0
      goto bail;
4045
0
    arg = arg->next;
4046
0
    param = param->next;
4047
0
  }
4048
0
  host->flags |= function->flags;
4049
0
  host->params = (txNode*)args;
4050
0
  fxPopNode(parser);
4051
0
  fxPushNode(parser, (txNode*)host);
4052
0
  return;
4053
0
bail:
4054
0
    fxReportWarning(parser, function->line, "cannot optimize native");
4055
0
}
4056
4057
txBoolean fxCheckReference(txParser* parser, txToken theToken)
4058
227k
{
4059
227k
  txNode* node = parser->root;
4060
227k
  txToken aToken = (node && node->description) ? node->description->token : XS_NO_TOKEN;
4061
227k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
4062
1.39k
    txNode* item;
4063
1.63k
  again:
4064
1.63k
    item = ((txExpressionsNode*)node)->items->first;
4065
1.63k
    if (item && !item->next) {
4066
1.52k
      aToken = (item->description) ? item->description->token : XS_NO_TOKEN;
4067
1.52k
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
4068
90
        item->next = node->next;
4069
90
        node = parser->root = item;
4070
90
      }
4071
1.43k
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
4072
235
        item->next = node->next;
4073
235
        node = item;
4074
235
        goto again;
4075
235
      }
4076
1.20k
      else
4077
1.20k
        aToken = XS_TOKEN_EXPRESSIONS;
4078
1.52k
    }
4079
1.63k
  }
4080
227k
  if (aToken == XS_TOKEN_ACCESS) {
4081
183k
    fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4082
183k
    return 1;
4083
183k
  }
4084
44.2k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED))
4085
26.2k
    return 1;
4086
    
4087
18.0k
  if (theToken == XS_TOKEN_ASSIGN) {
4088
9.77k
    if (aToken == XS_TOKEN_ARRAY) {
4089
446
      txNode* binding = fxArrayBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4090
446
            if (binding) {
4091
425
                binding->next = node->next;
4092
425
                parser->root = binding;
4093
425
        return 1;
4094
425
           }
4095
446
        }
4096
9.33k
    else if (aToken == XS_TOKEN_OBJECT) {
4097
5.93k
      txNode* binding = fxObjectBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4098
5.93k
            if (binding) {
4099
5.62k
                binding->next = node->next;
4100
5.62k
                parser->root = binding;
4101
5.62k
        return 1;
4102
5.62k
            }
4103
5.93k
        }
4104
9.77k
  }
4105
8.23k
  else if (theToken == XS_TOKEN_DELETE)
4106
1.19k
    return 1;
4107
10.7k
  return 0;
4108
18.0k
}
4109
4110
void fxCheckStrictBinding(txParser* parser, txNode* node)
4111
30.7k
{
4112
30.7k
  if (node && node->description) {
4113
30.7k
    if (node->description->token == XS_TOKEN_ACCESS) {
4114
0
      fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4115
0
    }
4116
30.7k
    else if (node->description->token == XS_TOKEN_ARG) {
4117
3.29k
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4118
3.29k
    }
4119
27.4k
    else if (node->description->token == XS_TOKEN_CONST) {
4120
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4121
0
    }
4122
27.4k
    else if (node->description->token == XS_TOKEN_LET) {
4123
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4124
0
    }
4125
27.4k
    else if (node->description->token == XS_TOKEN_USING) {
4126
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4127
0
    }
4128
27.4k
    else if (node->description->token == XS_TOKEN_VAR) {
4129
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4130
0
    }
4131
27.4k
    else if (node->description->token == XS_TOKEN_BINDING) {
4132
7
      fxCheckStrictBinding(parser, ((txBindingNode*)node)->target);
4133
7
    }
4134
27.4k
    else if (node->description->token == XS_TOKEN_ARRAY_BINDING) {
4135
162
      node = ((txArrayBindingNode*)node)->items->first;
4136
732
      while (node) {
4137
570
        fxCheckStrictBinding(parser, node);
4138
570
        node = node->next;
4139
570
      }
4140
162
    }
4141
27.2k
    else if (node->description->token == XS_TOKEN_OBJECT_BINDING) {
4142
19
      node = ((txObjectBindingNode*)node)->items->first;
4143
35
      while (node) {
4144
16
        fxCheckStrictBinding(parser, node);
4145
16
        node = node->next;
4146
16
      }
4147
19
    }
4148
27.2k
    else if (node->description->token == XS_TOKEN_PARAMS_BINDING) {
4149
27.2k
      node = ((txParamsBindingNode*)node)->items->first;
4150
30.1k
      while (node) {
4151
2.91k
        fxCheckStrictBinding(parser, node);
4152
2.91k
        node = node->next;
4153
2.91k
      }
4154
27.2k
    }
4155
50
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING)
4156
14
      fxCheckStrictBinding(parser, ((txPropertyBindingNode*)node)->binding);
4157
36
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING_AT)
4158
1
      fxCheckStrictBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
4159
35
    else if (node->description->token == XS_TOKEN_REST_BINDING)
4160
10
      fxCheckStrictBinding(parser, ((txRestBindingNode*)node)->binding);
4161
30.7k
  }
4162
30.7k
}
4163
4164
void fxCheckStrictFunction(txParser* parser, txFunctionNode* function)
4165
4.77k
{
4166
4.77k
  parser->states[0].line = function->line;
4167
4.77k
  fxCheckStrictSymbol(parser, function->symbol);
4168
4.77k
  fxCheckStrictBinding(parser, function->params);
4169
4.77k
}
4170
4171
void fxCheckStrictSymbol(txParser* parser, txSymbol* symbol)
4172
608k
{
4173
608k
  if (parser->flags & mxStrictFlag) {
4174
16.6k
    if (symbol == parser->argumentsSymbol)
4175
4
      fxReportParserError(parser, parser->states[0].line, "invalid arguments (strict mode)");
4176
16.6k
    else if (symbol == parser->evalSymbol)
4177
1
      fxReportParserError(parser, parser->states[0].line, "invalid eval (strict mode)");
4178
16.6k
    else if (symbol == parser->yieldSymbol)
4179
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield (strict mode)");
4180
16.6k
  }
4181
591k
  else if (parser->flags & mxYieldFlag) {
4182
1.26k
    if (symbol == parser->yieldSymbol)
4183
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
4184
1.26k
  }
4185
608k
}
4186
4187
void fxCheckUniqueProperty(txParser* parser, txNode* base, txNode* current)
4188
102k
{
4189
102k
  return; // no more!
4190
0
  if (current->description->token == XS_TOKEN_PROPERTY) {
4191
0
    txPropertyNode* currentNode = (txPropertyNode*)current;
4192
0
    while (base != current) {
4193
0
      txPropertyNode* baseNode = (txPropertyNode*)base;
4194
0
      if (baseNode->description->token == XS_TOKEN_PROPERTY) {
4195
0
        if (baseNode->symbol == currentNode->symbol) {
4196
0
          fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4197
0
        }
4198
0
      }
4199
0
      base = base->next;
4200
0
    }
4201
0
  }
4202
0
  else {
4203
0
    txPropertyAtNode* currentNode = (txPropertyAtNode*)current;
4204
0
    txIntegerNode* currentAt = (txIntegerNode*)(currentNode->at);
4205
0
    if (currentAt->description->token == XS_TOKEN_INTEGER) {
4206
0
      while (base != current) {
4207
0
        txPropertyAtNode* baseNode = (txPropertyAtNode*)base;
4208
0
        if (baseNode->description->token == XS_TOKEN_PROPERTY_AT) {
4209
0
          txIntegerNode* baseAt = (txIntegerNode*)(baseNode->at);
4210
0
          if (baseAt->description->token == XS_TOKEN_INTEGER) {
4211
0
            if (baseAt->value == currentAt->value) {
4212
0
              fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4213
0
            }
4214
0
          }
4215
0
        }
4216
0
        base = base->next;
4217
0
      }
4218
0
    }
4219
0
  }
4220
0
}
4221
4222
void fxCheckUniquePropertyAux(txParser* parser, txNode* baseNode, txNode* currentNode)
4223
0
{
4224
0
  if (currentNode->flags & mxGetterFlag) {
4225
0
    if (baseNode->flags & mxGetterFlag)
4226
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4227
0
    else if (!(baseNode->flags & mxSetterFlag))
4228
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4229
0
  }
4230
0
  else if (currentNode->flags & mxSetterFlag) {
4231
0
    if (baseNode->flags & mxSetterFlag)
4232
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4233
0
    else if (!(baseNode->flags & mxGetterFlag))
4234
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4235
0
  }
4236
0
  else {
4237
0
    if (baseNode->flags & mxGetterFlag)
4238
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4239
0
    else if (baseNode->flags & mxSetterFlag)
4240
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4241
0
    else if (parser->flags & mxStrictFlag)
4242
0
      fxReportParserError(parser, parser->states[0].line, "property already defined (strict mode)");
4243
0
  }
4244
0
}
4245
4246
4247
void fxJSONValue(txParser* parser)
4248
0
{
4249
0
  switch (parser->states[0].token) {
4250
0
  case XS_TOKEN_FALSE:
4251
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4252
0
    fxGetNextTokenJSON(parser);
4253
0
    break;
4254
0
  case XS_TOKEN_TRUE:
4255
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4256
0
    fxGetNextTokenJSON(parser);
4257
0
    break;
4258
0
  case XS_TOKEN_NULL:
4259
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4260
0
    fxGetNextTokenJSON(parser);
4261
0
    break;
4262
0
  case XS_TOKEN_INTEGER:
4263
0
    fxPushIntegerNode(parser, parser->states[0].integer, parser->states[0].line);
4264
0
    fxGetNextTokenJSON(parser);
4265
0
    break;
4266
0
  case XS_TOKEN_NUMBER:
4267
0
    fxPushNumberNode(parser, parser->states[0].number, parser->states[0].line);
4268
0
    fxGetNextTokenJSON(parser);
4269
0
    break;
4270
0
  case XS_TOKEN_STRING:
4271
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4272
0
    fxGetNextTokenJSON(parser);
4273
0
    break;
4274
0
  case XS_TOKEN_LEFT_BRACE:
4275
0
    fxJSONObject(parser);
4276
0
    break;
4277
0
  case XS_TOKEN_LEFT_BRACKET:
4278
0
    fxJSONArray(parser);
4279
0
    break;
4280
0
  default:
4281
0
    fxPushNULL(parser);
4282
0
    fxReportParserError(parser, parser->states[0].line, "invalid value");
4283
0
    break;
4284
0
  }
4285
0
}
4286
4287
void fxJSONObject(txParser* parser)
4288
0
{
4289
0
  txIndex aLength = 0;
4290
0
  txInteger aLine = parser->states[0].line;
4291
0
  fxGetNextTokenJSON(parser);
4292
0
  for (;;) {
4293
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4294
0
      break;
4295
0
    if (parser->states[0].token != XS_TOKEN_STRING) {
4296
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4297
0
      break;
4298
0
    }
4299
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4300
0
    fxGetNextTokenJSON(parser);
4301
0
    if (parser->states[0].token != XS_TOKEN_COLON) {
4302
0
      fxReportParserError(parser, parser->states[0].line, "missing :");
4303
0
      break;
4304
0
    }
4305
0
    fxGetNextTokenJSON(parser);
4306
0
    fxJSONValue(parser);
4307
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY_AT, parser->states[0].line);
4308
0
    aLength++;
4309
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4310
0
      break;
4311
0
    fxGetNextTokenJSON(parser);
4312
0
  }
4313
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4314
0
    fxReportParserError(parser, parser->states[0].line, "missing }");
4315
0
  fxGetNextTokenJSON(parser);
4316
0
  fxPushNodeList(parser, aLength);
4317
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
4318
0
}
4319
4320
void fxJSONArray(txParser* parser)
4321
0
{
4322
0
  txIndex aLength = 0;
4323
0
  txInteger aLine = parser->states[0].line;
4324
0
  fxGetNextTokenJSON(parser);
4325
0
  for (;;) {
4326
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACKET)
4327
0
      break;
4328
0
    fxJSONValue(parser);
4329
0
    aLength++;
4330
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4331
0
      break;
4332
0
    fxGetNextTokenJSON(parser);
4333
0
  }
4334
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET)
4335
0
    fxReportParserError(parser, parser->states[0].line, "missing ]");
4336
0
  fxGetNextTokenJSON(parser);
4337
0
  fxPushNodeList(parser, aLength);
4338
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
4339
0
}
4340
4341
void fxJSONModule(txParser* parser)
4342
0
{
4343
0
  fxJSONValue(parser);
4344
  
4345
0
  fxPushSymbol(parser, parser->defaultSymbol);
4346
0
  fxPushNULL(parser);
4347
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, 1);
4348
0
  fxSwapNodes(parser);
4349
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, 1);
4350
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, 1);
4351
  
4352
0
  fxPushSymbol(parser, parser->defaultSymbol);
4353
0
  fxPushNULL(parser);
4354
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, 1);
4355
0
  fxPushNodeList(parser, 1);
4356
0
  fxPushNULL(parser);
4357
0
  fxPushNULL(parser);
4358
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, 1);
4359
  
4360
0
  fxPushNodeList(parser, 2);
4361
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, 1);
4362
  
4363
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, 1);
4364
0
}
4365
4366
static txSymbol* fxJSXName(txParser* parser, txSymbol* before, txSymbol* after)
4367
1.38k
{
4368
1.38k
  txSize beforeLength = before->length;
4369
1.38k
  txSize afterLength = after->length;
4370
1.38k
  txSize length = beforeLength + 1 + afterLength + 1;
4371
1.38k
  txString string = fxNewParserChunk(parser, length);
4372
1.38k
  snprintf(string, length, "%s-%s", before->string, after->string);
4373
1.38k
  return fxNewParserSymbol(parser, string);
4374
1.38k
}
4375
4376
void fxJSXAttributeName(txParser* parser)
4377
11.5k
{
4378
11.5k
  txSymbol* symbol = parser->states[0].symbol;
4379
11.5k
  fxGetNextToken(parser);
4380
12.9k
  while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4381
1.35k
    fxGetNextToken(parser);
4382
1.35k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4383
1.35k
      symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4384
6
    else
4385
6
      fxReportParserError(parser, parser->states[0].line, "missing name");
4386
1.35k
    fxGetNextToken(parser);
4387
1.35k
  }
4388
11.5k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4389
2.77k
    fxGetNextToken(parser);
4390
2.77k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4391
692
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4392
2.08k
    else
4393
2.08k
      fxReportParserError(parser, parser->states[0].line, "missing name");
4394
2.77k
    fxGetNextToken(parser);
4395
3.06k
    while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4396
289
      fxGetNextToken(parser);
4397
289
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4398
31
        symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4399
258
      else
4400
258
        fxReportParserError(parser, parser->states[0].line, "missing name");
4401
289
      fxGetNextToken(parser);
4402
289
    }  
4403
2.77k
  }
4404
11.5k
  fxPushSymbol(parser, symbol);
4405
11.5k
}
4406
4407
void fxJSXAttributeValue(txParser* parser)
4408
4.78k
{
4409
4.78k
  txInteger line = parser->states[0].line;
4410
4.78k
  fxGetNextTokenJSXAttribute(parser);
4411
4.78k
  if (parser->states[0].token == XS_TOKEN_STRING) {
4412
2.21k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
4413
2.21k
    fxGetNextToken(parser);
4414
2.21k
  }
4415
2.57k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4416
17
    fxGetNextToken(parser);
4417
17
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE) {
4418
0
      fxGetNextToken(parser);
4419
0
      fxReportParserError(parser, parser->states[0].line, "missing expression");
4420
0
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4421
0
    }
4422
17
    else {
4423
17
      fxAssignmentExpression(parser);
4424
17
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4425
10
        fxGetNextToken(parser);
4426
7
      else
4427
7
        fxReportParserError(parser, parser->states[0].line, "missing }");
4428
17
    }
4429
17
  }
4430
2.56k
  else {
4431
2.56k
    fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4432
2.56k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4433
2.56k
  }
4434
4.78k
}
4435
4436
void fxJSXElement(txParser* parser)
4437
85.0k
{
4438
85.0k
  txBoolean closed = 0;
4439
85.0k
  txInteger line = parser->states[0].line;
4440
85.0k
  txNode* name = NULL;
4441
85.0k
  txInteger nodeCount = parser->nodeCount;
4442
85.0k
  txInteger propertyCount = 0;
4443
85.0k
  fxPushSymbol(parser, parser->__jsx__Symbol);
4444
85.0k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, parser->states[0].line);
4445
85.0k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4446
84.0k
    fxJSXElementName(parser);
4447
84.0k
    name = parser->root;
4448
84.0k
  }
4449
945
  else {
4450
945
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
4451
945
    fxPushNULL(parser);
4452
945
  }
4453
85.0k
  for (;;) {
4454
79.6k
    if (parser->states[0].token == XS_TOKEN_MORE)
4455
28.1k
      break;
4456
51.5k
    if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4457
34.9k
      fxGetNextToken(parser);
4458
34.9k
      if (parser->states[0].token != XS_TOKEN_MORE)
4459
1.13k
        fxReportParserError(parser, parser->states[0].line, "missing >");
4460
34.9k
      closed = 1;
4461
34.9k
      break;
4462
34.9k
    }
4463
16.5k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
4464
11.5k
      fxJSXAttributeName(parser);
4465
11.5k
      if (parser->states[0].token == XS_TOKEN_ASSIGN)
4466
4.78k
        fxJSXAttributeValue(parser);
4467
6.77k
      else
4468
6.77k
        fxPushNodeStruct(parser, 0, XS_TOKEN_TRUE, parser->states[0].line);
4469
11.5k
      fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY, parser->states[0].line);
4470
11.5k
      propertyCount++;
4471
11.5k
    }
4472
4.99k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4473
1.39k
      fxGetNextToken(parser);
4474
1.39k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
4475
7
        fxGetNextToken(parser);
4476
7
        fxAssignmentExpression(parser);
4477
7
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4478
6
          fxGetNextToken(parser);
4479
1
        else
4480
1
          fxReportParserError(parser, parser->states[0].line, "missing }");
4481
7
        fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, parser->states[0].line);
4482
7
        propertyCount++;
4483
7
      }
4484
1.38k
      else
4485
1.38k
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4486
1.39k
    }
4487
3.60k
    else {
4488
3.60k
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4489
3.60k
      break;
4490
3.60k
    }
4491
16.5k
  }
4492
85.0k
  if (propertyCount > 0) {
4493
3.73k
    fxPushNodeList(parser, propertyCount);
4494
3.73k
    fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, parser->states[0].line);
4495
3.73k
  }
4496
81.2k
  else
4497
81.2k
    fxPushNodeStruct(parser, 0, XS_TOKEN_NULL, parser->states[0].line);
4498
85.0k
  if (!closed) {
4499
64.3k
    for (;;) {
4500
64.3k
      fxGetNextTokenJSXChild(parser);
4501
64.3k
      if (parser->states[0].stringLength)
4502
20.6k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4503
64.3k
      if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4504
5.28k
        fxGetNextToken(parser);
4505
5.28k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4506
953
          fxGetNextToken(parser);
4507
4.33k
        else {
4508
4.33k
          fxAssignmentExpression(parser);
4509
4.33k
          if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4510
2.35k
            fxReportParserError(parser, parser->states[0].line, "missing }");
4511
4.33k
        }
4512
5.28k
      }
4513
59.0k
      else if (parser->states[0].token == XS_TOKEN_LESS) {
4514
52.8k
        fxGetNextToken(parser);
4515
52.8k
        if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4516
5.30k
          fxGetNextToken(parser);
4517
5.30k
          if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4518
4.72k
            fxJSXElementName(parser);
4519
4.72k
            if (!fxJSXMatch(parser, name, parser->root)) {
4520
4.50k
              fxReportParserError(parser, parser->states[0].line, "invalid element");
4521
4.50k
              fxPushNULL(parser);
4522
4.50k
            }
4523
4.72k
          }
4524
580
          else {
4525
580
            fxReportParserError(parser, parser->states[0].line, "missing identifier");
4526
580
            fxPushNULL(parser);
4527
580
          }
4528
5.30k
          if (parser->states[0].token != XS_TOKEN_MORE)
4529
4
            fxReportParserError(parser, parser->states[0].line, "missing >");
4530
5.30k
          fxPopNode(parser);
4531
5.30k
          break;
4532
5.30k
        }
4533
47.5k
        else
4534
47.5k
          fxJSXElement(parser);
4535
52.8k
      }
4536
6.23k
      else {
4537
6.23k
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4538
6.23k
        break;
4539
6.23k
      }
4540
64.3k
    }
4541
28.1k
  }
4542
85.0k
  fxPushNodeList(parser, parser->nodeCount - nodeCount - 1);
4543
85.0k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, line);
4544
85.0k
  fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, line);
4545
85.0k
}
4546
4547
void fxJSXElementName(txParser* parser)
4548
88.7k
{
4549
88.7k
  txInteger line = parser->states[0].line;
4550
88.7k
  txSymbol* symbol = parser->states[0].symbol;
4551
88.7k
  fxGetNextToken(parser);
4552
88.7k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4553
3.26k
    fxGetNextToken(parser);
4554
3.26k
    if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
4555
805
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4556
2.45k
    else
4557
2.45k
      fxReportParserError(parser, parser->states[0].line, "missing name");
4558
3.26k
    fxPushSymbol(parser, symbol);
4559
3.26k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4560
3.26k
    fxGetNextToken(parser);
4561
3.26k
  }
4562
85.5k
  else {
4563
85.5k
    fxPushSymbol(parser, symbol);
4564
85.5k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4565
108k
    while (parser->states[0].token == XS_TOKEN_DOT) {
4566
22.7k
      fxGetNextToken(parser);
4567
22.7k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4568
21.9k
        fxPushSymbol(parser, parser->states[0].symbol);
4569
21.9k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, parser->states[0].line);
4570
21.9k
        fxGetNextToken(parser);
4571
21.9k
      }
4572
769
      else
4573
769
        fxReportParserError(parser, parser->states[0].line, "missing property");
4574
22.7k
    }
4575
85.5k
  }
4576
88.7k
}
4577
4578
txBoolean fxJSXMatch(txParser* parser, txNode* opening, txNode* closing)
4579
4.72k
{
4580
4.72k
  if (opening && closing) {
4581
4.74k
    while (opening->description->token == XS_TOKEN_MEMBER) {
4582
715
      if (closing->description->token != XS_TOKEN_MEMBER)
4583
693
        return 0;
4584
22
      if (((txMemberNode*)opening)->symbol != ((txMemberNode*)closing)->symbol)
4585
3
        return 0;
4586
19
      opening = ((txMemberNode*)opening)->reference;
4587
19
      closing = ((txMemberNode*)closing)->reference;
4588
19
    }
4589
4.02k
    if (opening->description->token == XS_TOKEN_ACCESS) {
4590
4.02k
      if (closing->description->token != XS_TOKEN_ACCESS)
4591
1
        return 0;
4592
4.02k
      if (((txAccessNode*)opening)->symbol != ((txAccessNode*)closing)->symbol)
4593
3.80k
        return 0;
4594
219
      return 1;
4595
4.02k
    }
4596
4.02k
  }
4597
0
  return 0;
4598
4.72k
}
4599
4600
txSymbol* fxJSXNamespace(txParser* parser, txSymbol* namespace, txSymbol* name)
4601
1.49k
{
4602
1.49k
  txSize namespaceLength = namespace->length;
4603
1.49k
  txSize nameLength = name->length;
4604
1.49k
  txSize length = namespaceLength + 1 + nameLength + 1;
4605
1.49k
  txString string = fxNewParserChunk(parser, length);
4606
1.49k
  snprintf(string, length, "%s:%s", namespace->string, name->string);
4607
1.49k
  return fxNewParserSymbol(parser, string);
4608
1.49k
}