Coverage Report

Created: 2025-12-30 07:10

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
19.4k
#define XS_TOKEN_BEGIN_STATEMENT 1
150
6.35M
#define XS_TOKEN_BEGIN_EXPRESSION 2
151
4.71M
#define XS_TOKEN_ASSIGN_EXPRESSION 4
152
4.57M
#define XS_TOKEN_EQUAL_EXPRESSION 8
153
4.69M
#define XS_TOKEN_RELATIONAL_EXPRESSION 16
154
4.72M
#define XS_TOKEN_SHIFT_EXPRESSION 32
155
9.31M
#define XS_TOKEN_ADDITIVE_EXPRESSION 64
156
9.49M
#define XS_TOKEN_MULTIPLICATIVE_EXPRESSION 128
157
9.30M
#define XS_TOKEN_EXPONENTIATION_EXPRESSION 256
158
9.60M
#define XS_TOKEN_PREFIX_EXPRESSION 512
159
7.76M
#define XS_TOKEN_POSTFIX_EXPRESSION 1024
160
855k
#define XS_TOKEN_END_STATEMENT 2048
161
#define XS_TOKEN_REFERENCE_EXPRESSION 4096
162
752k
#define XS_TOKEN_BEGIN_BINDING 16384
163
350k
#define XS_TOKEN_IDENTIFIER_NAME 32768
164
10.0M
#define XS_TOKEN_UNARY_EXPRESSION 65536
165
9.48M
#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
388k
{
519
388k
  txBoolean result = ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == keyword)) ? 1 : 0;
520
388k
  if (result) {
521
21.1k
    if (parser->states[0].escaped)
522
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
523
21.1k
  }
524
388k
  return result;
525
388k
}
526
527
txBoolean fxIsToken(txParser* parser, txToken theToken)
528
90.2k
{
529
90.2k
  txBoolean result = (parser->states[0].token == theToken) ? 1 : 0;
530
90.2k
  if (result) {
531
41.2k
    if (parser->states[0].escaped)
532
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
533
41.2k
  }
534
90.2k
  return result;
535
90.2k
}
536
537
void fxMatchToken(txParser* parser, txToken theToken)
538
6.06M
{
539
6.06M
  if (parser->states[0].token == theToken) {
540
5.98M
    if (parser->states[0].escaped)
541
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
542
5.98M
    fxGetNextToken(parser);
543
5.98M
  }
544
86.8k
  else
545
86.8k
    fxReportParserError(parser, parser->states[0].line, "missing %s", gxTokenNames[theToken]);
546
6.06M
}
547
548
txNode* fxPopNode(txParser* parser)
549
97.5k
{
550
97.5k
  txNode* node = parser->root;
551
97.5k
  parser->root = node->next;
552
97.5k
  node->next = NULL;
553
97.5k
  parser->nodeCount--;
554
97.5k
  return node;
555
97.5k
}
556
557
void fxPushNode(txParser* parser, txNode* node)
558
29.0M
{
559
29.0M
  node->next = parser->root;
560
29.0M
  parser->root = (txNode*)node;
561
29.0M
  parser->nodeCount++;
562
29.0M
}
563
564
void fxPushBigIntNode(txParser* parser, txBigInt* value, txInteger line)
565
143k
{
566
143k
  txBigIntNode* node = fxNewParserChunk(parser, sizeof(txBigIntNode));
567
143k
  node->description = &gxTokenDescriptions[XS_TOKEN_BIGINT];
568
143k
  node->path = parser->path;
569
143k
  node->line = line;
570
143k
  node->flags = 0;
571
143k
  node->value = *value;
572
143k
  fxPushNode(parser, (txNode*)node);
573
143k
}
574
575
void fxPushIndexNode(txParser* parser, txIndex value, txInteger line)
576
35.0k
{
577
35.0k
  if (((txInteger)value) >= 0)
578
32.9k
    fxPushIntegerNode(parser, (txInteger)value, line);
579
2.08k
  else
580
2.08k
    fxPushNumberNode(parser, value, line);
581
35.0k
}
582
583
void fxPushIntegerNode(txParser* parser, txInteger value, txInteger line)
584
5.13M
{
585
5.13M
  txIntegerNode* node = fxNewParserChunk(parser, sizeof(txIntegerNode));
586
5.13M
  node->description = &gxTokenDescriptions[XS_TOKEN_INTEGER];
587
5.13M
  node->path = parser->path;
588
5.13M
  node->line = line;
589
5.13M
  node->flags = 0;
590
5.13M
  node->value = value;
591
5.13M
  fxPushNode(parser, (txNode*)node);
592
5.13M
}
593
594
void fxPushNodeStruct(txParser* parser, txInteger count, txToken token, txInteger line)
595
15.6M
{
596
15.6M
  const txNodeDescription* description = &gxTokenDescriptions[token];
597
15.6M
  txNode* node;
598
15.6M
  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
15.6M
    node = fxNewParserChunkClear(parser, description->size);
602
15.6M
  node->description = description;
603
15.6M
  node->flags |= parser->flags & (mxStrictFlag | mxGeneratorFlag | mxAsyncFlag);
604
15.6M
  node->path = parser->path;
605
15.6M
  node->line = line;
606
15.6M
    parser->nodeCount -= count;
607
15.6M
  if (count) {
608
15.0M
    txNode** dst = (txNode**)&node[1];
609
15.0M
    txNode* src = parser->root;
610
38.3M
    while (count) {
611
23.3M
      txNode* next = src->next;
612
23.3M
      src->next = NULL;
613
23.3M
      count--;
614
23.3M
      if (src->description)
615
19.3M
        dst[count] = src;
616
4.05M
      else if (src->path)
617
3.67M
        dst[count] = (txNode*)(src->path);
618
23.3M
      src = next;
619
23.3M
    }
620
15.0M
    parser->root = src;
621
15.0M
  }
622
15.6M
  fxPushNode(parser, node);
623
15.6M
}
624
625
void fxPushNodeList(txParser* parser, txInteger count)
626
2.15M
{
627
2.15M
  txNodeList* list = fxNewParserChunk(parser, sizeof(txNodeList));
628
2.15M
  txNode* previous = NULL;
629
2.15M
  txNode* current = parser->root;
630
2.15M
  txNode* next;
631
2.15M
    parser->nodeCount -= count;
632
2.15M
  list->length = count;
633
4.71M
  while (count) {
634
2.55M
    next = current->next;
635
2.55M
    current->next = previous;
636
2.55M
    previous = current;
637
2.55M
    current = next;
638
2.55M
    count--;
639
2.55M
  }
640
2.15M
  parser->root = current;
641
2.15M
  list->description = &gxTokenDescriptions[XS_NO_TOKEN];
642
2.15M
  list->first = previous;
643
2.15M
  fxPushNode(parser, (txNode*)list);
644
2.15M
}
645
646
void fxPushNULL(txParser* parser)
647
629k
{
648
629k
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
649
629k
  fxPushNode(parser, (txNode*)node);
650
629k
}
651
652
void fxPushNumberNode(txParser* parser, txNumber value, txInteger line)
653
41.3k
{
654
41.3k
  txNumberNode* node = fxNewParserChunk(parser, sizeof(txNumberNode));
655
41.3k
  node->description = &gxTokenDescriptions[XS_TOKEN_NUMBER];
656
41.3k
  node->path = parser->path;
657
41.3k
  node->line = line;
658
41.3k
  node->flags = 0;
659
41.3k
  node->value = value;
660
41.3k
  fxPushNode(parser, (txNode*)node);
661
41.3k
}
662
663
void fxPushRawNode(txParser* parser, txInteger length, txString value, txInteger line)
664
435k
{
665
435k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
666
435k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
667
435k
  node->path = parser->path;
668
435k
  node->line = line;
669
435k
  node->flags = 0;
670
435k
  node->length = length;
671
435k
  node->value = value;
672
435k
  fxPushNode(parser, (txNode*)node);
673
435k
}
674
675
void fxPushStringNode(txParser* parser, txInteger length, txString value, txInteger line)
676
833k
{
677
833k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
678
833k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
679
833k
  node->path = parser->path;
680
833k
  node->line = line;
681
833k
  node->flags = parser->states[0].escaped;
682
833k
  node->length = length;
683
833k
  node->value = value;
684
833k
  fxPushNode(parser, (txNode*)node);
685
833k
}
686
687
void fxPushSymbol(txParser* parser, txSymbol* symbol)
688
3.93M
{
689
3.93M
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
690
3.93M
  node->symbol = symbol;  
691
3.93M
  fxPushNode(parser, (txNode*)node);
692
3.93M
}
693
694
void fxSwapNodes(txParser* parser)
695
111k
{
696
111k
  txNode* previous = parser->root;
697
111k
  txNode* current = previous->next;
698
111k
  previous->next = current->next;
699
111k
  current->next = previous;
700
111k
  parser->root = current;
701
111k
}
702
703
void fxModule(txParser* parser)
704
9.16k
{
705
9.16k
  txInteger aCount = parser->nodeCount;
706
9.16k
  txInteger aLine = parser->states[0].line;
707
32.7k
  while ((parser->states[0].token != XS_TOKEN_EOF)) {
708
23.5k
    if (parser->states[0].token == XS_TOKEN_EXPORT)
709
11.6k
      fxExportDeclaration(parser);
710
11.9k
    else if (parser->states[0].token == XS_TOKEN_IMPORT) {
711
398
      fxLookAheadOnce(parser);
712
398
      if ((parser->states[1].token == XS_TOKEN_DOT) || (parser->states[1].token == XS_TOKEN_LEFT_PARENTHESIS))
713
126
        fxStatement(parser, 1);
714
272
      else
715
272
        fxImportDeclaration(parser);
716
398
    }
717
11.5k
    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
11.5k
    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
11.5k
    else {
726
11.5k
      fxStatement(parser, 1);
727
11.5k
    }
728
23.5k
  }
729
9.16k
  aCount = parser->nodeCount - aCount;
730
9.16k
  if (aCount > 1) {
731
255
    fxPushNodeList(parser, aCount);
732
255
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
733
255
  }
734
8.91k
  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
9.16k
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, aLine);
739
9.16k
  parser->root->flags = parser->flags & (mxStrictFlag | mxAwaitingFlag);
740
9.16k
}
741
742
void fxExportDeclaration(txParser* parser)
743
11.6k
{
744
11.6k
  txSymbol* symbol = C_NULL;
745
11.6k
  txInteger count;
746
11.6k
  txInteger line = parser->states[0].line;
747
11.6k
  txUnsigned flag = 0;
748
11.6k
  txToken aToken;
749
11.6k
  fxMatchToken(parser, XS_TOKEN_EXPORT);
750
11.6k
  switch (parser->states[0].token) {
751
2.45k
  case XS_TOKEN_MULTIPLY:
752
2.45k
    fxPushNULL(parser);
753
2.45k
    fxGetNextToken(parser);
754
2.45k
    if (fxIsKeyword(parser, parser->asSymbol)) {
755
1.78k
      fxGetNextToken(parser);
756
1.78k
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
757
1.78k
        fxPushSymbol(parser, parser->states[0].symbol);
758
1.78k
        fxGetNextToken(parser);
759
1.78k
      }
760
1
      else {
761
1
        fxPushNULL(parser);
762
1
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
763
1
      }
764
1.78k
    }
765
668
    else {
766
668
      fxPushNULL(parser);
767
668
    }
768
2.45k
    if (fxIsKeyword(parser, parser->fromSymbol)) {
769
49
      fxGetNextToken(parser);
770
49
      if (parser->states[0].token == XS_TOKEN_STRING) {
771
48
        fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
772
48
        fxPushNodeList(parser, 1);
773
48
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
774
48
        fxGetNextToken(parser);
775
48
        if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
776
0
          fxGetNextToken(parser);
777
0
          fxWithAttributes(parser);
778
0
        }
779
48
        else
780
48
          fxPushNULL(parser);
781
48
        fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
782
48
        fxSemicolon(parser);
783
48
      }
784
1
      else
785
1
        fxReportParserError(parser, parser->states[0].line, "missing module");
786
49
    }
787
2.40k
    else
788
2.40k
      fxReportParserError(parser, parser->states[0].line, "missing from");
789
2.45k
    break;
790
221
  case XS_TOKEN_DEFAULT:
791
221
    fxMatchToken(parser, XS_TOKEN_DEFAULT);
792
221
    if (parser->flags & mxDefaultFlag)
793
1
      fxReportParserError(parser, parser->states[0].line, "invalid default");
794
221
    parser->flags |= mxDefaultFlag;
795
221
    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
221
    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
221
    else {
826
221
      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
221
      fxAssignmentExpression(parser);
835
221
      fxSemicolon(parser);
836
221
      fxPushSymbol(parser, parser->defaultSymbol);
837
221
      fxPushNULL(parser);
838
221
      fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, line);
839
221
      fxSwapNodes(parser);
840
221
      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, line);
841
221
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
842
221
    }
843
221
    if (symbol) {
844
0
      fxPushSymbol(parser, symbol);
845
0
      fxPushSymbol(parser, parser->defaultSymbol);
846
0
    }
847
221
    else {
848
221
      fxPushSymbol(parser, parser->defaultSymbol);
849
221
      fxPushNULL(parser);
850
221
    }
851
221
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
852
221
    fxPushNodeList(parser, 1);
853
221
    fxPushNULL(parser);
854
221
    fxPushNULL(parser);
855
221
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
856
221
    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
109
  case XS_TOKEN_CONST:
901
217
  case XS_TOKEN_LET:
902
286
  case XS_TOKEN_VAR:
903
286
    aToken = parser->states[0].token;
904
286
    fxVariableStatement(parser, aToken, 0);
905
286
    count = parser->nodeCount;
906
286
    fxExportBinding(parser, parser->root);
907
286
    fxPushNodeList(parser, parser->nodeCount - count);
908
286
    fxPushNULL(parser);
909
286
    fxPushNULL(parser);
910
286
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
911
286
    fxSemicolon(parser);
912
286
    break;
913
8.35k
  case XS_TOKEN_LEFT_BRACE:
914
8.35k
    count = parser->nodeCount;
915
8.35k
    fxSpecifiers(parser);
916
8.35k
    fxPushNodeList(parser, parser->nodeCount - count);
917
8.35k
    if (fxIsKeyword(parser, parser->fromSymbol)) {
918
56
      fxGetNextToken(parser);
919
56
      if (parser->states[0].token == XS_TOKEN_STRING) {
920
55
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
921
55
        fxGetNextToken(parser);
922
55
      }
923
1
      else {
924
1
        fxPushNULL(parser);
925
1
        fxReportParserError(parser, parser->states[0].line, "missing module");
926
1
      }
927
56
      if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
928
0
        fxGetNextToken(parser);
929
0
        fxWithAttributes(parser);
930
0
      }
931
56
      else
932
56
        fxPushNULL(parser);
933
56
    }
934
8.29k
    else {
935
8.29k
      fxPushNULL(parser);
936
8.29k
      fxPushNULL(parser);
937
8.29k
    }
938
8.35k
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
939
8.35k
    fxSemicolon(parser);
940
8.35k
    break;
941
294
  default:
942
294
    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
294
    fxReportParserError(parser, parser->states[0].line, "invalid export %s", gxTokenNames[parser->states[0].token]);
951
294
    fxGetNextToken(parser);
952
294
    break;
953
11.6k
  }
954
11.6k
}
955
956
void fxExportBinding(txParser* parser, txNode* node)
957
537
{
958
537
  txToken token = node->description->token;
959
537
  if ((token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_VAR)) {
960
304
    fxPushSymbol(parser, ((txDeclareNode*)node)->symbol);
961
304
    fxPushNULL(parser);
962
304
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, node->line);
963
304
  }
964
233
  else if (token == XS_TOKEN_BINDING) {
965
210
    fxExportBinding(parser, ((txBindingNode*)node)->target);
966
210
  }
967
23
  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
23
  else if (token == XS_TOKEN_OBJECT_BINDING) {
975
3
    node = ((txObjectBindingNode*)node)->items->first;
976
5
    while (node) {
977
2
      fxExportBinding(parser, node);
978
2
      node = node->next;
979
2
    }
980
3
  }
981
20
  else if (token == XS_TOKEN_PROPERTY_BINDING)
982
1
    fxExportBinding(parser, ((txPropertyBindingNode*)node)->binding);
983
19
  else if (token == XS_TOKEN_PROPERTY_BINDING_AT)
984
1
    fxExportBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
985
18
  else if (token == XS_TOKEN_REST_BINDING)
986
0
    fxExportBinding(parser, ((txRestBindingNode*)node)->binding);
987
18
  else if (token == XS_TOKEN_STATEMENTS) {
988
18
    node = ((txStatementsNode*)node)->items->first;
989
56
    while (node) {
990
38
      fxExportBinding(parser, node);
991
38
      node = node->next;
992
38
    }
993
18
  }
994
537
}
995
996
997
void fxImportDeclaration(txParser* parser)
998
272
{
999
272
  txBoolean asFlag = 1;
1000
272
  txBoolean fromFlag = 0;
1001
272
  txInteger count = parser->nodeCount;
1002
272
  fxMatchToken(parser, XS_TOKEN_IMPORT);
1003
272
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1004
121
    fxPushSymbol(parser, parser->defaultSymbol);
1005
121
    fxPushSymbol(parser, parser->states[0].symbol);
1006
121
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1007
121
    fxGetNextToken(parser);
1008
121
    if (parser->states[0].token == XS_TOKEN_COMMA)
1009
2
      fxGetNextToken(parser);
1010
119
    else
1011
119
      asFlag = 0;
1012
121
    fromFlag = 1;
1013
121
  }
1014
272
  if (asFlag) {
1015
153
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1016
58
      fxGetNextToken(parser);
1017
58
      if (fxIsKeyword(parser, parser->asSymbol)) {
1018
57
        fxGetNextToken(parser);
1019
57
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1020
56
          fxPushNULL(parser);
1021
56
          fxPushSymbol(parser, parser->states[0].symbol);
1022
56
          fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1023
56
          fxGetNextToken(parser);
1024
56
        }
1025
1
        else {
1026
1
          fxReportParserError(parser, parser->states[0].line, "missing identifier");
1027
1
        }
1028
57
      }
1029
1
      else {
1030
1
        fxReportParserError(parser, parser->states[0].line, "missing as");
1031
1
      }
1032
58
      fromFlag = 1;
1033
58
    }
1034
95
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
1035
49
      fxSpecifiers(parser);
1036
49
      fromFlag = 1;
1037
49
    }
1038
153
  }
1039
272
  fxPushNodeList(parser, parser->nodeCount - count);
1040
272
  if (fromFlag) {
1041
224
    if (fxIsKeyword(parser, parser->fromSymbol)) {
1042
219
      fxGetNextToken(parser);
1043
219
      if (parser->states[0].token == XS_TOKEN_STRING) {
1044
217
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1045
217
        fxGetNextToken(parser);
1046
217
      }
1047
2
      else {
1048
2
        fxPushNULL(parser);
1049
2
        fxReportParserError(parser, parser->states[0].line, "missing module");
1050
2
      }
1051
219
    }
1052
5
    else {
1053
5
      fxPushNULL(parser);
1054
5
      fxReportParserError(parser, parser->states[0].line, "missing from");
1055
5
    }
1056
224
  }
1057
48
  else if (parser->states[0].token == XS_TOKEN_STRING) {
1058
41
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1059
41
    fxGetNextToken(parser);
1060
41
  }
1061
7
  else {
1062
7
    fxPushNULL(parser);
1063
7
    fxReportParserError(parser, parser->states[0].line, "missing module");
1064
7
  }
1065
272
  if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
1066
0
    fxGetNextToken(parser);
1067
0
    fxWithAttributes(parser);
1068
0
  }
1069
272
  else
1070
272
    fxPushNULL(parser);
1071
272
  fxPushNodeStruct(parser, 3, XS_TOKEN_IMPORT, parser->states[0].line);
1072
272
  fxSemicolon(parser);
1073
272
}
1074
1075
void fxSpecifiers(txParser* parser)
1076
8.40k
{
1077
//  txInteger aCount = 0;
1078
8.40k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1079
12.1k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1080
8.39k
    fxPushSymbol(parser, parser->states[0].symbol);
1081
8.39k
    fxGetNextToken(parser);
1082
8.39k
    if (fxIsKeyword(parser, parser->asSymbol)) {
1083
2.59k
      fxGetNextToken(parser);
1084
2.59k
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1085
1.78k
        fxPushSymbol(parser, parser->states[0].symbol);
1086
1.78k
        fxGetNextToken(parser);
1087
1.78k
      }
1088
812
      else {
1089
812
        fxPushNULL(parser);
1090
812
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
1091
812
      }
1092
2.59k
    }
1093
5.79k
    else
1094
5.79k
      fxPushNULL(parser);
1095
8.39k
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1096
//    aCount++;
1097
8.39k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
1098
4.68k
      break;
1099
3.70k
    fxGetNextToken(parser);
1100
3.70k
  }
1101
8.40k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1102
8.40k
}
1103
1104
void fxWithAttributes(txParser* parser)
1105
0
{
1106
0
  txBoolean flag = 0;
1107
0
  txString string;
1108
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1109
0
  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
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1143
0
  if (flag)
1144
0
    fxPushSymbol(parser, parser->jsonSymbol);
1145
0
  else
1146
0
    fxPushNULL(parser);
1147
0
}
1148
1149
void fxProgram(txParser* parser)
1150
945k
{
1151
945k
  txInteger count = parser->nodeCount;
1152
945k
  txInteger line = parser->states[0].line;
1153
945k
  txNode* node;
1154
1.36M
  while (parser->states[0].token != XS_TOKEN_EOF) {
1155
972k
    fxStatement(parser, -1);
1156
972k
    node = parser->root;
1157
972k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1158
81.9k
      break;
1159
890k
    node = ((txStatementNode*)node)->expression;
1160
890k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1161
473k
      break;
1162
416k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1163
26.3k
      if (!(parser->flags & mxStrictFlag)) {
1164
25.6k
        parser->flags |= mxStrictFlag;
1165
25.6k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1166
24.0k
          fxCheckStrictKeyword(parser);
1167
25.6k
      }
1168
26.3k
    }
1169
416k
  }
1170
1.71M
  while (parser->states[0].token != XS_TOKEN_EOF) {
1171
765k
    fxStatement(parser, -1);
1172
765k
  }
1173
945k
  count = parser->nodeCount - count;
1174
945k
  if (count > 1) {
1175
71.0k
    fxPushNodeList(parser, count);
1176
71.0k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1177
71.0k
  }
1178
874k
  else if (count == 0) {
1179
4.22k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1180
4.22k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1181
4.22k
  }
1182
945k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PROGRAM, line);
1183
945k
  if (parser->flags & mxFieldFlag)
1184
0
    if (parser->flags & mxArgumentsFlag)
1185
0
      fxReportParserError(parser, parser->states[0].line, "invalid arguments");
1186
945k
  parser->root->flags = parser->flags & mxStrictFlag;
1187
945k
}
1188
1189
void fxBody(txParser* parser)
1190
407k
{
1191
407k
  txInteger count = parser->nodeCount;
1192
407k
  txInteger line = parser->states[0].line;
1193
407k
  txNode* node;
1194
407k
    fxCheckParserStack(parser, line);
1195
535k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1196
353k
    fxStatement(parser, 1);
1197
353k
    node = parser->root;
1198
353k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1199
65.4k
      break;
1200
287k
    node = ((txStatementNode*)node)->expression;
1201
287k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1202
160k
      break;
1203
127k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1204
8.40k
      if (parser->flags & mxNotSimpleParametersFlag)
1205
1
        fxReportParserError(parser, parser->states[0].line, "invalid directive");
1206
8.40k
      if (!(parser->flags & mxStrictFlag)) {
1207
8.17k
        parser->flags |= mxStrictFlag;
1208
8.17k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1209
3.56k
          fxCheckStrictKeyword(parser);
1210
8.17k
      }
1211
8.40k
    }
1212
127k
  }
1213
807k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1214
399k
    fxStatement(parser, 1);
1215
399k
  }
1216
407k
  count = parser->nodeCount - count;
1217
407k
  if (count > 1) {
1218
35.6k
    fxPushNodeList(parser, count);
1219
35.6k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1220
35.6k
  }
1221
372k
  else if (count == 0) {
1222
64.7k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1223
64.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1224
64.7k
  }
1225
407k
}
1226
1227
void fxBlock(txParser* parser)
1228
87.2k
{
1229
87.2k
  txInteger aLine = parser->states[0].line;
1230
87.2k
  fxCheckParserStack(parser, aLine);
1231
87.2k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1232
87.2k
  fxStatements(parser);
1233
87.2k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1234
87.2k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BLOCK, aLine);
1235
87.2k
}
1236
1237
void fxStatements(txParser* parser)
1238
121k
{
1239
121k
  txInteger count = parser->nodeCount;
1240
121k
  txInteger line = parser->states[0].line;
1241
251k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1242
130k
    fxStatement(parser, 1);
1243
130k
  }
1244
121k
  count = parser->nodeCount - count;
1245
121k
  fxPushNodeList(parser, count);
1246
121k
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1247
121k
}
1248
1249
void fxStatement(txParser* parser, txInteger blockIt)
1250
2.78M
{
1251
2.78M
  txInteger line = parser->states[0].line;
1252
2.78M
  txSymbol* symbol = C_NULL;
1253
2.78M
  txUnsigned flag = 0;
1254
2.78M
  switch (parser->states[0].token) {
1255
//  case XS_TOKEN_COMMA:
1256
82.3k
  case XS_TOKEN_SEMICOLON:
1257
82.3k
    fxGetNextToken(parser);
1258
82.3k
    if (!blockIt) {
1259
2.54k
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1260
2.54k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1261
2.54k
    }
1262
82.3k
    break;
1263
10.1k
  case XS_TOKEN_BREAK:
1264
10.1k
    fxBreakStatement(parser);
1265
10.1k
    fxSemicolon(parser);
1266
10.1k
    break;
1267
56.4k
  case XS_TOKEN_CLASS:
1268
56.4k
    if (!blockIt)
1269
44
      fxReportParserError(parser, parser->states[0].line, "no block");
1270
56.4k
    fxClassExpression(parser, line, &symbol);
1271
56.4k
    if (symbol) {
1272
6.71k
      fxPushSymbol(parser, symbol);
1273
6.71k
      fxPushNodeStruct(parser, 1, XS_TOKEN_LET, line);
1274
6.71k
      fxSwapNodes(parser);
1275
6.71k
      fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, line);
1276
6.71k
    }
1277
49.6k
    else
1278
49.6k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1279
56.4k
    break;
1280
27.5k
  case XS_TOKEN_CONST:
1281
27.5k
    if (!blockIt)
1282
1
      fxReportParserError(parser, parser->states[0].line, "no block");
1283
27.5k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1284
27.5k
    fxSemicolon(parser);
1285
27.5k
    break;
1286
12.1k
  case XS_TOKEN_CONTINUE:
1287
12.1k
    fxContinueStatement(parser);
1288
12.1k
    fxSemicolon(parser);
1289
12.1k
    break;
1290
2.39k
  case XS_TOKEN_DEBUGGER:
1291
2.39k
    fxDebuggerStatement(parser);
1292
2.39k
    fxSemicolon(parser);
1293
2.39k
    break;
1294
31.9k
  case XS_TOKEN_DO:
1295
31.9k
    fxDoStatement(parser);
1296
31.9k
    break;
1297
86.9k
  case XS_TOKEN_FOR:
1298
86.9k
    fxForStatement(parser);
1299
86.9k
    break;
1300
6.01k
  case XS_TOKEN_FUNCTION:
1301
    //if ((parser->flags & mxStrictFlag) && !blockIt) BROWSER
1302
7.12k
  again:
1303
7.12k
    if (!blockIt)
1304
382
      fxReportParserError(parser, parser->states[0].line, "no block (strict code)");
1305
7.12k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
1306
7.12k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1307
774
      fxGetNextToken(parser);
1308
774
      fxGeneratorExpression(parser, line, &symbol, flag);
1309
774
    }
1310
6.35k
    else
1311
6.35k
      fxFunctionExpression(parser, line, &symbol, flag);
1312
7.12k
    if (symbol) {
1313
3.73k
      txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
1314
3.73k
      node->initializer = fxPopNode(parser);
1315
3.73k
      fxPushNode(parser, (txNode*)node);
1316
3.73k
    }
1317
3.39k
    else
1318
3.39k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1319
7.12k
    break;
1320
11.9k
  case XS_TOKEN_IF:
1321
11.9k
    fxIfStatement(parser);
1322
11.9k
    break;
1323
14.7k
  case XS_TOKEN_RETURN:
1324
14.7k
    if (!(parser->flags & (mxArrowFlag | mxFunctionFlag | mxGeneratorFlag)))
1325
499
      fxReportParserError(parser, parser->states[0].line, "invalid return");
1326
14.7k
    fxReturnStatement(parser);
1327
14.7k
    fxSemicolon(parser);
1328
14.7k
    break;
1329
79.4k
  case XS_TOKEN_LEFT_BRACE:
1330
79.4k
    fxBlock(parser);
1331
79.4k
    break;
1332
15.5k
  case XS_TOKEN_LET:
1333
15.5k
    if (!blockIt)
1334
3
      fxReportParserError(parser, parser->states[0].line, "no block");
1335
15.5k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1336
15.5k
    fxSemicolon(parser);
1337
15.5k
    break;
1338
11.9k
  case XS_TOKEN_SWITCH:
1339
11.9k
    fxSwitchStatement(parser);
1340
11.9k
    break;
1341
28.2k
  case XS_TOKEN_THROW:
1342
28.2k
    fxThrowStatement(parser);
1343
28.2k
    fxSemicolon(parser);
1344
28.2k
    break;
1345
8.54k
  case XS_TOKEN_TRY:
1346
8.54k
    fxTryStatement(parser);
1347
8.54k
    break;
1348
121k
  case XS_TOKEN_VAR:
1349
121k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1350
121k
    fxSemicolon(parser);
1351
121k
    break;
1352
4.13k
  case XS_TOKEN_WHILE:
1353
4.13k
    fxWhileStatement(parser);
1354
4.13k
    break;
1355
8.88k
  case XS_TOKEN_WITH:
1356
8.88k
    if (parser->flags & mxStrictFlag)
1357
1.20k
      fxReportParserError(parser, parser->states[0].line, "with (strict code)");
1358
8.88k
    fxWithStatement(parser);
1359
8.88k
    break;
1360
0
#if mxExplicitResourceManagement
1361
90
  case XS_TOKEN_AWAIT:
1362
90
    fxLookAheadOnce(parser);
1363
90
    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
90
    fxCommaExpression(parser);
1377
90
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1378
90
    fxSemicolon(parser);
1379
90
    break;
1380
0
#endif
1381
1.30M
  case XS_TOKEN_IDENTIFIER:
1382
1.30M
    fxLookAheadOnce(parser);
1383
1.30M
    if (parser->states[1].token == XS_TOKEN_COLON) {
1384
42.0k
      fxPushSymbol(parser, parser->states[0].symbol);
1385
42.0k
      fxGetNextToken(parser);
1386
42.0k
      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
42.0k
      if (parser->states[0].token == XS_TOKEN_FUNCTION)
1390
2.74k
        fxReportParserError(parser, parser->states[0].line, "labeled function");
1391
42.0k
      fxCheckParserStack(parser, line);
1392
42.0k
      fxStatement(parser, 0);
1393
42.0k
      fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, line);
1394
42.0k
      break;
1395
42.0k
    }
1396
1.25M
    if ((parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped) 
1397
1.39k
        && (!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_FUNCTION)) {
1398
1.11k
      fxGetNextToken(parser);
1399
1.11k
      flag = mxAsyncFlag;
1400
1.11k
      goto again;
1401
1.11k
    }
1402
1.25M
    if ((parser->states[0].symbol == parser->letSymbol) && (!parser->states[0].escaped) 
1403
47.7k
        && ((gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING) || (parser->states[1].token == XS_TOKEN_AWAIT) || (parser->states[1].token == XS_TOKEN_YIELD))
1404
44.2k
        && (blockIt || (!parser->states[1].crlf) || (parser->states[1].token == XS_TOKEN_LEFT_BRACKET))) {
1405
44.2k
      parser->states[0].token = XS_TOKEN_LET;
1406
44.2k
      if (!blockIt)
1407
9
        fxReportParserError(parser, parser->states[0].line, "no block");
1408
44.2k
      fxVariableStatement(parser, XS_TOKEN_LET, 0);
1409
44.2k
      fxSemicolon(parser);
1410
44.2k
      break;
1411
44.2k
    }
1412
1.21M
#if mxExplicitResourceManagement
1413
1.21M
    if ((parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1414
2.52k
        && (!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
1.66k
      parser->states[0].token = XS_TOKEN_USING;
1416
1.66k
      if (blockIt <= 0)
1417
893
        fxReportParserError(parser, parser->states[0].line, "no block");
1418
1.66k
      fxVariableStatement(parser, XS_TOKEN_USING, 0);
1419
1.66k
      fxSemicolon(parser);
1420
1.66k
      break;
1421
1.66k
    }
1422
1.21M
#endif
1423
    /* continue */
1424
2.07M
  default:
1425
2.07M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1426
1.95M
      fxCommaExpression(parser);
1427
1.95M
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1428
1.95M
      fxSemicolon(parser);
1429
1.95M
    }
1430
123k
    else {
1431
123k
      fxReportParserError(parser, parser->states[0].line, "invalid token %s", gxTokenNames[parser->states[0].token]);
1432
123k
      fxPushNULL(parser);
1433
123k
      fxGetNextToken(parser);
1434
123k
    }
1435
2.07M
    break;
1436
2.78M
  }
1437
2.78M
}
1438
1439
void fxSemicolon(txParser* parser)
1440
1.71M
{
1441
1.71M
  if ((parser->states[0].crlf) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_END_STATEMENT)) {
1442
1.63M
    if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1443
503k
      fxGetNextToken(parser);
1444
1.63M
  }
1445
76.1k
  else
1446
76.1k
    fxReportParserError(parser, parser->states[0].line, "missing ;");
1447
1.71M
}
1448
1449
void fxBreakStatement(txParser* parser)
1450
10.1k
{
1451
10.1k
  txInteger aLine = parser->states[0].line;
1452
10.1k
  fxMatchToken(parser, XS_TOKEN_BREAK);
1453
10.1k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1454
483
    fxPushSymbol(parser, parser->states[0].symbol);
1455
483
    fxGetNextToken(parser);
1456
483
  }
1457
9.69k
  else {
1458
9.69k
    fxPushNULL(parser);
1459
9.69k
  }
1460
10.1k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BREAK, aLine);
1461
10.1k
}
1462
1463
void fxContinueStatement(txParser* parser)
1464
12.1k
{
1465
12.1k
  txInteger aLine = parser->states[0].line;
1466
12.1k
  fxMatchToken(parser, XS_TOKEN_CONTINUE);
1467
12.1k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1468
2.24k
    fxPushSymbol(parser, parser->states[0].symbol);
1469
2.24k
    fxGetNextToken(parser);
1470
2.24k
  }
1471
9.93k
  else {
1472
9.93k
    fxPushNULL(parser);
1473
9.93k
  }
1474
12.1k
  fxPushNodeStruct(parser, 1, XS_TOKEN_CONTINUE, aLine);
1475
12.1k
}
1476
1477
void fxDebuggerStatement(txParser* parser)
1478
2.39k
{
1479
2.39k
  txInteger aLine = parser->states[0].line;
1480
2.39k
  fxMatchToken(parser, XS_TOKEN_DEBUGGER);
1481
2.39k
  fxPushNodeStruct(parser, 0, XS_TOKEN_DEBUGGER, aLine);
1482
2.39k
}
1483
1484
void fxDoStatement(txParser* parser)
1485
31.9k
{
1486
31.9k
  txInteger aLine = parser->states[0].line;
1487
31.9k
  fxCheckParserStack(parser, aLine);
1488
31.9k
  fxPushNULL(parser);
1489
31.9k
  fxMatchToken(parser, XS_TOKEN_DO);
1490
31.9k
  fxStatement(parser, 0);
1491
31.9k
  fxMatchToken(parser, XS_TOKEN_WHILE);
1492
31.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1493
31.9k
  fxCommaExpression(parser);
1494
31.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1495
31.9k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1496
159
    fxGetNextToken(parser);
1497
31.9k
  fxPushNodeStruct(parser, 2, XS_TOKEN_DO, aLine);
1498
31.9k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1499
31.9k
}
1500
1501
void fxForStatement(txParser* parser)
1502
86.9k
{
1503
86.9k
  txInteger aLine = parser->states[0].line;
1504
86.9k
  txBoolean awaitFlag = 0;
1505
86.9k
  txBoolean expressionFlag = 0;
1506
86.9k
  txToken aToken;
1507
86.9k
  fxPushNULL(parser);
1508
86.9k
  fxMatchToken(parser, XS_TOKEN_FOR);
1509
86.9k
  if (parser->states[0].token == XS_TOKEN_AWAIT) {
1510
189
    awaitFlag = 1;
1511
189
    fxMatchToken(parser, XS_TOKEN_AWAIT);
1512
189
  }
1513
86.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1514
86.9k
  fxLookAheadOnce(parser);
1515
86.9k
  parser->flags |= mxForFlag;
1516
86.9k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON) {
1517
188
    fxPushNULL(parser);
1518
188
  }
1519
86.7k
  else if (parser->states[0].token == XS_TOKEN_CONST) {
1520
1.21k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1521
1.21k
  }
1522
85.5k
  else if (parser->states[0].token == XS_TOKEN_LET) {
1523
11
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1524
11
  }
1525
85.5k
  else if (fxIsKeyword(parser, parser->letSymbol) && (gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING)) {
1526
1.77k
    parser->states[0].token = XS_TOKEN_LET;
1527
1.77k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1528
1.77k
  }
1529
83.7k
#if mxExplicitResourceManagement
1530
83.7k
  else if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1531
14
        && (!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
83.7k
  else if ((parser->states[0].token == XS_TOKEN_AWAIT)
1536
1.78k
        && (!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
83.7k
#endif
1550
83.7k
  else if (parser->states[0].token == XS_TOKEN_VAR) {
1551
29.8k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1552
29.8k
  }
1553
53.9k
  else {
1554
53.9k
    fxCommaExpression(parser);
1555
53.9k
    expressionFlag = 1;
1556
53.9k
  }
1557
86.9k
  parser->flags &= ~mxForFlag;
1558
86.9k
  if (awaitFlag && !fxIsKeyword(parser, parser->ofSymbol))
1559
1
    fxReportParserError(parser, parser->states[0].line, "invalid for await");
1560
86.9k
  if (fxIsToken(parser, XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)) {
1561
22.0k
    if (expressionFlag) {
1562
1.30k
      if (!fxCheckReference(parser, XS_TOKEN_ASSIGN)) {
1563
36
        fxReportParserError(parser, parser->states[0].line, "no reference");
1564
36
      }
1565
1.30k
    }
1566
20.7k
    else {
1567
20.7k
      aToken = parser->root->description->token;
1568
20.7k
      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
20.7k
      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
20.7k
    }
1586
22.0k
    aToken = parser->states[0].token;
1587
22.0k
    fxGetNextToken(parser);
1588
22.0k
    if (aToken == XS_TOKEN_IN)
1589
21.2k
      fxCommaExpression(parser);
1590
814
    else
1591
814
      fxAssignmentExpression(parser);
1592
22.0k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1593
22.0k
    fxStatement(parser, 0);
1594
22.0k
    if (awaitFlag)
1595
10
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_AWAIT_OF, aLine);
1596
22.0k
    else if (aToken == XS_TOKEN_IN)
1597
21.0k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_IN, aLine);
1598
933
    else
1599
933
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_OF, aLine);
1600
22.0k
  }
1601
64.9k
  else {
1602
64.9k
    if (expressionFlag)
1603
45.1k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1604
64.9k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1605
64.9k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1606
44.4k
      fxCommaExpression(parser);
1607
44.4k
    }
1608
20.4k
    else {
1609
20.4k
      fxPushNULL(parser);
1610
20.4k
    }
1611
64.9k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1612
64.9k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1613
43.2k
      fxCommaExpression(parser);
1614
43.2k
    }
1615
21.7k
    else {
1616
21.7k
      fxPushNULL(parser);
1617
21.7k
    }
1618
64.9k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1619
64.9k
    fxCheckParserStack(parser, aLine);
1620
64.9k
    fxStatement(parser, 0);
1621
64.9k
    fxPushNodeStruct(parser, 4, XS_TOKEN_FOR, aLine);
1622
64.9k
  }
1623
86.9k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1624
86.9k
}
1625
1626
void fxIfStatement(txParser* parser)
1627
11.9k
{
1628
11.9k
  txInteger aLine = parser->states[0].line;
1629
11.9k
  fxMatchToken(parser, XS_TOKEN_IF);
1630
11.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1631
11.9k
  fxCommaExpression(parser);
1632
11.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1633
11.9k
  fxStatement(parser, 0);
1634
11.9k
  if (parser->states[0].token == XS_TOKEN_ELSE) {
1635
923
    fxMatchToken(parser, XS_TOKEN_ELSE);
1636
923
    fxStatement(parser, 0);
1637
923
  }
1638
11.0k
  else {
1639
11.0k
    fxPushNULL(parser);
1640
11.0k
  }
1641
11.9k
  fxPushNodeStruct(parser, 3, XS_TOKEN_IF, aLine);
1642
11.9k
}
1643
1644
void fxReturnStatement(txParser* parser)
1645
14.2k
{
1646
14.2k
  txInteger aLine = parser->states[0].line;
1647
14.2k
  fxMatchToken(parser, XS_TOKEN_RETURN);
1648
14.2k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1649
9.42k
    fxCommaExpression(parser);
1650
9.42k
  }
1651
4.82k
  else {
1652
4.82k
    fxPushNULL(parser);
1653
4.82k
  }
1654
14.2k
  fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
1655
14.2k
}
1656
1657
void fxSwitchStatement(txParser* parser)
1658
11.9k
{
1659
11.9k
  txInteger aCount = 0;
1660
11.9k
  txBoolean aDefaultFlag = 0;
1661
11.9k
  txInteger aLine = parser->states[0].line;
1662
11.9k
  fxMatchToken(parser, XS_TOKEN_SWITCH);
1663
11.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1664
11.9k
  fxCommaExpression(parser);
1665
11.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1666
11.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1667
21.5k
  while ((parser->states[0].token == XS_TOKEN_CASE) || (parser->states[0].token == XS_TOKEN_DEFAULT)) {
1668
9.60k
    txInteger aCaseCount;
1669
9.60k
    txInteger aCaseLine = parser->states[0].line;
1670
9.60k
    if (parser->states[0].token == XS_TOKEN_CASE) {
1671
9.48k
      fxMatchToken(parser, XS_TOKEN_CASE);
1672
9.48k
      fxCommaExpression(parser);
1673
9.48k
      fxMatchToken(parser, XS_TOKEN_COLON);
1674
9.48k
      aCaseCount = parser->nodeCount;
1675
19.1k
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1676
9.66k
        fxStatement(parser, 1);
1677
9.48k
      aCaseCount = parser->nodeCount - aCaseCount;
1678
9.48k
      if (aCaseCount > 1) {
1679
1.56k
        fxPushNodeList(parser, aCaseCount);
1680
1.56k
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aCaseLine);
1681
1.56k
      }
1682
7.92k
      else if (aCaseCount == 0) {
1683
2.29k
        fxPushNULL(parser);
1684
2.29k
      }
1685
9.48k
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1686
9.48k
    }
1687
115
    else {
1688
115
      fxMatchToken(parser, XS_TOKEN_DEFAULT);
1689
115
      if (aDefaultFlag) 
1690
1
        fxReportParserError(parser, parser->states[0].line, "invalid default");
1691
115
      fxPushNULL(parser);
1692
115
      fxMatchToken(parser, XS_TOKEN_COLON);
1693
115
      aCaseCount = parser->nodeCount;
1694
345
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1695
230
        fxStatement(parser, 1);
1696
115
      aCaseCount = parser->nodeCount - aCaseCount;
1697
115
      if (aCaseCount > 1) {
1698
9
        fxPushNodeList(parser, aCaseCount);
1699
9
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1700
9
      }
1701
106
      else if (aCaseCount == 0) {
1702
1
        fxPushNULL(parser);
1703
1
      }
1704
115
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1705
115
      aDefaultFlag = 1;
1706
115
    }
1707
9.60k
    aCount++;
1708
9.60k
  }
1709
11.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1710
11.9k
  fxPushNodeList(parser, aCount);
1711
11.9k
  fxPushNodeStruct(parser, 2, XS_TOKEN_SWITCH, aLine);
1712
11.9k
}
1713
1714
void fxThrowStatement(txParser* parser)
1715
28.2k
{
1716
28.2k
  txInteger aLine = parser->states[0].line;
1717
28.2k
  fxMatchToken(parser, XS_TOKEN_THROW);
1718
28.2k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1719
23.8k
    fxCommaExpression(parser);
1720
23.8k
  }
1721
4.40k
  else {
1722
4.40k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1723
4.40k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
1724
4.40k
  }
1725
28.2k
  fxPushNodeStruct(parser, 1, XS_TOKEN_THROW, aLine);
1726
28.2k
}
1727
1728
void fxTryStatement(txParser* parser)
1729
8.54k
{
1730
8.54k
  txInteger aLine = parser->states[0].line;
1731
8.54k
  txBoolean ok = 0;
1732
8.54k
  fxMatchToken(parser, XS_TOKEN_TRY);
1733
8.54k
  fxBlock(parser);
1734
8.54k
  if (parser->states[0].token == XS_TOKEN_CATCH) {
1735
5.03k
    txInteger aCatchLine = parser->states[0].line;
1736
5.03k
    fxMatchToken(parser, XS_TOKEN_CATCH);
1737
5.03k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
1738
4.88k
      fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1739
4.88k
      fxBinding(parser, XS_TOKEN_LET, 1);
1740
4.88k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1741
4.88k
    }
1742
153
    else
1743
153
      fxPushNULL(parser);
1744
5.03k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1745
5.03k
    fxStatements(parser);
1746
5.03k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1747
5.03k
    fxPushNodeStruct(parser, 2, XS_TOKEN_CATCH, aCatchLine);
1748
5.03k
    ok = 1;
1749
5.03k
  }
1750
3.51k
  else {
1751
3.51k
    fxPushNULL(parser);
1752
3.51k
  }
1753
8.54k
  if (parser->states[0].token == XS_TOKEN_FINALLY) {
1754
52
    fxMatchToken(parser, XS_TOKEN_FINALLY);
1755
52
    fxBlock(parser);
1756
52
    ok = 1;
1757
52
  }
1758
8.49k
  else {
1759
8.49k
    fxPushNULL(parser);
1760
8.49k
  }
1761
8.54k
  if (!ok)
1762
1.60k
    fxReportParserError(parser, parser->states[0].line, "missing catch or finally");
1763
8.54k
  fxPushNodeStruct(parser, 3, XS_TOKEN_TRY, aLine);
1764
8.54k
}
1765
1766
void fxVariableStatement(txParser* parser, txToken theToken, txUnsigned flags)
1767
242k
{
1768
242k
  txBoolean commaFlag = 0;
1769
242k
  txInteger aCount = 0;
1770
242k
  txInteger aLine = parser->states[0].line;
1771
242k
  fxMatchToken(parser, theToken);
1772
258k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
1773
244k
    commaFlag = 0;
1774
244k
    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
244k
    aCount++;
1783
244k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
1784
16.5k
      parser->flags &= ~mxForFlag;
1785
16.5k
      fxGetNextToken(parser);
1786
16.5k
      commaFlag = 1;
1787
16.5k
    }
1788
228k
    else
1789
228k
      break;
1790
244k
  }
1791
242k
    if ((aCount == 0) || commaFlag) {
1792
7.30k
    fxPushNULL(parser);
1793
7.30k
    fxPushNULL(parser);
1794
7.30k
    fxPushNodeStruct(parser, 2, theToken, aLine);
1795
7.30k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
1796
7.30k
  }
1797
242k
  if (aCount > 1) {
1798
13.2k
    fxPushNodeList(parser, aCount);
1799
13.2k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1800
13.2k
  }
1801
242k
}
1802
1803
void fxWhileStatement(txParser* parser)
1804
4.13k
{
1805
4.13k
  txInteger aLine = parser->states[0].line;
1806
4.13k
  fxPushNULL(parser);
1807
4.13k
  fxMatchToken(parser, XS_TOKEN_WHILE);
1808
4.13k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1809
4.13k
  fxCommaExpression(parser);
1810
4.13k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1811
4.13k
  fxStatement(parser, 0);
1812
4.13k
  fxPushNodeStruct(parser, 2, XS_TOKEN_WHILE, aLine);
1813
4.13k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1814
4.13k
}
1815
1816
void fxWithStatement(txParser* parser)
1817
7.68k
{
1818
7.68k
  txInteger aLine = parser->states[0].line;
1819
7.68k
  fxMatchToken(parser, XS_TOKEN_WITH);
1820
7.68k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1821
7.68k
  fxCommaExpression(parser);
1822
7.68k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1823
7.68k
  fxStatement(parser, 0);
1824
7.68k
  fxPushNodeStruct(parser, 2, XS_TOKEN_WITH, aLine);
1825
7.68k
}
1826
1827
void fxCommaExpression(txParser* parser)
1828
2.23M
{
1829
2.23M
  txInteger aCount = 0;
1830
2.23M
  txInteger aLine = parser->states[0].line;
1831
2.23M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1832
2.23M
    fxAssignmentExpression(parser);
1833
2.23M
    aCount++;
1834
2.32M
    while (parser->states[0].token == XS_TOKEN_COMMA) {
1835
83.9k
      fxGetNextToken(parser);
1836
83.9k
      fxAssignmentExpression(parser);
1837
83.9k
      aCount++;
1838
83.9k
    }
1839
2.23M
  }
1840
2.23M
  if (aCount > 1) {
1841
48.7k
    fxPushNodeList(parser, aCount);
1842
48.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
1843
48.7k
  }
1844
2.18M
  else if (aCount == 0) {
1845
1.28k
    fxPushNULL(parser);
1846
1.28k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1847
1.28k
  }
1848
2.23M
}
1849
1850
void fxAssignmentExpression(txParser* parser)
1851
4.39M
{
1852
4.39M
  if (parser->states[0].token == XS_TOKEN_YIELD)
1853
16.1k
    fxYieldExpression(parser);
1854
4.37M
  else {
1855
4.37M
    fxConditionalExpression(parser);
1856
4.71M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ASSIGN_EXPRESSION) {
1857
333k
      txToken aToken = parser->states[0].token;
1858
333k
      txInteger aLine = parser->states[0].line;
1859
333k
      if (!fxCheckReference(parser, aToken)) 
1860
11.8k
        fxReportParserError(parser, parser->states[0].line, "no reference");
1861
333k
      fxGetNextToken(parser);
1862
333k
      fxAssignmentExpression(parser);
1863
333k
      fxPushNodeStruct(parser, 2, aToken, aLine);
1864
333k
    }
1865
4.37M
  }
1866
4.39M
}
1867
1868
void fxConditionalExpression(txParser* parser)
1869
4.37M
{
1870
4.37M
  fxCoalesceExpression(parser);
1871
4.37M
  if (parser->states[0].token == XS_TOKEN_QUESTION_MARK) {
1872
26.5k
    txInteger aLine = parser->states[0].line;
1873
26.5k
    txUnsigned flags;
1874
26.5k
    fxCheckArrowFunction(parser, 1);
1875
26.5k
    fxGetNextToken(parser);
1876
26.5k
    flags = parser->flags & mxForFlag;
1877
26.5k
    parser->flags &= ~mxForFlag;
1878
26.5k
    fxAssignmentExpression(parser);
1879
26.5k
    parser->flags |= flags;
1880
26.5k
    fxMatchToken(parser, XS_TOKEN_COLON);
1881
26.5k
    fxAssignmentExpression(parser);
1882
26.5k
    fxPushNodeStruct(parser, 3, XS_TOKEN_QUESTION_MARK, aLine);
1883
26.5k
  }
1884
4.37M
}
1885
1886
void fxCoalesceExpression(txParser* parser)
1887
4.37M
{
1888
4.37M
  fxOrExpression(parser);
1889
4.38M
  while (parser->states[0].token == XS_TOKEN_COALESCE) {
1890
5.75k
    txInteger aLine = parser->states[0].line;
1891
5.75k
    fxGetNextToken(parser);
1892
5.75k
    fxOrExpression(parser);
1893
5.75k
    fxCheckArrowFunction(parser, 2);
1894
5.75k
    fxPushNodeStruct(parser, 2, XS_TOKEN_COALESCE, aLine);
1895
5.75k
  }
1896
4.37M
}
1897
1898
void fxOrExpression(txParser* parser)
1899
4.38M
{
1900
4.38M
  fxAndExpression(parser);
1901
4.42M
  while (parser->states[0].token == XS_TOKEN_OR) {
1902
41.9k
    txInteger aLine = parser->states[0].line;
1903
41.9k
    fxGetNextToken(parser);
1904
41.9k
    fxAndExpression(parser);
1905
41.9k
    fxCheckArrowFunction(parser, 2);
1906
41.9k
    fxPushNodeStruct(parser, 2, XS_TOKEN_OR, aLine);
1907
41.9k
  }
1908
4.38M
}
1909
1910
void fxAndExpression(txParser* parser)
1911
4.42M
{
1912
4.42M
  fxBitOrExpression(parser);
1913
4.47M
  while (parser->states[0].token == XS_TOKEN_AND) {
1914
52.5k
    txInteger aLine = parser->states[0].line;
1915
52.5k
    fxGetNextToken(parser);
1916
52.5k
    fxBitOrExpression(parser);
1917
52.5k
    fxCheckArrowFunction(parser, 2);
1918
52.5k
    fxPushNodeStruct(parser, 2, XS_TOKEN_AND, aLine);
1919
52.5k
  }
1920
4.42M
}
1921
1922
void fxBitOrExpression(txParser* parser)
1923
4.47M
{
1924
4.47M
  fxBitXorExpression(parser);
1925
4.52M
  while (parser->states[0].token == XS_TOKEN_BIT_OR) {
1926
47.4k
    txInteger aLine = parser->states[0].line;
1927
47.4k
    fxGetNextToken(parser);
1928
47.4k
    fxBitXorExpression(parser);
1929
47.4k
    fxCheckArrowFunction(parser, 2);
1930
47.4k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_OR, aLine);
1931
47.4k
  }
1932
4.47M
}
1933
1934
void fxBitXorExpression(txParser* parser)
1935
4.51M
{
1936
4.51M
  fxBitAndExpression(parser);
1937
4.53M
  while (parser->states[0].token == XS_TOKEN_BIT_XOR) {
1938
16.7k
    txInteger aLine = parser->states[0].line;
1939
16.7k
    fxGetNextToken(parser);
1940
16.7k
    fxBitAndExpression(parser);
1941
16.7k
    fxCheckArrowFunction(parser, 2);
1942
16.7k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_XOR, aLine);
1943
16.7k
  }
1944
4.51M
}
1945
1946
void fxBitAndExpression(txParser* parser)
1947
4.53M
{
1948
4.53M
  fxEqualExpression(parser);
1949
4.56M
  while (parser->states[0].token == XS_TOKEN_BIT_AND) {
1950
30.3k
    txInteger aLine = parser->states[0].line;
1951
30.3k
    fxGetNextToken(parser);
1952
30.3k
    fxEqualExpression(parser);
1953
30.3k
    fxCheckArrowFunction(parser, 2);
1954
30.3k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_AND, aLine);
1955
30.3k
  }
1956
4.53M
}
1957
1958
void fxEqualExpression(txParser* parser)
1959
4.56M
{
1960
4.56M
  fxRelationalExpression(parser);
1961
4.57M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EQUAL_EXPRESSION) {
1962
12.5k
    txToken aToken = parser->states[0].token;
1963
12.5k
    txInteger aLine = parser->states[0].line;
1964
12.5k
    fxGetNextToken(parser);
1965
12.5k
    fxRelationalExpression(parser);
1966
12.5k
    fxCheckArrowFunction(parser, 2);
1967
12.5k
    fxPushNodeStruct(parser, 2, aToken, aLine);
1968
12.5k
  }
1969
4.56M
}
1970
1971
void fxRelationalExpression(txParser* parser)
1972
4.57M
{
1973
4.57M
  if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
1974
5.80k
    txInteger aLine = parser->states[0].line;
1975
5.80k
    fxPushSymbol(parser, parser->states[0].symbol);
1976
5.80k
    fxGetNextToken(parser);
1977
5.80k
    fxMatchToken(parser, XS_TOKEN_IN);
1978
5.80k
    if (parser->flags & mxForFlag)
1979
1
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[XS_TOKEN_IN]);
1980
5.80k
    fxShiftExpression(parser);
1981
5.80k
    fxCheckArrowFunction(parser, 2);
1982
5.80k
    fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_IDENTIFIER, aLine);
1983
5.80k
  }
1984
4.57M
  else {
1985
4.57M
    fxShiftExpression(parser);
1986
4.57M
    if ((parser->flags & mxForFlag) && ((parser->states[0].token == XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)))
1987
1.30k
      return;
1988
4.69M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_RELATIONAL_EXPRESSION) {
1989
126k
      txToken aToken = parser->states[0].token;
1990
126k
      txInteger aLine = parser->states[0].line;
1991
126k
      fxMatchToken(parser, aToken);
1992
126k
      fxShiftExpression(parser);
1993
126k
      fxCheckArrowFunction(parser, 2);
1994
126k
      fxPushNodeStruct(parser, 2, aToken, aLine);
1995
126k
    }
1996
4.57M
  }
1997
4.57M
}
1998
1999
void fxShiftExpression(txParser* parser)
2000
4.69M
{
2001
4.69M
  fxAdditiveExpression(parser);
2002
4.72M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_SHIFT_EXPRESSION) {
2003
32.4k
    txToken aToken = parser->states[0].token;
2004
32.4k
    txInteger aLine = parser->states[0].line;
2005
32.4k
    fxGetNextToken(parser);
2006
32.4k
    fxAdditiveExpression(parser);
2007
32.4k
    fxCheckArrowFunction(parser, 2);
2008
32.4k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2009
32.4k
  }
2010
4.69M
}
2011
2012
void fxAdditiveExpression(txParser* parser)
2013
4.72M
{
2014
4.72M
  fxMultiplicativeExpression(parser);
2015
9.31M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ADDITIVE_EXPRESSION) {
2016
4.58M
    txToken aToken = parser->states[0].token;
2017
4.58M
    txInteger aLine = parser->states[0].line;
2018
4.58M
    fxGetNextToken(parser);
2019
4.58M
    fxMultiplicativeExpression(parser);
2020
4.58M
    fxCheckArrowFunction(parser, 2);
2021
4.58M
    fxPushNodeStruct(parser, 2, aToken, aLine);
2022
4.58M
  }
2023
4.72M
}
2024
2025
void fxMultiplicativeExpression(txParser* parser)
2026
9.30M
{
2027
9.30M
  fxExponentiationExpression(parser);
2028
9.49M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_MULTIPLICATIVE_EXPRESSION) {
2029
185k
    txToken aToken = parser->states[0].token;
2030
185k
    txInteger aLine = parser->states[0].line;
2031
185k
    fxGetNextToken(parser);
2032
185k
    fxExponentiationExpression(parser);
2033
185k
    fxCheckArrowFunction(parser, 2);
2034
185k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2035
185k
  }
2036
9.30M
}
2037
2038
void fxExponentiationExpression(txParser* parser)
2039
9.48M
{
2040
9.48M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION)
2041
178k
    fxUnaryExpression(parser);
2042
9.30M
  else {
2043
9.30M
    fxPrefixExpression(parser);
2044
9.30M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EXPONENTIATION_EXPRESSION) {
2045
3.46k
      txToken aToken = parser->states[0].token;
2046
3.46k
      txInteger aLine = parser->states[0].line;
2047
3.46k
      fxGetNextToken(parser);
2048
3.46k
            fxExponentiationExpression(parser);
2049
3.46k
      fxCheckArrowFunction(parser, 2);
2050
3.46k
      fxPushNodeStruct(parser, 2, aToken, aLine);
2051
3.46k
    }
2052
9.30M
  }
2053
9.48M
}
2054
2055
void fxUnaryExpression(txParser* parser)
2056
529k
{
2057
529k
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION) {
2058
353k
    txToken aToken = parser->states[0].token;
2059
353k
    txInteger aLine = parser->states[0].line;
2060
353k
    fxCheckParserStack(parser, aLine);
2061
353k
    fxMatchToken(parser, aToken);
2062
353k
    fxUnaryExpression(parser);
2063
353k
    fxCheckArrowFunction(parser, 1);
2064
353k
    if (aToken == XS_TOKEN_ADD)
2065
15.0k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PLUS, aLine);
2066
338k
    else if (aToken == XS_TOKEN_SUBTRACT)
2067
82.5k
      fxPushNodeStruct(parser, 1, XS_TOKEN_MINUS, aLine);
2068
255k
    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
16.6k
      if (!fxCheckReference(parser, aToken)) 
2073
0
        fxReportParserError(parser, parser->states[0].line, "no reference");
2074
16.6k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2075
16.6k
    }
2076
238k
    else if (aToken == XS_TOKEN_AWAIT) {
2077
1.12k
      if ((parser->flags & mxGeneratorFlag) && !(parser->flags & mxYieldFlag))
2078
3
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2079
1.12k
      else
2080
1.12k
        parser->flags |= mxAwaitingFlag;
2081
1.12k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2082
1.12k
    }
2083
237k
    else
2084
237k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2085
      
2086
353k
  }
2087
175k
  else
2088
175k
    fxPrefixExpression(parser);
2089
529k
}
2090
2091
void fxPrefixExpression(txParser* parser)
2092
9.60M
{
2093
9.60M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_PREFIX_EXPRESSION) {
2094
116k
    txToken aToken = parser->states[0].token;
2095
116k
    txInteger aLine = parser->states[0].line;
2096
116k
    fxCheckParserStack(parser, aLine);
2097
116k
    fxGetNextToken(parser);
2098
116k
    fxPrefixExpression(parser);
2099
116k
    fxCheckArrowFunction(parser, 1);
2100
116k
    if (!fxCheckReference(parser, aToken)) 
2101
1.09k
      fxReportParserError(parser, parser->states[0].line, "no reference");
2102
116k
    fxPushNodeStruct(parser, 1, aToken, aLine);
2103
116k
    parser->root->flags = mxExpressionNoValue;
2104
116k
  }
2105
9.48M
  else
2106
9.48M
    fxPostfixExpression(parser);
2107
9.60M
}
2108
2109
void fxPostfixExpression(txParser* parser)
2110
9.48M
{
2111
9.48M
  fxCallExpression(parser);
2112
9.48M
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_POSTFIX_EXPRESSION)) {
2113
53.8k
    fxCheckArrowFunction(parser, 1);
2114
53.8k
    if (!fxCheckReference(parser, parser->states[0].token)) 
2115
1.24k
      fxReportParserError(parser, parser->states[0].line, "no reference");
2116
53.8k
    fxPushNodeStruct(parser, 1, parser->states[0].token, parser->states[0].line);
2117
53.8k
    fxGetNextToken(parser);
2118
53.8k
  }
2119
9.48M
}
2120
2121
void fxCallExpression(txParser* parser)
2122
9.48M
{
2123
9.48M
  txInteger chainLine = parser->states[0].line;
2124
9.48M
  fxLiteralExpression(parser, 0);
2125
9.48M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_CALL_EXPRESSION) {
2126
606k
    txBoolean chainFlag = 0;
2127
606k
    fxCheckArrowFunction(parser, 1);
2128
1.76M
    for (;;) {
2129
1.76M
      txInteger aLine = parser->states[0].line;
2130
1.76M
      if (parser->states[0].token == XS_TOKEN_DOT) {
2131
477k
        fxGetNextToken(parser);
2132
477k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2133
462k
          fxPushSymbol(parser, parser->states[0].symbol);
2134
462k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2135
462k
          fxGetNextToken(parser);
2136
462k
        }
2137
15.3k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2138
12.7k
          if (parser->root->flags & mxSuperFlag)
2139
0
            fxReportParserError(parser, parser->states[0].line, "invalid super");
2140
12.7k
          fxPushSymbol(parser, parser->states[0].symbol);
2141
12.7k
          fxSwapNodes(parser);
2142
12.7k
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2143
12.7k
          fxGetNextToken(parser);
2144
12.7k
        }
2145
2.62k
        else
2146
2.62k
          fxReportParserError(parser, parser->states[0].line, "missing property");
2147
477k
      }
2148
      //else if (parser->states[0].crlf)
2149
      //  break;
2150
1.28M
      else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2151
37.5k
        fxGetNextToken(parser);
2152
37.5k
        fxCommaExpression(parser);
2153
37.5k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2154
37.5k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2155
37.5k
      }
2156
1.24M
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2157
367k
        txUnsigned nativeFlags = 0;
2158
367k
        txAccessNode* access = NULL;
2159
367k
        if (parser->root->description && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2160
112k
          access = (txAccessNode*)parser->root;
2161
112k
          if (access->symbol == parser->evalSymbol) {
2162
10.3k
            parser->flags |= mxEvalFlag;
2163
10.3k
          }
2164
102k
          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
112k
        }
2174
367k
        fxParameters(parser);
2175
367k
        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
367k
        else
2219
367k
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2220
367k
      }
2221
879k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
2222
380k
        if (chainFlag)
2223
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2224
380k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2225
380k
        fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2226
380k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2227
380k
        fxGetNextToken(parser);
2228
380k
        fxPushNodeList(parser, 1);
2229
380k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2230
380k
      }
2231
499k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
2232
440
        if (chainFlag)
2233
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2234
440
        fxTemplateExpression(parser);
2235
440
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2236
440
      }
2237
498k
      else if (parser->states[0].token == XS_TOKEN_CHAIN) {
2238
16.1k
        fxGetNextToken(parser);
2239
16.1k
        chainFlag = 1;
2240
16.1k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2241
11.5k
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2242
11.5k
          fxPushSymbol(parser, parser->states[0].symbol);
2243
11.5k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2244
11.5k
          fxGetNextToken(parser);
2245
11.5k
        }
2246
4.61k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2247
313
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2248
313
          fxPushSymbol(parser, parser->states[0].symbol);
2249
313
          fxSwapNodes(parser);
2250
313
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2251
313
          fxGetNextToken(parser);
2252
313
        }
2253
4.30k
        else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2254
2.26k
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2255
2.26k
          fxGetNextToken(parser);
2256
2.26k
          fxCommaExpression(parser);
2257
2.26k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2258
2.26k
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2259
2.26k
        }
2260
2.03k
        else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2261
94
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2262
94
          fxParameters(parser);
2263
94
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2264
94
        }
2265
1.94k
        else
2266
1.94k
          fxReportParserError(parser, parser->states[0].line, "invalid ?.");
2267
16.1k
      }
2268
482k
      else
2269
482k
        break;
2270
1.76M
    } 
2271
606k
    if (chainFlag)
2272
11.9k
      fxPushNodeStruct(parser, 1, XS_TOKEN_CHAIN, chainLine);
2273
606k
  } 
2274
9.48M
}
2275
2276
void fxLiteralExpression(txParser* parser, txUnsigned flag)
2277
9.54M
{
2278
9.54M
  int escaped;
2279
9.54M
  txSymbol* aSymbol;
2280
9.54M
  txInteger aLine = parser->states[0].line;
2281
9.54M
  txUnsigned flags = 0;
2282
9.54M
  char c = 0;
2283
9.54M
  fxCheckParserStack(parser, aLine);
2284
9.54M
  switch (parser->states[0].token) {
2285
23.0k
  case XS_TOKEN_NULL:
2286
31.8k
  case XS_TOKEN_TRUE:
2287
38.0k
  case XS_TOKEN_FALSE:
2288
38.0k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2289
38.0k
    fxMatchToken(parser, parser->states[0].token);
2290
38.0k
    break;
2291
10.6k
  case XS_TOKEN_IMPORT:
2292
10.6k
    fxMatchToken(parser, XS_TOKEN_IMPORT);
2293
10.6k
    if (!flag && (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)) {
2294
6.38k
      txUnsigned flags = parser->flags & mxForFlag;
2295
6.38k
      fxGetNextToken(parser);
2296
6.38k
      parser->flags &= ~mxForFlag;
2297
6.38k
      fxAssignmentExpression(parser);
2298
6.38k
      if (parser->states[0].token == XS_TOKEN_COMMA) {
2299
166
        fxGetNextToken(parser);
2300
166
        if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
2301
128
          fxAssignmentExpression(parser);
2302
128
          if (parser->states[0].token == XS_TOKEN_COMMA)
2303
76
            fxGetNextToken(parser);
2304
128
        }
2305
38
        else
2306
38
          fxPushNULL(parser);
2307
166
      }
2308
6.21k
      else
2309
6.21k
        fxPushNULL(parser);
2310
6.38k
      parser->flags |= flags;
2311
6.38k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
2312
6.38k
      fxPushNodeStruct(parser, 2, XS_TOKEN_IMPORT_CALL, aLine);
2313
6.38k
    }
2314
4.23k
    else if (parser->states[0].token == XS_TOKEN_DOT) {
2315
1.87k
      fxGetNextToken(parser);
2316
1.87k
      if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->metaSymbol) && (!parser->states[0].escaped)) { 
2317
1.70k
        fxGetNextToken(parser);
2318
1.70k
        if (parser->flags & mxProgramFlag)
2319
1.57k
          fxReportParserError(parser, parser->states[0].line, "invalid import.meta");
2320
125
        else
2321
125
          fxPushNodeStruct(parser, 0, XS_TOKEN_IMPORT_META, aLine);
2322
1.70k
      }
2323
171
      else
2324
171
        fxReportParserError(parser, parser->states[0].line, "invalid import.");
2325
1.87k
    }
2326
2.36k
    else
2327
2.36k
      fxReportParserError(parser, parser->states[0].line, "invalid import");
2328
10.6k
    break;
2329
6.36k
  case XS_TOKEN_SUPER:
2330
6.36k
    fxMatchToken(parser, XS_TOKEN_SUPER);
2331
6.36k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2332
322
      if (parser->flags & mxDerivedFlag) {
2333
46
        fxParameters(parser);
2334
46
        fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2335
46
      }
2336
276
      else {
2337
276
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2338
276
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2339
276
      }
2340
322
    }
2341
6.04k
    else if ((parser->states[0].token == XS_TOKEN_DOT) || (parser->states[0].token == XS_TOKEN_LEFT_BRACKET)) {
2342
1.63k
      if (parser->flags & mxSuperFlag) {
2343
1.23k
        fxPushNodeStruct(parser, 0, XS_TOKEN_THIS, aLine);
2344
1.23k
        parser->root->flags |= parser->flags & (mxDerivedFlag | mxSuperFlag);
2345
1.23k
      }
2346
406
      else {
2347
406
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2348
406
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2349
406
      }
2350
1.63k
    }
2351
4.40k
    else
2352
4.40k
      fxReportParserError(parser, parser->states[0].line, "invalid super");
2353
6.36k
    parser->flags |= mxSuperFlag;
2354
6.36k
    break;
2355
39.8k
  case XS_TOKEN_THIS:
2356
39.8k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2357
39.8k
    parser->root->flags |= parser->flags & mxDerivedFlag;
2358
39.8k
    fxMatchToken(parser, XS_TOKEN_THIS);
2359
39.8k
    break;
2360
5.10M
  case XS_TOKEN_INTEGER:
2361
5.10M
    fxPushIntegerNode(parser, parser->states[0].integer, aLine);
2362
5.10M
    fxGetNextToken(parser);
2363
5.10M
    break;
2364
39.2k
  case XS_TOKEN_NUMBER:
2365
39.2k
    fxPushNumberNode(parser, parser->states[0].number, aLine);
2366
39.2k
    fxGetNextToken(parser);
2367
39.2k
    break;
2368
143k
  case XS_TOKEN_BIGINT:
2369
143k
    fxPushBigIntNode(parser, &parser->states[0].bigint, aLine);
2370
143k
    fxGetNextToken(parser);
2371
143k
    break;
2372
1.17k
  case XS_TOKEN_DIVIDE_ASSIGN:
2373
1.17k
    c = '=';
2374
    // continue
2375
31.9k
  case XS_TOKEN_DIVIDE:
2376
31.9k
    fxGetNextRegExp(parser, c);
2377
31.9k
    fxPushStringNode(parser, parser->states[0].modifierLength, parser->states[0].modifier, aLine);
2378
31.9k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2379
31.9k
    fxPushNodeStruct(parser, 2, XS_TOKEN_REGEXP, aLine);
2380
31.9k
    fxGetNextToken(parser);
2381
31.9k
    break;
2382
331k
  case XS_TOKEN_STRING:
2383
331k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2384
331k
    fxGetNextToken(parser);
2385
331k
    break;
2386
2.29M
  case XS_TOKEN_IDENTIFIER:
2387
2.29M
    escaped = parser->states[0].escaped;
2388
2.29M
    aSymbol = parser->states[0].symbol;
2389
2.29M
    fxGetNextToken(parser);
2390
//    if (aSymbol == parser->undefinedSymbol) {
2391
//      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2392
//      break;
2393
//    }
2394
2.29M
    flags = 0;
2395
2.29M
    if ((aSymbol == parser->asyncSymbol) && (!escaped) && (!parser->states[0].crlf)) {
2396
8.53k
      if (parser->states[0].token == XS_TOKEN_FUNCTION) {
2397
725
        fxMatchToken(parser, XS_TOKEN_FUNCTION);
2398
725
        if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2399
170
          fxGetNextToken(parser);
2400
170
          fxGeneratorExpression(parser, aLine, C_NULL, mxAsyncFlag);
2401
170
        }
2402
555
        else
2403
555
          fxFunctionExpression(parser, aLine, C_NULL, mxAsyncFlag);
2404
725
        break;
2405
725
      }
2406
7.81k
      if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2407
4.11k
        fxGroupExpression(parser, mxAsyncFlag);
2408
4.11k
        break;
2409
4.11k
      }
2410
3.70k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2411
//        if (!(parser->flags & mxForFlag) || !fxIsKeyword(parser, parser->ofSymbol)) {
2412
1.48k
          aSymbol = parser->states[0].symbol;
2413
1.48k
          fxGetNextToken(parser);
2414
1.48k
          flags = mxAsyncFlag;
2415
//        }
2416
1.48k
      }
2417
3.70k
    }
2418
2.29M
    if (aSymbol == parser->awaitSymbol)
2419
985
      parser->flags |= mxAwaitingFlag;
2420
2.29M
    if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
2421
23.4k
      fxCheckStrictSymbol(parser, aSymbol);
2422
23.4k
      if (flags && (aSymbol == parser->awaitSymbol))
2423
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2424
23.4k
      fxPushSymbol(parser, aSymbol);
2425
23.4k
      fxPushNULL(parser);
2426
23.4k
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2427
23.4k
      fxPushNodeList(parser, 1);
2428
23.4k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2429
23.4k
      fxArrowExpression(parser, flags);
2430
23.4k
      break;
2431
23.4k
    }
2432
2.27M
    if (aSymbol == parser->argumentsSymbol)
2433
2.32k
      parser->flags |= mxArgumentsFlag;
2434
2.27M
    fxPushSymbol(parser, aSymbol);
2435
2.27M
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2436
2.27M
    break;
2437
23.4k
  case XS_TOKEN_CLASS:
2438
23.4k
    flags = parser->flags & mxForFlag;
2439
23.4k
    parser->flags &= ~mxForFlag;
2440
23.4k
    fxClassExpression(parser, aLine, C_NULL);
2441
23.4k
    parser->flags |= flags;
2442
23.4k
    break;
2443
339k
  case XS_TOKEN_FUNCTION:
2444
339k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
2445
339k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2446
11.6k
      fxGetNextToken(parser);
2447
11.6k
      fxGeneratorExpression(parser, aLine, C_NULL, 0);
2448
11.6k
    }
2449
327k
    else
2450
327k
      fxFunctionExpression(parser, aLine, C_NULL, 0);
2451
339k
    break;
2452
60.3k
  case XS_TOKEN_NEW:
2453
60.3k
    fxNewExpression(parser);
2454
60.3k
    break;
2455
275k
  case XS_TOKEN_LEFT_BRACE:
2456
275k
    flags = parser->flags & mxForFlag;
2457
275k
    parser->flags &= ~mxForFlag;
2458
275k
    fxObjectExpression(parser);
2459
275k
    parser->flags |= flags;
2460
275k
    break;
2461
158k
  case XS_TOKEN_LEFT_BRACKET:
2462
158k
    flags = parser->flags & mxForFlag;
2463
158k
    parser->flags &= ~mxForFlag;
2464
158k
    fxArrayExpression(parser);
2465
158k
    parser->flags |= flags;
2466
158k
    break;
2467
508k
  case XS_TOKEN_LEFT_PARENTHESIS:
2468
508k
    fxGroupExpression(parser, 0);
2469
508k
    break;
2470
46.9k
  case XS_TOKEN_TEMPLATE:
2471
46.9k
    fxPushNULL(parser);
2472
46.9k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2473
46.9k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2474
46.9k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2475
46.9k
    fxGetNextToken(parser);
2476
46.9k
    fxPushNodeList(parser, 1);
2477
46.9k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2478
46.9k
    break;
2479
1.87k
  case XS_TOKEN_TEMPLATE_HEAD:
2480
1.87k
    fxPushNULL(parser);
2481
1.87k
    fxTemplateExpression(parser);
2482
1.87k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2483
1.87k
    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
59.3k
  case XS_TOKEN_LESS:
2499
59.3k
    fxGetNextToken(parser);
2500
59.3k
    fxJSXElement(parser);
2501
59.3k
    fxGetNextToken(parser);
2502
59.3k
    break;
2503
23.4k
  default:
2504
23.4k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2505
23.4k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
2506
23.4k
    break;
2507
9.54M
  }
2508
9.54M
}
2509
2510
void fxArrayExpression(txParser* parser)
2511
158k
{
2512
158k
  txInteger aCount = 0;
2513
158k
  int elision = 1;
2514
158k
  txInteger aLine = parser->states[0].line;
2515
158k
  txBoolean aSpreadFlag = 0;
2516
158k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
2517
867k
  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
708k
    txInteger anItemLine = parser->states[0].line;
2519
708k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
2520
374k
      fxGetNextToken(parser);
2521
374k
      if (elision) {
2522
186k
        fxPushNodeStruct(parser, 0, XS_TOKEN_ELISION, anItemLine);
2523
186k
        aCount++;
2524
186k
      }
2525
188k
      else
2526
188k
        elision = 1;
2527
374k
    }
2528
334k
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
2529
2.88k
      fxGetNextToken(parser);
2530
2.88k
      if (!elision)
2531
1.45k
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2532
2.88k
      fxAssignmentExpression(parser);
2533
2.88k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, anItemLine);
2534
2.88k
      aCount++;
2535
2.88k
      elision = 0;
2536
2.88k
      aSpreadFlag = 1;
2537
2.88k
    }
2538
331k
    else {
2539
331k
      if (!elision)
2540
2.67k
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2541
331k
      fxAssignmentExpression(parser);
2542
331k
      aCount++;
2543
331k
      elision = 0;
2544
331k
    }
2545
708k
  }
2546
158k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2547
158k
  fxPushNodeList(parser, aCount);
2548
158k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
2549
158k
  if (aCount && elision)
2550
3.42k
    parser->root->flags |= mxElisionFlag;
2551
158k
  if (aSpreadFlag)
2552
714
    parser->root->flags |= mxSpreadFlag;
2553
158k
}
2554
2555
void fxArrowExpression(txParser* parser, txUnsigned flag)
2556
91.0k
{
2557
91.0k
  txInteger aLine = parser->states[0].line;
2558
91.0k
  txUnsigned flags = parser->flags;
2559
91.0k
  parser->flags &= ~(mxAsyncFlag | mxGeneratorFlag);
2560
91.0k
  parser->flags |= mxArrowFlag | flag;
2561
91.0k
  fxMatchToken(parser, XS_TOKEN_ARROW);
2562
91.0k
  fxPushNULL(parser);
2563
91.0k
  fxSwapNodes(parser);  
2564
91.0k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2565
60.7k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2566
60.7k
    fxBody(parser);
2567
60.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2568
60.7k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2569
60.7k
  }
2570
30.3k
  else {
2571
30.3k
    fxAssignmentExpression(parser);
2572
30.3k
    fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
2573
30.3k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2574
30.3k
    if (!(flags & mxAsyncFlag) && (flag & mxAsyncFlag)) {
2575
1.16k
      if (parser->states[0].token == XS_TOKEN_AWAIT) {
2576
1
        parser->states[0].token = XS_TOKEN_IDENTIFIER;
2577
1
      }
2578
1.16k
    }
2579
30.3k
  }
2580
91.0k
  fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2581
91.0k
  parser->root->flags = parser->flags & (mxStrictFlag | mxFieldFlag | mxNotSimpleParametersFlag | mxArrowFlag | mxSuperFlag | flag);
2582
91.0k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2583
1.82k
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2584
91.0k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag | mxEvalFlag));
2585
91.0k
}
2586
2587
void fxClassExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol)
2588
79.8k
{
2589
79.8k
  txBoolean heritageFlag = 0;
2590
//  txBoolean hostFlag = 0;
2591
79.8k
  txNode* constructor = NULL;
2592
79.8k
  txInteger aCount = 0;
2593
79.8k
  txInteger aLine = parser->states[0].line;
2594
79.8k
  txUnsigned flags = parser->flags;
2595
79.8k
  txUnsigned constructorFlags = mxSuperFlag;
2596
79.8k
  txInteger constructorInitCount = 0;
2597
79.8k
  txInteger instanceInitCount = 0;
2598
79.8k
  parser->flags |= mxStrictFlag;
2599
79.8k
  fxMatchToken(parser, XS_TOKEN_CLASS);
2600
79.8k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2601
20.2k
    fxPushSymbol(parser, parser->states[0].symbol);
2602
20.2k
    if (theSymbol)
2603
16.3k
      *theSymbol = parser->states[0].symbol;
2604
20.2k
    fxGetNextToken(parser);
2605
20.2k
  }
2606
59.5k
  else
2607
59.5k
    fxPushNULL(parser);
2608
79.8k
  if (parser->states[0].token == XS_TOKEN_EXTENDS) {
2609
569
    fxMatchToken(parser, XS_TOKEN_EXTENDS);
2610
569
    fxCallExpression(parser);
2611
569
    fxCheckArrowFunction(parser, 1);
2612
569
    fxCheckNativeConstructor(parser);
2613
569
    flags |= parser->flags & mxAwaitingFlag;
2614
569
    constructorFlags |= mxDerivedFlag;
2615
569
    if (parser->root->description->token == XS_TOKEN_HOST)
2616
0
      constructorFlags |= mxHostFlag;
2617
569
    heritageFlag = 1;
2618
569
  }
2619
79.2k
  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
79.2k
  else {
2636
79.2k
    fxPushNULL(parser);
2637
79.2k
    constructorFlags |= mxBaseFlag;
2638
79.2k
  }
2639
79.8k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2640
71.8k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2641
150k
    for (;;) {
2642
150k
      txBoolean aStaticFlag;
2643
150k
      txInteger aPropertyLine = parser->states[0].line;
2644
150k
      txSymbol* aSymbol;
2645
150k
      txToken aToken0;
2646
150k
      txToken aToken1;
2647
150k
      txToken aToken2;
2648
150k
      txUnsigned flag;
2649
169k
      while (parser->states[0].token == XS_TOKEN_SEMICOLON)
2650
18.3k
        fxGetNextToken(parser);
2651
150k
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
2652
14.2k
        break;
2653
136k
      aStaticFlag = 0;
2654
136k
      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
7.23k
          fxPushSymbol(parser, parser->staticSymbol);
2658
7.23k
          aToken1 = XS_TOKEN_PROPERTY;
2659
7.23k
          goto field;
2660
7.23k
        }
2661
42.6k
        if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2662
32.1k
          txUnsigned flags = parser->flags;
2663
32.1k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag | mxAsyncFlag;
2664
32.1k
          fxCheckParserStack(parser, aPropertyLine);
2665
32.1k
          fxGetNextToken(parser);
2666
32.1k
          fxStatements(parser);
2667
32.1k
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2668
32.1k
          fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aPropertyLine);
2669
32.1k
          if (parser->flags & mxArgumentsFlag)
2670
0
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2671
32.1k
          if (parser->flags & mxAwaitingFlag)
2672
0
            fxReportParserError(parser, parser->states[0].line, "invalid await");
2673
32.1k
          parser->flags = flags;
2674
32.1k
          parser->root->flags |= mxStaticFlag;
2675
32.1k
          constructorInitCount++;
2676
32.1k
          aCount++;
2677
32.1k
          continue;
2678
32.1k
        }
2679
10.5k
        aStaticFlag = 1;
2680
10.5k
      }
2681
97.0k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flag);
2682
97.0k
      if ((aStaticFlag == 0) && (aSymbol == parser->constructorSymbol)) {
2683
213
        fxPopNode(parser); // symbol
2684
213
        if (constructor || (aToken2 == XS_TOKEN_GENERATOR) || (aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER) || (flag & mxAsyncFlag)) 
2685
2
          fxReportParserError(parser, parser->states[0].line, "invalid constructor");
2686
213
        fxFunctionExpression(parser, aPropertyLine, C_NULL, constructorFlags);
2687
213
        constructor = fxPopNode(parser);
2688
213
      }
2689
96.8k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2690
10.9k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2691
1
          fxReportParserError(parser, parser->states[0].line, "invalid method: #constructor");
2692
10.9k
        if (aStaticFlag && (aSymbol == parser->prototypeSymbol))
2693
0
          fxReportParserError(parser, parser->states[0].line, "invalid static method: prototype");
2694
10.9k
        if (aStaticFlag)
2695
2.85k
          flag |= mxStaticFlag;
2696
10.9k
        if (aToken2 == XS_TOKEN_GETTER) 
2697
269
          flag |= mxGetterFlag;
2698
10.6k
        else if (aToken2 == XS_TOKEN_SETTER) 
2699
118
          flag |= mxSetterFlag;
2700
10.5k
        else
2701
10.5k
          flag |= mxMethodFlag;
2702
10.9k
        if (aToken2 == XS_TOKEN_GENERATOR)
2703
2.26k
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2704
8.67k
        else
2705
8.67k
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2706
10.9k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2707
10.9k
        parser->root->flags |= flag & (mxStaticFlag | mxGetterFlag | mxSetterFlag | mxMethodFlag);
2708
10.9k
        if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
2709
1.36k
          if (aStaticFlag)
2710
12
            constructorInitCount++;
2711
1.35k
          else
2712
1.35k
            instanceInitCount++;
2713
1.36k
        }
2714
10.9k
        aCount++;
2715
10.9k
      }
2716
85.9k
      else {
2717
85.9k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2718
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: #constructor");
2719
85.9k
        if (aSymbol == parser->constructorSymbol)
2720
0
          fxReportParserError(parser, parser->states[0].line, "invalid field: constructor");
2721
85.9k
        if (aSymbol == parser->prototypeSymbol)
2722
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: prototype");
2723
85.9k
      field:
2724
84.1k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
2725
11.5k
          txUnsigned flags = parser->flags;
2726
11.5k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag;
2727
11.5k
          fxGetNextToken(parser);
2728
11.5k
          fxAssignmentExpression(parser);
2729
11.5k
          if (parser->flags & mxArgumentsFlag)
2730
1
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2731
11.5k
          parser->flags = flags;
2732
11.5k
        }
2733
72.6k
        else {
2734
72.6k
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2735
72.6k
        }
2736
84.1k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2737
84.1k
        if (aStaticFlag) {
2738
4.73k
          parser->root->flags |= mxStaticFlag;
2739
4.73k
          constructorInitCount++;
2740
4.73k
        }
2741
79.4k
        else
2742
79.4k
          instanceInitCount++;
2743
84.1k
        fxSemicolon(parser);
2744
84.1k
        aCount++;
2745
84.1k
      }
2746
97.0k
    }
2747
71.8k
  }
2748
70.8k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2749
70.8k
  fxPushNodeList(parser, aCount);
2750
  
2751
70.8k
  if (constructorInitCount || instanceInitCount) {
2752
9.86k
    txNodeList* itemsList = (txNodeList*)(parser->root);
2753
9.86k
    txNodeList* constructorInitList = C_NULL;
2754
9.86k
    txNode** constructorInitAddress = C_NULL;
2755
9.86k
    txNodeList* instanceInitList = C_NULL;
2756
9.86k
    txNode** instanceInitAddress = C_NULL;
2757
9.86k
    txNode** address;
2758
9.86k
    txNode* item;
2759
9.86k
    if (constructorInitCount) {
2760
2.21k
      fxPushNULL(parser);
2761
2.21k
      fxPushNodeList(parser, 0);
2762
2.21k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2763
2.21k
      fxPushNodeList(parser, 0);
2764
2.21k
      constructorInitList = (txNodeList*)(parser->root);
2765
2.21k
      constructorInitList->length = constructorInitCount;
2766
2.21k
      constructorInitAddress = &(((txNodeList*)(parser->root))->first);
2767
2.21k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2768
2.21k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2769
2.21k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2770
2.21k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2771
2.21k
    }
2772
7.65k
    else 
2773
7.65k
      fxPushNULL(parser);
2774
9.86k
    if (instanceInitCount) {
2775
8.18k
      fxPushNULL(parser);
2776
8.18k
      fxPushNodeList(parser, 0);
2777
8.18k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2778
8.18k
      fxPushNodeList(parser, 0);
2779
8.18k
      instanceInitList = (txNodeList*)(parser->root);
2780
8.18k
      instanceInitList->length = instanceInitCount;
2781
8.18k
      instanceInitAddress = &(((txNodeList*)(parser->root))->first);
2782
8.18k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2783
8.18k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2784
8.18k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2785
8.18k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2786
8.18k
    }
2787
1.68k
    else 
2788
1.68k
      fxPushNULL(parser);
2789
9.86k
    address = &(itemsList->first);
2790
46.5k
    while ((item = *address)) {
2791
36.6k
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2792
2.68k
        if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) {
2793
1.32k
          txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2794
1.32k
          field->item = item;
2795
1.32k
          if (item->flags & mxStaticFlag) {
2796
9
            *constructorInitAddress = (txNode*)field;
2797
9
            constructorInitAddress = &field->next;
2798
9
          }
2799
1.31k
          else {
2800
1.31k
            *instanceInitAddress = (txNode*)field;
2801
1.31k
            instanceInitAddress = &field->next;
2802
1.31k
          }
2803
1.32k
        }
2804
2.68k
      }
2805
36.6k
      address = &(item->next);
2806
36.6k
    }
2807
9.86k
    address = &(itemsList->first);
2808
46.5k
    while ((item = *address)) {
2809
36.6k
      if (item->description->token == XS_TOKEN_BODY) {
2810
1.54k
        *address = item->next;
2811
1.54k
        item->next = C_NULL;
2812
1.54k
        itemsList->length--;
2813
1.54k
        *constructorInitAddress = (txNode*)item;
2814
1.54k
        constructorInitAddress = &item->next;
2815
1.54k
      }
2816
35.1k
      else if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2817
2.68k
        address = &(item->next);
2818
2.68k
      }
2819
32.4k
      else {
2820
32.4k
        txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2821
32.4k
        field->item = item;
2822
32.4k
        if (item->description->token == XS_TOKEN_PROPERTY) {
2823
14.9k
          field->value = ((txPropertyNode*)item)->value;
2824
14.9k
          ((txPropertyNode*)item)->value = C_NULL;
2825
14.9k
        }
2826
17.4k
        else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
2827
12.5k
          field->value = ((txPropertyAtNode*)item)->value;
2828
12.5k
          ((txPropertyAtNode*)item)->value = C_NULL;
2829
12.5k
        }
2830
4.95k
        else {
2831
4.95k
          field->value = ((txPrivatePropertyNode*)item)->value;
2832
4.95k
          ((txPrivatePropertyNode*)item)->value = C_NULL;
2833
4.95k
        }
2834
32.4k
        if (item->flags & mxStaticFlag) {
2835
666
          *constructorInitAddress = (txNode*)field;
2836
666
          constructorInitAddress = &field->next;
2837
666
        }
2838
31.7k
        else {
2839
31.7k
          *instanceInitAddress = (txNode*)field;
2840
31.7k
          instanceInitAddress = &field->next;
2841
31.7k
        }
2842
32.4k
        address = &(item->next);
2843
32.4k
      }
2844
36.6k
    }
2845
9.86k
  }
2846
60.9k
  else {
2847
60.9k
    fxPushNULL(parser);
2848
60.9k
    fxPushNULL(parser);
2849
60.9k
  }
2850
70.8k
  if (constructor) {
2851
200
    fxPushNode(parser, constructor);
2852
200
  }
2853
70.6k
  else {
2854
70.6k
    if (heritageFlag) {
2855
346
      fxPushNULL(parser);
2856
    
2857
346
      fxPushSymbol(parser, parser->argsSymbol);
2858
346
      fxPushNULL(parser);
2859
346
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2860
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
2861
346
      fxPushNodeList(parser, 1);
2862
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2863
      
2864
346
      fxPushSymbol(parser, parser->argsSymbol);
2865
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2866
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2867
346
      fxPushNodeList(parser, 1);
2868
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
2869
346
      parser->root->flags |= mxSpreadFlag;
2870
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2871
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2872
346
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2873
      
2874
346
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2875
346
      parser->root->flags = mxStrictFlag | mxDerivedFlag | mxMethodFlag | mxTargetFlag | mxSuperFlag;
2876
346
    }
2877
70.2k
    else {
2878
70.2k
      fxPushNULL(parser);
2879
    
2880
70.2k
      fxPushNodeList(parser, 0);
2881
70.2k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2882
      
2883
70.2k
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2884
70.2k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2885
70.2k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2886
      
2887
70.2k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2888
70.2k
      parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2889
70.2k
    }
2890
70.6k
  }
2891
70.8k
  fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2892
70.8k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag));
2893
70.8k
}
2894
2895
void fxFunctionExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2896
348k
{
2897
348k
  txUnsigned flags = parser->flags;
2898
348k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxFunctionFlag | mxTargetFlag | flag;
2899
348k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2900
80.0k
      || ((flags & mxGeneratorFlag) && !(flags & mxStrictFlag) && (parser->states[0].token == XS_TOKEN_YIELD))
2901
268k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2902
268k
    fxPushSymbol(parser, parser->states[0].symbol);
2903
268k
    if (theSymbol)
2904
4.08k
      *theSymbol = parser->states[0].symbol;
2905
268k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2906
268k
    fxGetNextToken(parser);
2907
268k
  }
2908
80.0k
  else
2909
80.0k
    fxPushNULL(parser);
2910
348k
  fxParametersBinding(parser);
2911
348k
  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
348k
  else {
2928
348k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2929
348k
    fxBody(parser);
2930
348k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2931
348k
    fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, theLine);
2932
348k
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2933
348k
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2934
3.13k
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2935
348k
        if (parser->flags & mxNativeFlag) {
2936
0
          fxCheckNativeFunction(parser);
2937
0
        }     
2938
348k
        parser->flags = flags;
2939
348k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2940
348k
  }
2941
348k
}
2942
2943
void fxGeneratorExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2944
16.3k
{
2945
16.3k
  txUnsigned flags = parser->flags;
2946
16.3k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxGeneratorFlag | mxTargetFlag | flag;
2947
16.3k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2948
12.3k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2949
12.3k
    fxPushSymbol(parser, parser->states[0].symbol);
2950
12.3k
    if (theSymbol)
2951
714
      *theSymbol = parser->states[0].symbol;
2952
11.6k
    else if (parser->states[0].symbol == parser->yieldSymbol)
2953
713
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
2954
10.9k
    else if ((parser->flags & mxAsyncFlag) && (parser->states[0].symbol == parser->awaitSymbol))
2955
0
      fxReportParserError(parser, parser->states[0].line, "invalid await");
2956
12.3k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2957
12.3k
    fxGetNextToken(parser);
2958
12.3k
  }
2959
4.00k
  else
2960
4.00k
    fxPushNULL(parser);
2961
16.3k
  fxParametersBinding(parser);
2962
16.3k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2963
16.3k
  parser->flags |= mxYieldFlag;
2964
16.3k
    fxBody(parser);
2965
16.3k
  parser->flags &= ~mxYieldFlag;
2966
16.3k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2967
16.3k
  fxPushNodeStruct(parser, 3, XS_TOKEN_GENERATOR, theLine);
2968
16.3k
  parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxGeneratorFlag | mxArgumentsFlag | mxEvalFlag | flag);
2969
16.3k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2970
228
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2971
16.3k
  parser->flags = flags;
2972
16.3k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2973
16.3k
}
2974
2975
void fxGroupExpression(txParser* parser, txUnsigned flag)
2976
512k
{
2977
512k
  txBoolean commaFlag = 0;
2978
512k
  txBoolean spreadFlag = 0;
2979
512k
  txInteger aCount = 0;
2980
512k
  txInteger aLine;
2981
512k
  txUnsigned formerAwaitingYieldingFlags = parser->flags & (mxAwaitingFlag | mxYieldingFlag);
2982
512k
  parser->flags &= ~(mxAwaitingFlag | mxYieldingFlag);
2983
512k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
2984
731k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2985
449k
    aLine = parser->states[0].line;
2986
449k
    commaFlag = 0;
2987
449k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
2988
313
      fxGetNextToken(parser);
2989
313
      fxAssignmentExpression(parser);
2990
313
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2991
313
      spreadFlag = 1;
2992
313
    }
2993
449k
    else
2994
449k
      fxAssignmentExpression(parser);
2995
449k
    aCount++;
2996
449k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
2997
231k
      break;
2998
218k
    fxGetNextToken(parser);
2999
218k
    commaFlag = 1;
3000
218k
  }
3001
512k
  aLine = parser->states[0].line;
3002
512k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3003
512k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
3004
67.8k
    fxPushNodeList(parser, aCount);
3005
67.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3006
67.8k
    if (commaFlag && spreadFlag)
3007
0
      fxReportParserError(parser, parser->states[0].line, "invalid parameters");
3008
67.8k
    if (!fxParametersBindingFromExpressions(parser, parser->root))
3009
219
      fxReportParserError(parser, parser->states[0].line, "no parameters");
3010
67.8k
    fxCheckStrictBinding(parser, parser->root);
3011
67.8k
    parser->root->flags |= flag;
3012
67.8k
    if (parser->flags & mxAwaitingFlag) {
3013
80
      if (flag || (parser->flags & mxAsyncFlag))
3014
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
3015
80
      else
3016
80
        formerAwaitingYieldingFlags |= mxAwaitingFlag;
3017
80
    }
3018
67.8k
    if (parser->flags & mxYieldingFlag)
3019
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
3020
67.8k
    fxArrowExpression(parser, flag);
3021
67.8k
  }
3022
445k
  else if (flag) {
3023
1.19k
    fxPushNodeList(parser, aCount);
3024
1.19k
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3025
1.19k
    if (spreadFlag)
3026
1
      parser->root->flags |= mxSpreadFlag;
3027
    
3028
1.19k
    fxPushSymbol(parser, parser->asyncSymbol);
3029
1.19k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
3030
1.19k
    fxSwapNodes(parser);
3031
1.19k
    fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
3032
1.19k
  }
3033
443k
  else {
3034
443k
        if ((aCount == 0) || commaFlag) {
3035
4.79k
            fxPushNULL(parser);
3036
4.79k
      fxReportParserError(parser, parser->states[0].line, "missing expression");
3037
4.79k
        }
3038
439k
    else /*if (aCount > 1)*/ {
3039
439k
      fxPushNodeList(parser, aCount);
3040
439k
      fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3041
439k
    }
3042
443k
  }
3043
512k
  parser->flags |= formerAwaitingYieldingFlags;
3044
512k
}
3045
3046
void fxNewExpression(txParser* parser)
3047
60.3k
{
3048
60.3k
  txInteger aLine = parser->states[0].line;
3049
60.3k
  fxMatchToken(parser, XS_TOKEN_NEW);
3050
60.3k
  if (parser->states[0].token == XS_TOKEN_DOT) {
3051
582
    fxGetNextToken(parser);
3052
582
    if (fxIsKeyword(parser, parser->targetSymbol)) {
3053
57
      if (!(parser->flags & mxTargetFlag))
3054
2
        fxReportParserError(parser, parser->states[0].line, "invalid new.target");
3055
57
      fxGetNextToken(parser);
3056
57
      fxPushNodeStruct(parser, 0, XS_TOKEN_TARGET, aLine);
3057
57
    }
3058
525
    else
3059
525
      fxReportParserError(parser, parser->states[0].line, "missing target");
3060
582
    return;
3061
582
  }
3062
59.7k
  fxLiteralExpression(parser, 1);
3063
59.7k
  fxCheckArrowFunction(parser, 1);
3064
63.1k
  for (;;) {
3065
63.1k
    txInteger aMemberLine = parser->states[0].line;
3066
63.1k
    if (parser->states[0].token == XS_TOKEN_DOT) {
3067
5.99k
      fxGetNextToken(parser);
3068
5.99k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3069
5.97k
        fxPushSymbol(parser, parser->states[0].symbol);
3070
5.97k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aMemberLine);
3071
5.97k
        fxGetNextToken(parser);
3072
5.97k
      }
3073
13
      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
3
      else
3080
3
        fxReportParserError(parser, parser->states[0].line, "missing property");
3081
5.99k
    }
3082
57.1k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3083
368
      fxGetNextToken(parser);
3084
368
      fxCommaExpression(parser);
3085
368
      fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aMemberLine);
3086
368
      fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3087
368
    }
3088
56.8k
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
3089
251
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3090
251
      fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3091
251
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3092
251
      fxGetNextToken(parser);
3093
251
      fxPushNodeList(parser, 1);
3094
251
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3095
251
    }
3096
56.5k
    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
56.5k
    else
3101
56.5k
      break;
3102
63.1k
  } 
3103
59.7k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3104
45.5k
    fxParameters(parser);
3105
14.1k
  else {
3106
14.1k
    fxPushNodeList(parser, 0);
3107
14.1k
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3108
14.1k
  }
3109
59.7k
  fxPushNodeStruct(parser, 2, XS_TOKEN_NEW, aLine);
3110
59.7k
}
3111
3112
void fxObjectExpression(txParser* parser)
3113
275k
{
3114
275k
  txInteger aCount = 0;
3115
275k
  txSymbol* aSymbol;
3116
275k
  txToken aToken0;
3117
275k
  txToken aToken1;
3118
275k
  txToken aToken2;
3119
275k
  txInteger aLine = parser->states[0].line;
3120
275k
  txNode* base = parser->root;
3121
275k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3122
351k
  for (;;) {
3123
351k
    txInteger aPropertyLine = parser->states[0].line;
3124
351k
    txUnsigned flags = 0;
3125
351k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3126
122k
            break;
3127
228k
        if (parser->states[0].token == XS_TOKEN_SPREAD) {
3128
74.1k
      fxGetNextToken(parser);
3129
74.1k
      fxAssignmentExpression(parser);
3130
74.1k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aPropertyLine);
3131
74.1k
        }
3132
154k
        else {
3133
154k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flags);
3134
154k
      if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
3135
1.54k
        fxReportParserError(parser, parser->states[0].line, "invalid private property");
3136
1.54k
      }
3137
153k
      else if ((aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER)) {
3138
881
        flags |= mxShorthandFlag;
3139
881
        if (aToken2 == XS_TOKEN_GETTER)
3140
672
          flags |= mxGetterFlag;
3141
209
        else if (aToken2 == XS_TOKEN_SETTER)
3142
209
          flags |= mxSetterFlag;
3143
881
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3144
879
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag);
3145
2
        else
3146
2
          fxReportParserError(parser, parser->states[0].line, "missing (");
3147
881
      }
3148
152k
      else if (aToken2 == XS_TOKEN_GENERATOR) {
3149
5.89k
        flags |= mxShorthandFlag | mxMethodFlag;
3150
5.89k
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3151
1.48k
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3152
4.40k
        else
3153
4.40k
          fxReportParserError(parser, parser->states[0].line, "missing (");
3154
5.89k
      }
3155
146k
      else if (aToken2 == XS_TOKEN_FUNCTION) {
3156
44
        flags |= mxShorthandFlag | mxMethodFlag;
3157
44
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3158
41
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3159
3
        else
3160
3
          fxReportParserError(parser, parser->states[0].line, "missing (");
3161
44
      }
3162
146k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3163
4.20k
        flags |= mxShorthandFlag | mxMethodFlag;
3164
4.20k
        fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3165
4.20k
      }
3166
142k
      else if (parser->states[0].token == XS_TOKEN_COLON) {
3167
123k
        fxGetNextToken(parser);
3168
123k
        fxAssignmentExpression(parser);
3169
123k
      }
3170
18.9k
      else if (aToken1 == XS_TOKEN_PROPERTY) {
3171
10.1k
        flags |= mxShorthandFlag;
3172
10.1k
        fxPushSymbol(parser, aSymbol);
3173
10.1k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
3174
4.38k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3175
4.38k
          fxGetNextToken(parser);
3176
4.38k
          fxAssignmentExpression(parser);
3177
4.38k
          fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aPropertyLine);
3178
4.38k
        }
3179
5.73k
        else if (aToken0 == XS_TOKEN_IDENTIFIER) {
3180
3.51k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3181
3.51k
        }
3182
2.21k
        else {
3183
2.21k
          fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3184
2.21k
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3185
2.21k
        }
3186
10.1k
      }
3187
8.78k
      else {
3188
8.78k
        fxReportParserError(parser, parser->states[0].line, "missing :");
3189
8.78k
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3190
8.78k
      }
3191
154k
      fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
3192
154k
      parser->root->flags |= flags;
3193
154k
      fxCheckUniqueProperty(parser, base, parser->root); 
3194
154k
    }
3195
228k
    aCount++;
3196
228k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3197
110k
            break;
3198
118k
    fxMatchToken(parser, XS_TOKEN_COMMA);
3199
118k
  }
3200
275k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3201
275k
  fxPushNodeList(parser, aCount);
3202
275k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
3203
275k
}
3204
3205
void fxTemplateExpression(txParser* parser)
3206
2.31k
{
3207
2.31k
  txInteger aCount = 0;
3208
2.31k
  txInteger aLine = parser->states[0].line;
3209
2.31k
  fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3210
2.31k
  fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3211
2.31k
  fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3212
2.31k
  aCount++;
3213
6.84k
  for (;;) {
3214
6.84k
    fxGetNextToken(parser);
3215
6.84k
        if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3216
5.21k
            fxCommaExpression(parser);
3217
5.21k
            aCount++;
3218
5.21k
        }
3219
6.84k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3220
3
      fxReportParserError(parser, parser->states[0].line, "missing }");
3221
3
    }
3222
6.84k
    fxGetNextTokenTemplate(parser);
3223
6.84k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3224
6.84k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3225
6.84k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3226
6.84k
    aCount++;
3227
6.84k
    if (parser->states[0].token == XS_TOKEN_TEMPLATE_TAIL) {
3228
1.36k
      fxGetNextToken(parser);
3229
1.36k
      break;
3230
1.36k
    }
3231
6.84k
  }
3232
2.31k
  fxPushNodeList(parser, aCount);
3233
2.31k
}
3234
3235
void fxYieldExpression(txParser* parser)
3236
16.1k
{
3237
16.1k
  txInteger aLine = parser->states[0].line;
3238
16.1k
  if (!(parser->flags & mxYieldFlag))
3239
169
    fxReportParserError(parser, parser->states[0].line, "invalid yield");
3240
15.9k
  else
3241
15.9k
    parser->flags |= mxYieldingFlag;
3242
16.1k
  fxMatchToken(parser, XS_TOKEN_YIELD);
3243
16.1k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_MULTIPLY)) {
3244
125
    fxGetNextToken(parser);
3245
125
    fxAssignmentExpression(parser);
3246
125
    fxPushNodeStruct(parser, 1, XS_TOKEN_DELEGATE, aLine);
3247
125
    return;
3248
125
  }
3249
16.0k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3250
15.6k
    fxAssignmentExpression(parser);
3251
15.6k
  }
3252
398
  else {
3253
398
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
3254
398
  }
3255
16.0k
  fxPushNodeStruct(parser, 1, XS_TOKEN_YIELD, aLine);
3256
16.0k
}
3257
3258
void fxParameters(txParser* parser)
3259
413k
{
3260
413k
  txInteger aCount = 0;
3261
413k
  txInteger aLine = parser->states[0].line;
3262
413k
  txBoolean aSpreadFlag = 0;
3263
413k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
3264
962k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3265
549k
    txInteger aParamLine = parser->states[0].line;
3266
549k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3267
255
      fxGetNextToken(parser);
3268
255
      fxAssignmentExpression(parser);
3269
255
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aParamLine);
3270
255
      aSpreadFlag = 1;
3271
255
    }
3272
549k
    else
3273
549k
      fxAssignmentExpression(parser);
3274
549k
    aCount++;
3275
549k
    if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3276
228k
      fxMatchToken(parser, XS_TOKEN_COMMA);
3277
549k
  }
3278
413k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3279
413k
  fxPushNodeList(parser, aCount);
3280
413k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3281
413k
  if (aSpreadFlag)
3282
183
    parser->root->flags |= mxSpreadFlag;
3283
413k
}
3284
3285
void fxPropertyName(txParser* parser, txSymbol** theSymbol, txToken* theToken0, txToken* theToken1, txToken* theToken2, txUnsigned* flag)
3286
250k
{
3287
250k
  txSymbol* aSymbol = C_NULL;
3288
250k
  txToken aToken0 = XS_NO_TOKEN;
3289
250k
  txToken aToken1 = XS_NO_TOKEN;
3290
250k
  txToken aToken2 = XS_NO_TOKEN;
3291
250k
  txInteger aLine = parser->states[0].line;
3292
250k
  txIndex index;
3293
250k
  *flag = 0;
3294
250k
  fxLookAheadOnce(parser);
3295
250k
  aToken0 = parser->states[0].token;
3296
250k
  if ((gxTokenFlags[aToken0] & XS_TOKEN_IDENTIFIER_NAME)) {
3297
166k
    aSymbol = parser->states[0].symbol;
3298
166k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3299
113k
      fxPushSymbol(parser, aSymbol);
3300
113k
      aToken1 = XS_TOKEN_PROPERTY;
3301
113k
    }
3302
53.5k
    else if (fxIsKeyword(parser, parser->asyncSymbol) && (!parser->states[1].crlf)) {
3303
5.50k
      *flag = mxAsyncFlag;
3304
5.50k
      fxGetNextToken(parser);
3305
5.50k
      if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3306
3.94k
        aToken2 = XS_TOKEN_GENERATOR;
3307
3.94k
        fxGetNextToken(parser);
3308
3.94k
      }
3309
1.55k
      else
3310
1.55k
        aToken2 = XS_TOKEN_FUNCTION;
3311
5.50k
    }
3312
48.0k
    else if (fxIsKeyword(parser, parser->getSymbol)) {
3313
1.57k
      aToken2 = XS_TOKEN_GETTER;
3314
1.57k
      fxGetNextToken(parser);
3315
1.57k
    }
3316
46.5k
    else if (fxIsKeyword(parser, parser->setSymbol)) {
3317
5.86k
      aToken2 = XS_TOKEN_SETTER;
3318
5.86k
      fxGetNextToken(parser);
3319
5.86k
    }
3320
40.6k
    else {
3321
40.6k
      fxPushSymbol(parser, aSymbol);
3322
40.6k
      aToken1 = XS_TOKEN_PROPERTY;
3323
40.6k
    }
3324
166k
  }
3325
83.4k
  else if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3326
11.3k
    aToken2 = XS_TOKEN_GENERATOR;
3327
11.3k
    fxGetNextToken(parser);
3328
11.3k
  }
3329
72.1k
  else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3330
9.46k
    aSymbol = parser->states[0].symbol;
3331
9.46k
    fxPushSymbol(parser, aSymbol);
3332
9.46k
    aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3333
9.46k
  }
3334
62.6k
  else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3335
21.7k
    if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3336
21.7k
      fxPushIndexNode(parser, index, aLine);
3337
21.7k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3338
21.7k
    }
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
21.7k
  }
3345
40.8k
  else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3346
2.88k
    if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3347
2.07k
      fxPushIndexNode(parser, index, aLine);
3348
2.07k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3349
2.07k
    }
3350
808
    else {
3351
808
      aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3352
808
      fxPushSymbol(parser, aSymbol);
3353
808
      aToken1 = XS_TOKEN_PROPERTY;
3354
808
    }
3355
2.88k
  }
3356
37.9k
  else if (parser->states[0].token == XS_TOKEN_STRING) {
3357
23.3k
    if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3358
4.12k
      fxPushIndexNode(parser, index, aLine);
3359
4.12k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3360
4.12k
    }
3361
19.2k
    else {
3362
19.2k
      aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3363
19.2k
      fxPushSymbol(parser, aSymbol);
3364
19.2k
      aToken1 = XS_TOKEN_PROPERTY;
3365
19.2k
    }
3366
23.3k
  }
3367
14.6k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3368
7.14k
    fxGetNextToken(parser);
3369
7.14k
    fxCommaExpression(parser);
3370
7.14k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3371
1.36k
      fxReportParserError(parser, parser->states[0].line, "missing ]");
3372
1.36k
    }
3373
7.14k
    aToken1 = XS_TOKEN_PROPERTY_AT;
3374
7.14k
  }
3375
7.46k
  else {
3376
7.46k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3377
7.46k
    fxPushNULL(parser);
3378
7.46k
  }
3379
250k
  if (aToken2 != XS_NO_TOKEN) {
3380
24.2k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3381
9.91k
      aSymbol = parser->states[0].symbol;
3382
9.91k
      fxPushSymbol(parser, aSymbol);
3383
9.91k
      aToken1 = XS_TOKEN_PROPERTY;
3384
9.91k
      fxGetNextToken(parser);
3385
9.91k
    }
3386
14.3k
    else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3387
2.80k
      aSymbol = parser->states[0].symbol;
3388
2.80k
      fxPushSymbol(parser, aSymbol);
3389
2.80k
      aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3390
2.80k
      fxGetNextToken(parser);
3391
2.80k
    }
3392
11.5k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3393
1.23k
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3394
1.23k
        fxPushIndexNode(parser, index, aLine);
3395
1.23k
        aToken1 = XS_TOKEN_PROPERTY_AT;
3396
1.23k
      }
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.23k
      fxGetNextToken(parser);
3403
1.23k
    }
3404
10.2k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3405
4.19k
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3406
2.87k
        fxPushIndexNode(parser, index, aLine);
3407
2.87k
        aToken1 = XS_TOKEN_PROPERTY_AT;
3408
2.87k
      }
3409
1.32k
      else {
3410
1.32k
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3411
1.32k
        fxPushSymbol(parser, aSymbol);
3412
1.32k
        aToken1 = XS_TOKEN_PROPERTY;
3413
1.32k
      }
3414
4.19k
      fxGetNextToken(parser);
3415
4.19k
    }
3416
6.09k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3417
963
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3418
307
        fxPushIndexNode(parser, index, aLine);
3419
307
        aToken1 = XS_TOKEN_PROPERTY_AT;
3420
307
      }
3421
656
      else {
3422
656
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3423
656
        fxPushSymbol(parser, aSymbol);
3424
656
        aToken1 = XS_TOKEN_PROPERTY;
3425
656
      }
3426
963
      fxGetNextToken(parser);
3427
963
    }
3428
5.13k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3429
109
      fxGetNextToken(parser);
3430
109
      fxCommaExpression(parser);
3431
109
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3432
1
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3433
1
      }
3434
109
      aToken1 = XS_TOKEN_PROPERTY_AT;
3435
109
      fxGetNextToken(parser);
3436
109
    }
3437
5.02k
    else if (aToken2 == XS_TOKEN_GETTER) {
3438
612
      fxPushSymbol(parser, aSymbol);
3439
612
      aToken1 = XS_TOKEN_PROPERTY;
3440
612
      aToken2 = XS_NO_TOKEN;
3441
612
    }
3442
4.41k
    else if (aToken2 == XS_TOKEN_SETTER) {
3443
2.73k
      fxPushSymbol(parser, aSymbol);
3444
2.73k
      aToken1 = XS_TOKEN_PROPERTY;
3445
2.73k
      aToken2 = XS_NO_TOKEN;
3446
2.73k
    }
3447
1.67k
    else {
3448
1.67k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3449
1.67k
      fxPushNULL(parser);
3450
1.67k
    }
3451
24.2k
  }
3452
226k
  else
3453
226k
    fxGetNextToken(parser);
3454
250k
  *theSymbol = aSymbol;
3455
250k
  *theToken0 = aToken0;
3456
250k
  *theToken1 = aToken1;
3457
250k
  *theToken2 = aToken2;
3458
250k
}
3459
3460
void fxBinding(txParser* parser, txToken theToken, txUnsigned flags)
3461
296k
{
3462
296k
  txInteger aLine = parser->states[0].line;
3463
296k
  fxCheckParserStack(parser, aLine);
3464
296k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3465
238k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
3466
238k
    if (((theToken == XS_TOKEN_CONST) || (theToken == XS_TOKEN_LET) || (theToken == XS_TOKEN_USING)) && (parser->states[0].symbol == parser->letSymbol))
3467
551
      fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3468
238k
    fxPushSymbol(parser, parser->states[0].symbol);
3469
238k
    fxPushNodeStruct(parser, 1, theToken, aLine);
3470
238k
    if (flags & mxAwaitingFlag)
3471
0
      parser->root->flags |= mxAwaitingFlag;
3472
238k
    fxGetNextToken(parser);
3473
238k
  }
3474
58.9k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
3475
16.4k
    if (theToken == XS_TOKEN_USING)
3476
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3477
16.4k
    fxObjectBinding(parser, theToken);
3478
16.4k
  }
3479
42.5k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3480
40.1k
    if (theToken == XS_TOKEN_USING)
3481
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3482
40.1k
    fxArrayBinding(parser, theToken);
3483
40.1k
  }
3484
2.36k
  else {
3485
2.36k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3486
2.36k
    fxPushNULL(parser);
3487
2.36k
  }
3488
296k
  if ((flags & 1) && (parser->states[0].token == XS_TOKEN_ASSIGN)) {
3489
119k
    parser->flags &= ~mxForFlag;
3490
119k
    fxGetNextToken(parser);
3491
119k
    fxAssignmentExpression(parser);
3492
119k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aLine);
3493
119k
  }
3494
296k
}
3495
3496
txNode* fxBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3497
87.4k
{
3498
87.4k
  txToken aToken = (theNode && theNode->description) ? theNode->description->token : XS_NO_TOKEN;
3499
87.4k
  txNode* binding;
3500
106k
again:
3501
106k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
3502
52.8k
    txNode* item = ((txExpressionsNode*)theNode)->items->first;
3503
52.8k
    if (item && !item->next) {
3504
52.5k
      aToken = item->description->token;
3505
52.5k
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3506
33.2k
        item->next = theNode->next;
3507
33.2k
        theNode = item;
3508
33.2k
      }
3509
19.3k
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
3510
18.5k
        item->next = theNode->next;
3511
18.5k
        theNode = item;
3512
18.5k
        goto again;
3513
18.5k
      }
3514
731
      else
3515
731
        return NULL;
3516
52.5k
    }
3517
52.8k
  }
3518
86.7k
  if (aToken == XS_TOKEN_BINDING) {
3519
2.09k
    binding = fxBindingFromExpression(parser, ((txBindingNode*)theNode)->target, theToken);
3520
2.09k
    ((txBindingNode*)theNode)->target = binding;
3521
//    fxCheckStrictBinding(parser, theNode);
3522
//    fxCheckStrictSymbol(parser, ((txBindingNode*)theNode)->symbol);
3523
//    theNode->description = &gxTokenDescriptions[theToken];
3524
2.09k
    return theNode;
3525
2.09k
  }
3526
84.6k
  if (aToken == XS_TOKEN_ARRAY_BINDING) {
3527
314
    txNodeList* list = ((txArrayBindingNode*)theNode)->items;
3528
314
    txNode** address = &(list->first);
3529
314
    txNode* item;
3530
1.05k
    while ((item = *address)) {
3531
745
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3532
745
      binding->next = item->next;
3533
745
      address = &(binding->next);
3534
745
    }
3535
314
    return theNode;
3536
314
  }
3537
84.3k
  if (aToken == XS_TOKEN_OBJECT_BINDING) {
3538
54
    txNodeList* list = ((txObjectBindingNode*)theNode)->items;
3539
54
    txNode** address = &(list->first);
3540
54
    txNode* item;
3541
91
    while ((item = *address)) {
3542
37
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3543
37
      binding->next = item->next;
3544
37
      address = &(binding->next);
3545
37
    }
3546
54
    return theNode;
3547
54
  }
3548
84.2k
  if (aToken == XS_TOKEN_PROPERTY_BINDING) {
3549
35
    ((txPropertyBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingNode*)theNode)->binding, theToken);
3550
35
    return theNode;
3551
35
  }
3552
84.2k
  if (aToken == XS_TOKEN_PROPERTY_BINDING_AT) {
3553
0
    ((txPropertyBindingAtNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingAtNode*)theNode)->binding, theToken);
3554
0
    return theNode;
3555
0
  }
3556
84.2k
  if (aToken == XS_TOKEN_REST_BINDING) {
3557
32
    ((txRestBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txRestBindingNode*)theNode)->binding, theToken);
3558
32
    return theNode;
3559
32
  }
3560
84.1k
  if (aToken == XS_TOKEN_SKIP_BINDING)
3561
423
    return theNode;
3562
  
3563
83.7k
  if (aToken == XS_TOKEN_ACCESS) {
3564
61.7k
    fxCheckStrictSymbol(parser, ((txAccessNode*)theNode)->symbol);
3565
61.7k
    if (theToken == XS_TOKEN_ACCESS)
3566
53.0k
      return theNode;
3567
8.71k
    fxPushSymbol(parser, ((txAccessNode*)theNode)->symbol);
3568
8.71k
    fxPushNodeStruct(parser, 1, theToken, ((txAccessNode*)theNode)->line);
3569
8.71k
    return fxPopNode(parser);
3570
61.7k
  }
3571
22.0k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3572
17.1k
    return theNode;
3573
17.1k
  }
3574
4.86k
  if (aToken == XS_TOKEN_ASSIGN) {
3575
348
    binding = fxBindingFromExpression(parser, ((txAssignNode*)theNode)->reference, theToken);
3576
348
    if (!binding)
3577
0
      return NULL;
3578
348
    ((txBindingNode*)theNode)->description = &gxTokenDescriptions[XS_TOKEN_BINDING];
3579
348
    ((txBindingNode*)theNode)->target = binding;
3580
348
    ((txBindingNode*)theNode)->initializer = ((txAssignNode*)theNode)->value;
3581
348
    return theNode;
3582
348
  }
3583
  
3584
4.51k
  if (aToken == XS_TOKEN_ARRAY)
3585
2.20k
    return fxArrayBindingFromExpression(parser, theNode, theToken);
3586
2.31k
  if (aToken == XS_TOKEN_OBJECT)
3587
290
    return fxObjectBindingFromExpression(parser, theNode, theToken);
3588
2.02k
  return NULL;
3589
2.31k
}
3590
3591
void fxArrayBinding(txParser* parser, txToken theToken)
3592
40.1k
{
3593
40.1k
  txInteger aCount = 0;
3594
40.1k
  txInteger aLine = parser->states[0].line;
3595
40.1k
  int elision = 1;
3596
40.1k
  fxCheckParserStack(parser, aLine);
3597
40.1k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
3598
136k
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING)) {
3599
96.0k
    txInteger anItemLine = parser->states[0].line;
3600
96.0k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
3601
71.4k
      fxGetNextToken(parser);
3602
71.4k
      if (elision) {
3603
51.7k
        fxPushNodeStruct(parser, 0, XS_TOKEN_SKIP_BINDING, anItemLine);
3604
51.7k
        aCount++;
3605
51.7k
      }
3606
19.7k
      else
3607
19.7k
        elision = 1;
3608
71.4k
    }
3609
24.6k
    else {
3610
24.6k
      if (!elision)
3611
1.92k
        fxReportParserError(parser, parser->states[0].line, "missing ,");
3612
24.6k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3613
17
        fxRestBinding(parser, theToken, 0);
3614
17
        aCount++;
3615
17
        break;
3616
17
      }
3617
24.6k
      fxBinding(parser, theToken, 1);
3618
24.6k
      aCount++;
3619
24.6k
      elision = 0;
3620
24.6k
    }
3621
96.0k
  }
3622
40.1k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3623
40.1k
  fxPushNodeList(parser, aCount);
3624
40.1k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, aLine);
3625
40.1k
}
3626
3627
txNode* fxArrayBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3628
2.95k
{
3629
2.95k
  txNodeList* list = ((txArrayNode*)theNode)->items;
3630
2.95k
  txNode** address = &(list->first);
3631
2.95k
  txNode* item;
3632
2.95k
  txNode* binding;
3633
7.84k
  while ((item = *address)) {
3634
5.32k
        if (!item->description) {
3635
0
            parser->errorSymbol = parser->SyntaxErrorSymbol;
3636
0
            return NULL;
3637
0
        }
3638
5.32k
    if (item->description->token == XS_TOKEN_SPREAD) {
3639
44
      if (theNode->flags & mxElisionFlag) {
3640
1
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3641
1
        return NULL;
3642
1
      }
3643
43
      binding = fxRestBindingFromExpression(parser, item, theToken, 0);
3644
43
      if (!binding) {
3645
4
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3646
4
        return NULL;
3647
4
      }
3648
39
      break;
3649
43
    }
3650
5.28k
    if (item->description->token == XS_TOKEN_ELISION) {
3651
1.91k
      item->description = &gxTokenDescriptions[XS_TOKEN_SKIP_BINDING];
3652
1.91k
    }
3653
3.36k
    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
3.36k
        binding = fxBindingFromExpression(parser, item, theToken);
3658
3.36k
        if (!binding) {
3659
383
          parser->errorSymbol = parser->SyntaxErrorSymbol;
3660
383
          return NULL;
3661
383
        }
3662
2.97k
        binding->next = item->next;
3663
2.97k
        item = *address = binding;
3664
//      }
3665
2.97k
    }
3666
4.89k
    address = &(item->next);
3667
4.89k
  }
3668
2.56k
  fxPushNode(parser, (txNode*)list);
3669
2.56k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, theNode->line);
3670
2.56k
  return fxPopNode(parser);
3671
2.95k
}
3672
3673
txUnsigned fxObjectBinding(txParser* parser, txToken theToken)
3674
16.4k
{
3675
16.4k
  txUnsigned flags = 0;
3676
16.4k
  txInteger aCount = 0;
3677
16.4k
  txInteger aLine = parser->states[0].line;
3678
16.4k
  txSymbol* aSymbol;
3679
16.4k
  txToken aToken;
3680
16.4k
  txIndex index;
3681
16.4k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3682
17.3k
  for (;;) {
3683
17.3k
    txInteger aPropertyLine = parser->states[0].line;
3684
17.3k
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3685
1.13k
      break;
3686
16.2k
    aSymbol = NULL;
3687
16.2k
    aToken = XS_TOKEN_PROPERTY_BINDING;
3688
16.2k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3689
4.91k
      aSymbol = parser->states[0].symbol;
3690
4.91k
      fxPushSymbol(parser, aSymbol);
3691
4.91k
      aToken = XS_TOKEN_PROPERTY_BINDING;
3692
4.91k
    }
3693
11.3k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3694
2.63k
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3695
2.63k
        fxPushIndexNode(parser, index, aPropertyLine);
3696
2.63k
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3697
2.63k
      }
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
2.63k
    }
3704
8.67k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3705
2.70k
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3706
6
        fxPushIndexNode(parser, index, aPropertyLine);
3707
6
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3708
6
      }
3709
2.69k
      else {
3710
2.69k
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3711
2.69k
        fxPushSymbol(parser, aSymbol);
3712
2.69k
        aToken = XS_TOKEN_PROPERTY_BINDING;
3713
2.69k
      }
3714
2.70k
    }
3715
5.97k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3716
707
      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
704
      else {
3721
704
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3722
704
        fxPushSymbol(parser, aSymbol);
3723
704
        aToken = XS_TOKEN_PROPERTY_BINDING;
3724
704
      }
3725
707
    }
3726
5.26k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3727
3.53k
      fxGetNextToken(parser);
3728
3.53k
      fxCommaExpression(parser);
3729
3.53k
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3730
1.79k
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3731
1.79k
      }
3732
3.53k
      aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3733
3.53k
    }
3734
1.72k
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
3735
79
      flags |= mxSpreadFlag;
3736
79
      fxRestBinding(parser, theToken, 1);
3737
79
      aCount++;
3738
79
            break;
3739
79
    }
3740
1.65k
    else {
3741
1.65k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3742
1.65k
      fxPushNULL(parser);
3743
1.65k
    }
3744
16.1k
    fxLookAheadOnce(parser);
3745
16.1k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3746
579
      fxGetNextToken(parser);
3747
579
      fxGetNextToken(parser);
3748
579
      fxBinding(parser, theToken, 1);
3749
579
    }
3750
15.5k
    else if (aSymbol) {
3751
5.56k
      fxBinding(parser, theToken, 1);
3752
5.56k
    }
3753
10.0k
    else {
3754
10.0k
      fxReportParserError(parser, parser->states[0].line, "missing :");
3755
10.0k
      fxPushNULL(parser);
3756
10.0k
    }
3757
16.1k
    fxPushNodeStruct(parser, 2, aToken, aPropertyLine);
3758
16.1k
    aCount++;
3759
16.1k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3760
118
            break;
3761
16.0k
    if (parser->states[0].token == XS_TOKEN_COMMA)
3762
1.01k
      fxGetNextToken(parser);
3763
15.0k
    else
3764
15.0k
            break;
3765
16.0k
  }
3766
16.4k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3767
16.4k
  fxPushNodeList(parser, aCount);
3768
16.4k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, aLine);
3769
16.4k
  parser->root->flags |= flags;
3770
16.4k
  return flags;
3771
16.4k
}
3772
3773
txNode* fxObjectBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3774
86.1k
{
3775
86.1k
  txNodeList* list = ((txObjectNode*)theNode)->items;
3776
86.1k
  txNode* property = list->first;
3777
86.1k
  txNode* binding;
3778
86.1k
  txUnsigned flags = 0;
3779
91.3k
  while (property) {
3780
73.0k
    if (!property->description) {
3781
0
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3782
0
      return NULL;
3783
0
    }
3784
73.0k
    if (property->description->token == XS_TOKEN_PROPERTY) {
3785
3.65k
      binding = fxBindingFromExpression(parser, ((txPropertyNode*)property)->value, theToken);
3786
3.65k
      if (!binding) {
3787
401
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3788
401
        return NULL;
3789
401
      }
3790
3.25k
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING];
3791
3.25k
      ((txPropertyBindingNode*)property)->binding = binding;
3792
3.25k
    }
3793
69.3k
    else if (property->description->token == XS_TOKEN_PROPERTY_AT) {
3794
1.92k
      binding = fxBindingFromExpression(parser, ((txPropertyAtNode*)property)->value, theToken);
3795
1.92k
      if (!binding) {
3796
16
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3797
16
        return NULL;
3798
16
      }
3799
1.90k
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING_AT];
3800
1.90k
      ((txPropertyBindingAtNode*)property)->binding = binding;
3801
1.90k
    }
3802
67.4k
    else if (property->description->token == XS_TOKEN_SPREAD) {
3803
67.4k
      binding = fxRestBindingFromExpression(parser, property, theToken, 1);
3804
67.4k
      if (!binding) {
3805
2.20k
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3806
2.20k
        return NULL;
3807
2.20k
      }
3808
65.2k
      flags |= mxSpreadFlag;
3809
65.2k
      break;
3810
67.4k
    }
3811
5.16k
    property = property->next;
3812
5.16k
  }
3813
83.5k
  fxPushNode(parser, (txNode*)list);
3814
83.5k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, theNode->line);
3815
83.5k
  parser->root->flags |= flags;
3816
83.5k
  return fxPopNode(parser);
3817
86.1k
}
3818
3819
void fxParametersBinding(txParser* parser)
3820
363k
{
3821
363k
  txInteger aCount = 0;
3822
363k
  txInteger aLine = parser->states[0].line;
3823
363k
  txBindingNode* binding;
3824
363k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3825
362k
    fxGetNextToken(parser);
3826
380k
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
3827
18.7k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3828
552
        parser->flags |= mxNotSimpleParametersFlag;
3829
552
        fxRestBinding(parser, XS_TOKEN_ARG, 0);
3830
552
        aCount++;
3831
552
        break;
3832
552
      }
3833
18.2k
      fxBinding(parser, XS_TOKEN_ARG, 1);
3834
18.2k
      binding = (txBindingNode*)parser->root;
3835
18.2k
      if (binding->description->token != XS_TOKEN_ARG)
3836
1.79k
        parser->flags |= mxNotSimpleParametersFlag;
3837
18.2k
      aCount++;
3838
18.2k
      if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3839
7.44k
        fxMatchToken(parser, XS_TOKEN_COMMA);
3840
18.2k
    }
3841
362k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3842
362k
  }
3843
851
  else
3844
851
    fxReportParserError(parser, parser->states[0].line, "missing (");
3845
363k
  fxPushNodeList(parser, aCount);
3846
363k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
3847
363k
}
3848
3849
txNode* fxParametersBindingFromExpressions(txParser* parser, txNode* theNode)
3850
67.8k
{
3851
67.8k
  txNodeList* list = ((txParamsNode*)theNode)->items;
3852
67.8k
  txNode** address = &(list->first);
3853
67.8k
  txNode* item;
3854
67.8k
  txBindingNode* binding;
3855
75.3k
  while ((item = *address)) {
3856
7.73k
    txToken aToken = (item && item->description) ? item->description->token : XS_NO_TOKEN;
3857
7.73k
    if (aToken == XS_TOKEN_SPREAD) {
3858
17
      binding = (txBindingNode*)fxRestBindingFromExpression(parser, item, XS_TOKEN_ARG, 0);
3859
17
      if (!binding)
3860
1
        return NULL;
3861
16
      parser->flags |= mxNotSimpleParametersFlag;
3862
16
      break;
3863
17
    }
3864
7.71k
    binding = (txBindingNode*)fxBindingFromExpression(parser, item, XS_TOKEN_ARG);
3865
7.71k
    if (!binding)
3866
218
      return NULL;
3867
7.49k
    if (binding->description->token != XS_TOKEN_ARG)
3868
398
      parser->flags |= mxNotSimpleParametersFlag;
3869
7.49k
    binding->next = item->next;
3870
7.49k
    item = *address = (txNode*)binding;
3871
7.49k
    address = &(item->next);
3872
7.49k
  }
3873
67.6k
  theNode->description = &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING];
3874
67.6k
  return theNode;
3875
67.8k
}
3876
3877
void fxRestBinding(txParser* parser, txToken theToken, txUnsigned flag)
3878
648
{
3879
648
  txInteger aLine = parser->states[0].line;
3880
648
  fxMatchToken(parser, XS_TOKEN_SPREAD);
3881
648
  fxBinding(parser, theToken, 0);
3882
648
  if (flag && ((parser->root->description->token == XS_TOKEN_ARRAY_BINDING) || (parser->root->description->token == XS_TOKEN_OBJECT_BINDING))) {
3883
17
    fxReportParserError(parser, parser->states[0].line, "invalid rest");
3884
17
  }
3885
648
  fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
3886
648
}
3887
3888
txNode* fxRestBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken, txUnsigned flag)
3889
67.4k
{
3890
67.4k
  txNode* expression = ((txSpreadNode*)theNode)->expression;
3891
67.4k
  txNode* binding;
3892
67.4k
  if (theNode->next) {
3893
2
    parser->errorSymbol = parser->SyntaxErrorSymbol;
3894
2
    return NULL;
3895
2
  }
3896
67.4k
  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
67.4k
    binding = fxBindingFromExpression(parser, expression, theToken);
3902
67.4k
    if (!binding) {
3903
2.20k
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3904
2.20k
      return NULL;
3905
2.20k
    }
3906
65.2k
    if (binding->description->token == XS_TOKEN_BINDING) {
3907
177
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3908
177
      return NULL;
3909
177
    }
3910
65.1k
    if (flag && ((binding->description->token == XS_TOKEN_ARRAY_BINDING) || (binding->description->token == XS_TOKEN_OBJECT_BINDING))) {
3911
1.42k
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3912
1.42k
      return NULL;
3913
1.42k
    }
3914
//  }
3915
63.6k
  theNode->description = &gxTokenDescriptions[XS_TOKEN_REST_BINDING];
3916
63.6k
  ((txRestBindingNode*)theNode)->binding = binding;
3917
63.6k
  return theNode;
3918
65.1k
}
3919
3920
void fxCheckArrowFunction(txParser* parser, txInteger count)
3921
5.94M
{
3922
5.94M
  txNode* node = parser->root;
3923
16.9M
  while (count) {
3924
10.9M
    if (node->flags & mxArrowFlag)
3925
32.0k
      fxReportParserError(parser, parser->states[0].line, "invalid arrow function");
3926
10.9M
    count--;
3927
10.9M
    node = node->next;
3928
10.9M
  }
3929
5.94M
}
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
568
{
3941
568
  txClassNode* root = (txClassNode*)(parser->root);
3942
568
  if (root->description != &gxTokenDescriptions[XS_TOKEN_CLASS])
3943
553
    return;
3944
15
  if (root->symbol != C_NULL)
3945
6
    return;
3946
9
  txHostNode* host = (txHostNode*)(root->heritage);
3947
9
  if (host == C_NULL)
3948
8
    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
408k
{
4059
408k
  txNode* node = parser->root;
4060
408k
  txToken aToken = (node && node->description) ? node->description->token : XS_NO_TOKEN;
4061
408k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
4062
2.02k
    txNode* item;
4063
2.31k
  again:
4064
2.31k
    item = ((txExpressionsNode*)node)->items->first;
4065
2.31k
    if (item && !item->next) {
4066
2.08k
      aToken = (item->description) ? item->description->token : XS_NO_TOKEN;
4067
2.08k
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
4068
373
        item->next = node->next;
4069
373
        node = parser->root = item;
4070
373
      }
4071
1.70k
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
4072
292
        item->next = node->next;
4073
292
        node = item;
4074
292
        goto again;
4075
292
      }
4076
1.41k
      else
4077
1.41k
        aToken = XS_TOKEN_EXPRESSIONS;
4078
2.08k
    }
4079
2.31k
  }
4080
408k
  if (aToken == XS_TOKEN_ACCESS) {
4081
255k
    fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4082
255k
    return 1;
4083
255k
  }
4084
152k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED))
4085
53.0k
    return 1;
4086
    
4087
99.7k
  if (theToken == XS_TOKEN_ASSIGN) {
4088
91.2k
    if (aToken == XS_TOKEN_ARRAY) {
4089
748
      txNode* binding = fxArrayBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4090
748
            if (binding) {
4091
739
                binding->next = node->next;
4092
739
                parser->root = binding;
4093
739
        return 1;
4094
739
           }
4095
748
        }
4096
90.5k
    else if (aToken == XS_TOKEN_OBJECT) {
4097
85.8k
      txNode* binding = fxObjectBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4098
85.8k
            if (binding) {
4099
81.7k
                binding->next = node->next;
4100
81.7k
                parser->root = binding;
4101
81.7k
        return 1;
4102
81.7k
            }
4103
85.8k
        }
4104
91.2k
  }
4105
8.48k
  else if (theToken == XS_TOKEN_DELETE)
4106
1.51k
    return 1;
4107
15.8k
  return 0;
4108
99.7k
}
4109
4110
void fxCheckStrictBinding(txParser* parser, txNode* node)
4111
82.3k
{
4112
82.3k
  if (node && node->description) {
4113
82.3k
    if (node->description->token == XS_TOKEN_ACCESS) {
4114
0
      fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4115
0
    }
4116
82.3k
    else if (node->description->token == XS_TOKEN_ARG) {
4117
9.05k
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4118
9.05k
    }
4119
73.3k
    else if (node->description->token == XS_TOKEN_CONST) {
4120
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4121
0
    }
4122
73.3k
    else if (node->description->token == XS_TOKEN_LET) {
4123
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4124
0
    }
4125
73.3k
    else if (node->description->token == XS_TOKEN_USING) {
4126
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4127
0
    }
4128
73.3k
    else if (node->description->token == XS_TOKEN_VAR) {
4129
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4130
0
    }
4131
73.3k
    else if (node->description->token == XS_TOKEN_BINDING) {
4132
8
      fxCheckStrictBinding(parser, ((txBindingNode*)node)->target);
4133
8
    }
4134
73.3k
    else if (node->description->token == XS_TOKEN_ARRAY_BINDING) {
4135
361
      node = ((txArrayBindingNode*)node)->items->first;
4136
1.73k
      while (node) {
4137
1.37k
        fxCheckStrictBinding(parser, node);
4138
1.37k
        node = node->next;
4139
1.37k
      }
4140
361
    }
4141
72.9k
    else if (node->description->token == XS_TOKEN_OBJECT_BINDING) {
4142
22
      node = ((txObjectBindingNode*)node)->items->first;
4143
39
      while (node) {
4144
17
        fxCheckStrictBinding(parser, node);
4145
17
        node = node->next;
4146
17
      }
4147
22
    }
4148
72.9k
    else if (node->description->token == XS_TOKEN_PARAMS_BINDING) {
4149
72.8k
      node = ((txParamsBindingNode*)node)->items->first;
4150
80.9k
      while (node) {
4151
8.07k
        fxCheckStrictBinding(parser, node);
4152
8.07k
        node = node->next;
4153
8.07k
      }
4154
72.8k
    }
4155
56
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING)
4156
14
      fxCheckStrictBinding(parser, ((txPropertyBindingNode*)node)->binding);
4157
42
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING_AT)
4158
1
      fxCheckStrictBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
4159
41
    else if (node->description->token == XS_TOKEN_REST_BINDING)
4160
17
      fxCheckStrictBinding(parser, ((txRestBindingNode*)node)->binding);
4161
82.3k
  }
4162
82.3k
}
4163
4164
void fxCheckStrictFunction(txParser* parser, txFunctionNode* function)
4165
5.18k
{
4166
5.18k
  parser->states[0].line = function->line;
4167
5.18k
  fxCheckStrictSymbol(parser, function->symbol);
4168
5.18k
  fxCheckStrictBinding(parser, function->params);
4169
5.18k
}
4170
4171
void fxCheckStrictSymbol(txParser* parser, txSymbol* symbol)
4172
872k
{
4173
872k
  if (parser->flags & mxStrictFlag) {
4174
49.5k
    if (symbol == parser->argumentsSymbol)
4175
1.00k
      fxReportParserError(parser, parser->states[0].line, "invalid arguments (strict mode)");
4176
48.5k
    else if (symbol == parser->evalSymbol)
4177
29
      fxReportParserError(parser, parser->states[0].line, "invalid eval (strict mode)");
4178
48.4k
    else if (symbol == parser->yieldSymbol)
4179
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield (strict mode)");
4180
49.5k
  }
4181
823k
  else if (parser->flags & mxYieldFlag) {
4182
2.98k
    if (symbol == parser->yieldSymbol)
4183
1
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
4184
2.98k
  }
4185
872k
}
4186
4187
void fxCheckUniqueProperty(txParser* parser, txNode* base, txNode* current)
4188
122k
{
4189
122k
  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
665
{
4368
665
  txSize beforeLength = before->length;
4369
665
  txSize afterLength = after->length;
4370
665
  txSize length = beforeLength + 1 + afterLength + 1;
4371
665
  txString string = fxNewParserChunk(parser, length);
4372
665
  snprintf(string, length, "%s-%s", before->string, after->string);
4373
665
  return fxNewParserSymbol(parser, string);
4374
665
}
4375
4376
void fxJSXAttributeName(txParser* parser)
4377
32.2k
{
4378
32.2k
  txSymbol* symbol = parser->states[0].symbol;
4379
32.2k
  fxGetNextToken(parser);
4380
32.8k
  while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4381
584
    fxGetNextToken(parser);
4382
584
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4383
580
      symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4384
4
    else
4385
4
      fxReportParserError(parser, parser->states[0].line, "missing name");
4386
584
    fxGetNextToken(parser);
4387
584
  }
4388
32.2k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4389
3.93k
    fxGetNextToken(parser);
4390
3.93k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4391
1.73k
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4392
2.20k
    else
4393
2.20k
      fxReportParserError(parser, parser->states[0].line, "missing name");
4394
3.93k
    fxGetNextToken(parser);
4395
4.44k
    while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4396
505
      fxGetNextToken(parser);
4397
505
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4398
85
        symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4399
420
      else
4400
420
        fxReportParserError(parser, parser->states[0].line, "missing name");
4401
505
      fxGetNextToken(parser);
4402
505
    }  
4403
3.93k
  }
4404
32.2k
  fxPushSymbol(parser, symbol);
4405
32.2k
}
4406
4407
void fxJSXAttributeValue(txParser* parser)
4408
8.57k
{
4409
8.57k
  txInteger line = parser->states[0].line;
4410
8.57k
  fxGetNextTokenJSXAttribute(parser);
4411
8.57k
  if (parser->states[0].token == XS_TOKEN_STRING) {
4412
2.31k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
4413
2.31k
    fxGetNextToken(parser);
4414
2.31k
  }
4415
6.26k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4416
90
    fxGetNextToken(parser);
4417
90
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE) {
4418
1
      fxGetNextToken(parser);
4419
1
      fxReportParserError(parser, parser->states[0].line, "missing expression");
4420
1
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4421
1
    }
4422
89
    else {
4423
89
      fxAssignmentExpression(parser);
4424
89
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4425
10
        fxGetNextToken(parser);
4426
79
      else
4427
79
        fxReportParserError(parser, parser->states[0].line, "missing }");
4428
89
    }
4429
90
  }
4430
6.17k
  else {
4431
6.17k
    fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4432
6.17k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4433
6.17k
  }
4434
8.57k
}
4435
4436
void fxJSXElement(txParser* parser)
4437
130k
{
4438
130k
  txBoolean closed = 0;
4439
130k
  txInteger line = parser->states[0].line;
4440
130k
  txNode* name = NULL;
4441
130k
  txInteger nodeCount = parser->nodeCount;
4442
130k
  txInteger propertyCount = 0;
4443
130k
  fxPushSymbol(parser, parser->__jsx__Symbol);
4444
130k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, parser->states[0].line);
4445
130k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4446
127k
    fxJSXElementName(parser);
4447
127k
    name = parser->root;
4448
127k
  }
4449
2.45k
  else {
4450
2.45k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
4451
2.45k
    fxPushNULL(parser);
4452
2.45k
  }
4453
140k
  for (;;) {
4454
140k
    if (parser->states[0].token == XS_TOKEN_MORE)
4455
44.6k
      break;
4456
95.6k
    if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4457
57.0k
      fxGetNextToken(parser);
4458
57.0k
      if (parser->states[0].token != XS_TOKEN_MORE)
4459
1.04k
        fxReportParserError(parser, parser->states[0].line, "missing >");
4460
57.0k
      closed = 1;
4461
57.0k
      break;
4462
57.0k
    }
4463
38.5k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
4464
32.2k
      fxJSXAttributeName(parser);
4465
32.2k
      if (parser->states[0].token == XS_TOKEN_ASSIGN)
4466
8.57k
        fxJSXAttributeValue(parser);
4467
23.7k
      else
4468
23.7k
        fxPushNodeStruct(parser, 0, XS_TOKEN_TRUE, parser->states[0].line);
4469
32.2k
      fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY, parser->states[0].line);
4470
32.2k
      propertyCount++;
4471
32.2k
    }
4472
6.29k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4473
1.71k
      fxGetNextToken(parser);
4474
1.71k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
4475
389
        fxGetNextToken(parser);
4476
389
        fxAssignmentExpression(parser);
4477
389
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4478
6
          fxGetNextToken(parser);
4479
383
        else
4480
383
          fxReportParserError(parser, parser->states[0].line, "missing }");
4481
389
        fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, parser->states[0].line);
4482
389
        propertyCount++;
4483
389
      }
4484
1.33k
      else
4485
1.33k
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4486
1.71k
    }
4487
4.58k
    else {
4488
4.58k
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4489
4.58k
      break;
4490
4.58k
    }
4491
38.5k
  }
4492
130k
  if (propertyCount > 0) {
4493
19.0k
    fxPushNodeList(parser, propertyCount);
4494
19.0k
    fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, parser->states[0].line);
4495
19.0k
  }
4496
111k
  else
4497
111k
    fxPushNodeStruct(parser, 0, XS_TOKEN_NULL, parser->states[0].line);
4498
130k
  if (!closed) {
4499
106k
    for (;;) {
4500
106k
      fxGetNextTokenJSXChild(parser);
4501
106k
      if (parser->states[0].stringLength)
4502
21.2k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4503
106k
      if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4504
8.72k
        fxGetNextToken(parser);
4505
8.72k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4506
2.48k
          fxGetNextToken(parser);
4507
6.24k
        else {
4508
6.24k
          fxAssignmentExpression(parser);
4509
6.24k
          if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4510
2.15k
            fxReportParserError(parser, parser->states[0].line, "missing }");
4511
6.24k
        }
4512
8.72k
      }
4513
97.2k
      else if (parser->states[0].token == XS_TOKEN_LESS) {
4514
92.0k
        fxGetNextToken(parser);
4515
92.0k
        if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4516
19.9k
          fxGetNextToken(parser);
4517
19.9k
          if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4518
19.2k
            fxJSXElementName(parser);
4519
19.2k
            if (!fxJSXMatch(parser, name, parser->root)) {
4520
3.85k
              fxReportParserError(parser, parser->states[0].line, "invalid element");
4521
3.85k
              fxPushNULL(parser);
4522
3.85k
            }
4523
19.2k
          }
4524
764
          else {
4525
764
            fxReportParserError(parser, parser->states[0].line, "missing identifier");
4526
764
            fxPushNULL(parser);
4527
764
          }
4528
19.9k
          if (parser->states[0].token != XS_TOKEN_MORE)
4529
2.08k
            fxReportParserError(parser, parser->states[0].line, "missing >");
4530
19.9k
          fxPopNode(parser);
4531
19.9k
          break;
4532
19.9k
        }
4533
72.0k
        else
4534
72.0k
          fxJSXElement(parser);
4535
92.0k
      }
4536
5.26k
      else {
4537
5.26k
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4538
5.26k
        break;
4539
5.26k
      }
4540
106k
    }
4541
44.6k
  }
4542
130k
  fxPushNodeList(parser, parser->nodeCount - nodeCount - 1);
4543
130k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, line);
4544
130k
  fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, line);
4545
130k
}
4546
4547
void fxJSXElementName(txParser* parser)
4548
147k
{
4549
147k
  txInteger line = parser->states[0].line;
4550
147k
  txSymbol* symbol = parser->states[0].symbol;
4551
147k
  fxGetNextToken(parser);
4552
147k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4553
3.34k
    fxGetNextToken(parser);
4554
3.34k
    if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
4555
1.07k
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4556
2.27k
    else
4557
2.27k
      fxReportParserError(parser, parser->states[0].line, "missing name");
4558
3.34k
    fxPushSymbol(parser, symbol);
4559
3.34k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4560
3.34k
    fxGetNextToken(parser);
4561
3.34k
  }
4562
143k
  else {
4563
143k
    fxPushSymbol(parser, symbol);
4564
143k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4565
181k
    while (parser->states[0].token == XS_TOKEN_DOT) {
4566
37.3k
      fxGetNextToken(parser);
4567
37.3k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4568
23.4k
        fxPushSymbol(parser, parser->states[0].symbol);
4569
23.4k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, parser->states[0].line);
4570
23.4k
        fxGetNextToken(parser);
4571
23.4k
      }
4572
13.8k
      else
4573
13.8k
        fxReportParserError(parser, parser->states[0].line, "missing property");
4574
37.3k
    }
4575
143k
  }
4576
147k
}
4577
4578
txBoolean fxJSXMatch(txParser* parser, txNode* opening, txNode* closing)
4579
6.13k
{
4580
6.13k
  if (opening && closing) {
4581
6.14k
    while (opening->description->token == XS_TOKEN_MEMBER) {
4582
1.24k
      if (closing->description->token != XS_TOKEN_MEMBER)
4583
1.23k
        return 0;
4584
4
      if (((txMemberNode*)opening)->symbol != ((txMemberNode*)closing)->symbol)
4585
1
        return 0;
4586
3
      opening = ((txMemberNode*)opening)->reference;
4587
3
      closing = ((txMemberNode*)closing)->reference;
4588
3
    }
4589
4.89k
    if (opening->description->token == XS_TOKEN_ACCESS) {
4590
4.89k
      if (closing->description->token != XS_TOKEN_ACCESS)
4591
1
        return 0;
4592
4.89k
      if (((txAccessNode*)opening)->symbol != ((txAccessNode*)closing)->symbol)
4593
2.61k
        return 0;
4594
2.28k
      return 1;
4595
4.89k
    }
4596
4.89k
  }
4597
0
  return 0;
4598
6.13k
}
4599
4600
txSymbol* fxJSXNamespace(txParser* parser, txSymbol* namespace, txSymbol* name)
4601
2.80k
{
4602
2.80k
  txSize namespaceLength = namespace->length;
4603
2.80k
  txSize nameLength = name->length;
4604
2.80k
  txSize length = namespaceLength + 1 + nameLength + 1;
4605
2.80k
  txString string = fxNewParserChunk(parser, length);
4606
2.80k
  snprintf(string, length, "%s:%s", namespace->string, name->string);
4607
2.80k
  return fxNewParserSymbol(parser, string);
4608
2.80k
}