Coverage Report

Created: 2026-09-03 07:12

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-2025  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
6.90k
#define XS_TOKEN_BEGIN_STATEMENT 1
150
4.08M
#define XS_TOKEN_BEGIN_EXPRESSION 2
151
2.88M
#define XS_TOKEN_ASSIGN_EXPRESSION 4
152
2.79M
#define XS_TOKEN_EQUAL_EXPRESSION 8
153
2.85M
#define XS_TOKEN_RELATIONAL_EXPRESSION 16
154
2.88M
#define XS_TOKEN_SHIFT_EXPRESSION 32
155
15.6M
#define XS_TOKEN_ADDITIVE_EXPRESSION 64
156
15.8M
#define XS_TOKEN_MULTIPLICATIVE_EXPRESSION 128
157
15.7M
#define XS_TOKEN_EXPONENTIATION_EXPRESSION 256
158
15.9M
#define XS_TOKEN_PREFIX_EXPRESSION 512
159
14.7M
#define XS_TOKEN_POSTFIX_EXPRESSION 1024
160
533k
#define XS_TOKEN_END_STATEMENT 2048
161
#define XS_TOKEN_REFERENCE_EXPRESSION 4096
162
475k
#define XS_TOKEN_BEGIN_BINDING 16384
163
234k
#define XS_TOKEN_IDENTIFIER_NAME 32768
164
16.2M
#define XS_TOKEN_UNARY_EXPRESSION 65536
165
15.8M
#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
207k
{
519
207k
  txBoolean result = ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == keyword)) ? 1 : 0;
520
207k
  if (result) {
521
35.4k
    if (parser->states[0].escaped)
522
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
523
35.4k
  }
524
207k
  return result;
525
207k
}
526
527
txBoolean fxIsToken(txParser* parser, txToken theToken)
528
65.7k
{
529
65.7k
  txBoolean result = (parser->states[0].token == theToken) ? 1 : 0;
530
65.7k
  if (result) {
531
25.6k
    if (parser->states[0].escaped)
532
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
533
25.6k
  }
534
65.7k
  return result;
535
65.7k
}
536
537
void fxMatchToken(txParser* parser, txToken theToken)
538
4.07M
{
539
4.07M
  if (parser->states[0].token == theToken) {
540
4.02M
    if (parser->states[0].escaped)
541
0
      fxReportParserError(parser, parser->states[0].line, "escaped keyword");
542
4.02M
    fxGetNextToken(parser);
543
4.02M
  }
544
46.5k
  else
545
46.5k
    fxReportParserError(parser, parser->states[0].line, "missing %s", gxTokenNames[theToken]);
546
4.07M
}
547
548
txNode* fxPopNode(txParser* parser)
549
37.5k
{
550
37.5k
  txNode* node = parser->root;
551
37.5k
  parser->root = node->next;
552
37.5k
  node->next = NULL;
553
37.5k
  parser->nodeCount--;
554
37.5k
  return node;
555
37.5k
}
556
557
void fxPushNode(txParser* parser, txNode* node)
558
38.2M
{
559
38.2M
  node->next = parser->root;
560
38.2M
  parser->root = (txNode*)node;
561
38.2M
  parser->nodeCount++;
562
38.2M
}
563
564
void fxPushBigIntNode(txParser* parser, txBigInt* value, txInteger line)
565
63.2k
{
566
63.2k
  txBigIntNode* node = fxNewParserChunk(parser, sizeof(txBigIntNode));
567
63.2k
  node->description = &gxTokenDescriptions[XS_TOKEN_BIGINT];
568
63.2k
  node->path = parser->path;
569
63.2k
  node->line = line;
570
63.2k
  node->flags = 0;
571
63.2k
  node->value = *value;
572
63.2k
  fxPushNode(parser, (txNode*)node);
573
63.2k
}
574
575
void fxPushIndexNode(txParser* parser, txIndex value, txInteger line)
576
21.2k
{
577
21.2k
  if (((txInteger)value) >= 0)
578
21.1k
    fxPushIntegerNode(parser, (txInteger)value, line);
579
82
  else
580
82
    fxPushNumberNode(parser, value, line);
581
21.2k
}
582
583
void fxPushIntegerNode(txParser* parser, txInteger value, txInteger line)
584
13.1M
{
585
13.1M
  txIntegerNode* node = fxNewParserChunk(parser, sizeof(txIntegerNode));
586
13.1M
  node->description = &gxTokenDescriptions[XS_TOKEN_INTEGER];
587
13.1M
  node->path = parser->path;
588
13.1M
  node->line = line;
589
13.1M
  node->flags = 0;
590
13.1M
  node->value = value;
591
13.1M
  fxPushNode(parser, (txNode*)node);
592
13.1M
}
593
594
void fxPushNodeStruct(txParser* parser, txInteger count, txToken token, txInteger line)
595
19.6M
{
596
19.6M
  const txNodeDescription* description = &gxTokenDescriptions[token];
597
19.6M
  txNode* node;
598
19.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
19.6M
    node = fxNewParserChunkClear(parser, description->size);
602
19.6M
  node->description = description;
603
19.6M
  node->flags |= parser->flags & (mxStrictFlag | mxGeneratorFlag | mxAsyncFlag);
604
19.6M
  node->path = parser->path;
605
19.6M
  node->line = line;
606
19.6M
    parser->nodeCount -= count;
607
19.6M
  if (count) {
608
19.3M
    txNode** dst = (txNode**)&node[1];
609
19.3M
    txNode* src = parser->root;
610
53.9M
    while (count) {
611
34.5M
      txNode* next = src->next;
612
34.5M
      src->next = NULL;
613
34.5M
      count--;
614
34.5M
      if (src->description)
615
31.8M
        dst[count] = src;
616
2.72M
      else if (src->path)
617
2.48M
        dst[count] = (txNode*)(src->path);
618
34.5M
      src = next;
619
34.5M
    }
620
19.3M
    parser->root = src;
621
19.3M
  }
622
19.6M
  fxPushNode(parser, node);
623
19.6M
}
624
625
void fxPushNodeList(txParser* parser, txInteger count)
626
1.30M
{
627
1.30M
  txNodeList* list = fxNewParserChunk(parser, sizeof(txNodeList));
628
1.30M
  txNode* previous = NULL;
629
1.30M
  txNode* current = parser->root;
630
1.30M
  txNode* next;
631
1.30M
    parser->nodeCount -= count;
632
1.30M
  list->length = count;
633
3.06M
  while (count) {
634
1.75M
    next = current->next;
635
1.75M
    current->next = previous;
636
1.75M
    previous = current;
637
1.75M
    current = next;
638
1.75M
    count--;
639
1.75M
  }
640
1.30M
  parser->root = current;
641
1.30M
  list->description = &gxTokenDescriptions[XS_NO_TOKEN];
642
1.30M
  list->first = previous;
643
1.30M
  fxPushNode(parser, (txNode*)list);
644
1.30M
}
645
646
void fxPushNULL(txParser* parser)
647
489k
{
648
489k
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
649
489k
  fxPushNode(parser, (txNode*)node);
650
489k
}
651
652
void fxPushNumberNode(txParser* parser, txNumber value, txInteger line)
653
32.0k
{
654
32.0k
  txNumberNode* node = fxNewParserChunk(parser, sizeof(txNumberNode));
655
32.0k
  node->description = &gxTokenDescriptions[XS_TOKEN_NUMBER];
656
32.0k
  node->path = parser->path;
657
32.0k
  node->line = line;
658
32.0k
  node->flags = 0;
659
32.0k
  node->value = value;
660
32.0k
  fxPushNode(parser, (txNode*)node);
661
32.0k
}
662
663
void fxPushRawNode(txParser* parser, txInteger length, txString value, txInteger line)
664
235k
{
665
235k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
666
235k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
667
235k
  node->path = parser->path;
668
235k
  node->line = line;
669
235k
  node->flags = 0;
670
235k
  node->length = length;
671
235k
  node->value = value;
672
235k
  fxPushNode(parser, (txNode*)node);
673
235k
}
674
675
void fxPushStringNode(txParser* parser, txInteger length, txString value, txInteger line)
676
562k
{
677
562k
  txStringNode* node = fxNewParserChunk(parser, sizeof(txStringNode));
678
562k
  node->description = &gxTokenDescriptions[XS_TOKEN_STRING];
679
562k
  node->path = parser->path;
680
562k
  node->line = line;
681
562k
  node->flags = parser->states[0].escaped;
682
562k
  node->length = length;
683
562k
  node->value = value;
684
562k
  fxPushNode(parser, (txNode*)node);
685
562k
}
686
687
void fxPushSymbol(txParser* parser, txSymbol* symbol)
688
2.63M
{
689
2.63M
    txNodeLink* node = fxNewParserChunkClear(parser, sizeof(txNodeLink));
690
2.63M
  node->symbol = symbol;  
691
2.63M
  fxPushNode(parser, (txNode*)node);
692
2.63M
}
693
694
void fxSwapNodes(txParser* parser)
695
75.8k
{
696
75.8k
  txNode* previous = parser->root;
697
75.8k
  txNode* current = previous->next;
698
75.8k
  previous->next = current->next;
699
75.8k
  current->next = previous;
700
75.8k
  parser->root = current;
701
75.8k
}
702
703
void fxModule(txParser* parser)
704
17.0k
{
705
17.0k
  txInteger aCount = parser->nodeCount;
706
17.0k
  txInteger aLine = parser->states[0].line;
707
61.3k
  while ((parser->states[0].token != XS_TOKEN_EOF)) {
708
44.3k
    if (parser->states[0].token == XS_TOKEN_EXPORT)
709
12.4k
      fxExportDeclaration(parser);
710
31.8k
    else if (parser->states[0].token == XS_TOKEN_IMPORT) {
711
2.27k
      fxLookAheadOnce(parser);
712
2.27k
      if ((parser->states[1].token == XS_TOKEN_DOT) || (parser->states[1].token == XS_TOKEN_LEFT_PARENTHESIS))
713
99
        fxStatement(parser, 1);
714
2.17k
      else
715
2.17k
        fxImportDeclaration(parser);
716
2.27k
    }
717
29.6k
    else if (parser->states[0].token == XS_TOKEN_RETURN) {
718
729
      fxReportParserError(parser, parser->states[0].line, "invalid return");
719
729
      fxGetNextToken(parser);
720
729
    }
721
28.8k
    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
28.8k
    else {
726
28.8k
      fxStatement(parser, 1);
727
28.8k
    }
728
44.3k
  }
729
17.0k
  aCount = parser->nodeCount - aCount;
730
17.0k
  if (aCount > 1) {
731
3.33k
    fxPushNodeList(parser, aCount);
732
3.33k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
733
3.33k
  }
734
13.7k
  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
17.0k
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, aLine);
739
17.0k
  parser->root->flags = parser->flags & (mxStrictFlag | mxAwaitingFlag);
740
17.0k
}
741
742
void fxExportDeclaration(txParser* parser)
743
12.4k
{
744
12.4k
  txSymbol* symbol = C_NULL;
745
12.4k
  txInteger count;
746
12.4k
  txInteger line = parser->states[0].line;
747
12.4k
  txUnsigned flag = 0;
748
12.4k
  txToken aToken;
749
12.4k
  fxMatchToken(parser, XS_TOKEN_EXPORT);
750
12.4k
  switch (parser->states[0].token) {
751
3.14k
  case XS_TOKEN_MULTIPLY:
752
3.14k
    fxPushNULL(parser);
753
3.14k
    fxGetNextToken(parser);
754
3.14k
    if (fxIsKeyword(parser, parser->asSymbol)) {
755
24
      fxGetNextToken(parser);
756
24
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
757
23
        fxPushSymbol(parser, parser->states[0].symbol);
758
23
        fxGetNextToken(parser);
759
23
      }
760
1
      else {
761
1
        fxPushNULL(parser);
762
1
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
763
1
      }
764
24
    }
765
3.12k
    else {
766
3.12k
      fxPushNULL(parser);
767
3.12k
    }
768
3.14k
    if (fxIsKeyword(parser, parser->fromSymbol)) {
769
1.76k
      fxGetNextToken(parser);
770
1.76k
      if (parser->states[0].token == XS_TOKEN_STRING) {
771
1.76k
        fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
772
1.76k
        fxPushNodeList(parser, 1);
773
1.76k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
774
1.76k
        fxGetNextToken(parser);
775
1.76k
        if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
776
1
          fxGetNextToken(parser);
777
1
          fxWithAttributes(parser);
778
1
        }
779
1.76k
        else
780
1.76k
          fxPushNULL(parser);
781
1.76k
        fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
782
1.76k
        fxSemicolon(parser);
783
1.76k
      }
784
2
      else
785
2
        fxReportParserError(parser, parser->states[0].line, "missing module");
786
1.76k
    }
787
1.38k
    else
788
1.38k
      fxReportParserError(parser, parser->states[0].line, "missing from");
789
3.14k
    break;
790
207
  case XS_TOKEN_DEFAULT:
791
207
    fxMatchToken(parser, XS_TOKEN_DEFAULT);
792
207
    if (parser->flags & mxDefaultFlag)
793
2
      fxReportParserError(parser, parser->states[0].line, "invalid default");
794
207
    parser->flags |= mxDefaultFlag;
795
207
    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
207
    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
207
    else {
826
207
      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
207
      fxAssignmentExpression(parser);
835
207
      fxSemicolon(parser);
836
207
      fxPushSymbol(parser, parser->defaultSymbol);
837
207
      fxPushNULL(parser);
838
207
      fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, line);
839
207
      fxSwapNodes(parser);
840
207
      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, line);
841
207
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
842
207
    }
843
207
    if (symbol) {
844
0
      fxPushSymbol(parser, symbol);
845
0
      fxPushSymbol(parser, parser->defaultSymbol);
846
0
    }
847
207
    else {
848
207
      fxPushSymbol(parser, parser->defaultSymbol);
849
207
      fxPushNULL(parser);
850
207
    }
851
207
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, line);
852
207
    fxPushNodeList(parser, 1);
853
207
    fxPushNULL(parser);
854
207
    fxPushNULL(parser);
855
207
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
856
207
    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
4
  case XS_TOKEN_FUNCTION:
877
4
  again2:
878
4
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
879
4
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
880
1
      fxGetNextToken(parser);
881
1
      fxGeneratorExpression(parser, line, &symbol, flag);
882
1
    }
883
3
    else
884
3
      fxFunctionExpression(parser, line, &symbol, flag);
885
4
    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
4
    else
898
4
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
899
4
    break;
900
109
  case XS_TOKEN_CONST:
901
214
  case XS_TOKEN_LET:
902
265
  case XS_TOKEN_VAR:
903
265
    aToken = parser->states[0].token;
904
265
    fxVariableStatement(parser, aToken, 0);
905
265
    count = parser->nodeCount;
906
265
    fxExportBinding(parser, parser->root);
907
265
    fxPushNodeList(parser, parser->nodeCount - count);
908
265
    fxPushNULL(parser);
909
265
    fxPushNULL(parser);
910
265
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
911
265
    fxSemicolon(parser);
912
265
    break;
913
5.27k
  case XS_TOKEN_LEFT_BRACE:
914
5.27k
    count = parser->nodeCount;
915
5.27k
    fxSpecifiers(parser);
916
5.27k
    fxPushNodeList(parser, parser->nodeCount - count);
917
5.27k
    if (fxIsKeyword(parser, parser->fromSymbol)) {
918
58
      fxGetNextToken(parser);
919
58
      if (parser->states[0].token == XS_TOKEN_STRING) {
920
57
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
921
57
        fxGetNextToken(parser);
922
57
      }
923
1
      else {
924
1
        fxPushNULL(parser);
925
1
        fxReportParserError(parser, parser->states[0].line, "missing module");
926
1
      }
927
58
      if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
928
0
        fxGetNextToken(parser);
929
0
        fxWithAttributes(parser);
930
0
      }
931
58
      else
932
58
        fxPushNULL(parser);
933
58
    }
934
5.22k
    else {
935
5.22k
      fxPushNULL(parser);
936
5.22k
      fxPushNULL(parser);
937
5.22k
    }
938
5.27k
    fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, line);
939
5.27k
    fxSemicolon(parser);
940
5.27k
    break;
941
3.52k
  default:
942
3.52k
    if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped)) {
943
1
      fxLookAheadOnce(parser);
944
1
      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
1
    }
950
3.52k
    fxReportParserError(parser, parser->states[0].line, "invalid export %s", gxTokenNames[parser->states[0].token]);
951
3.52k
    fxGetNextToken(parser);
952
3.52k
    break;
953
12.4k
  }
954
12.4k
}
955
956
void fxExportBinding(txParser* parser, txNode* node)
957
516
{
958
516
  txToken token = node->description->token;
959
516
  if ((token == XS_TOKEN_CONST) || (token == XS_TOKEN_LET) || (token == XS_TOKEN_VAR)) {
960
288
    fxPushSymbol(parser, ((txDeclareNode*)node)->symbol);
961
288
    fxPushNULL(parser);
962
288
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, node->line);
963
288
  }
964
228
  else if (token == XS_TOKEN_BINDING) {
965
202
    fxExportBinding(parser, ((txBindingNode*)node)->target);
966
202
  }
967
26
  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
26
  else if (token == XS_TOKEN_OBJECT_BINDING) {
975
6
    node = ((txObjectBindingNode*)node)->items->first;
976
13
    while (node) {
977
7
      fxExportBinding(parser, node);
978
7
      node = node->next;
979
7
    }
980
6
  }
981
20
  else if (token == XS_TOKEN_PROPERTY_BINDING)
982
7
    fxExportBinding(parser, ((txPropertyBindingNode*)node)->binding);
983
13
  else if (token == XS_TOKEN_PROPERTY_BINDING_AT)
984
0
    fxExportBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
985
13
  else if (token == XS_TOKEN_REST_BINDING)
986
0
    fxExportBinding(parser, ((txRestBindingNode*)node)->binding);
987
13
  else if (token == XS_TOKEN_STATEMENTS) {
988
13
    node = ((txStatementsNode*)node)->items->first;
989
49
    while (node) {
990
36
      fxExportBinding(parser, node);
991
36
      node = node->next;
992
36
    }
993
13
  }
994
516
}
995
996
997
void fxImportDeclaration(txParser* parser)
998
2.17k
{
999
2.17k
  txBoolean asFlag = 1;
1000
2.17k
  txBoolean fromFlag = 0;
1001
2.17k
  txInteger count = parser->nodeCount;
1002
2.17k
  fxMatchToken(parser, XS_TOKEN_IMPORT);
1003
2.17k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1004
94
    fxPushSymbol(parser, parser->defaultSymbol);
1005
94
    fxPushSymbol(parser, parser->states[0].symbol);
1006
94
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1007
94
    fxGetNextToken(parser);
1008
94
    if (parser->states[0].token == XS_TOKEN_COMMA)
1009
1
      fxGetNextToken(parser);
1010
93
    else
1011
93
      asFlag = 0;
1012
94
    fromFlag = 1;
1013
94
  }
1014
2.17k
  if (asFlag) {
1015
2.08k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1016
1.95k
      fxGetNextToken(parser);
1017
1.95k
      if (fxIsKeyword(parser, parser->asSymbol)) {
1018
641
        fxGetNextToken(parser);
1019
641
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
1020
63
          fxPushNULL(parser);
1021
63
          fxPushSymbol(parser, parser->states[0].symbol);
1022
63
          fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1023
63
          fxGetNextToken(parser);
1024
63
        }
1025
578
        else {
1026
578
          fxReportParserError(parser, parser->states[0].line, "missing identifier");
1027
578
        }
1028
641
      }
1029
1.30k
      else {
1030
1.30k
        fxReportParserError(parser, parser->states[0].line, "missing as");
1031
1.30k
      }
1032
1.95k
      fromFlag = 1;
1033
1.95k
    }
1034
134
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
1035
44
      fxSpecifiers(parser);
1036
44
      fromFlag = 1;
1037
44
    }
1038
2.08k
  }
1039
2.17k
  fxPushNodeList(parser, parser->nodeCount - count);
1040
2.17k
  if (fromFlag) {
1041
198
    if (fxIsKeyword(parser, parser->fromSymbol)) {
1042
195
      fxGetNextToken(parser);
1043
195
      if (parser->states[0].token == XS_TOKEN_STRING) {
1044
193
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1045
193
        fxGetNextToken(parser);
1046
193
      }
1047
2
      else {
1048
2
        fxPushNULL(parser);
1049
2
        fxReportParserError(parser, parser->states[0].line, "missing module");
1050
2
      }
1051
195
    }
1052
3
    else {
1053
3
      fxPushNULL(parser);
1054
3
      fxReportParserError(parser, parser->states[0].line, "missing from");
1055
3
    }
1056
198
  }
1057
1.97k
  else if (parser->states[0].token == XS_TOKEN_STRING) {
1058
87
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
1059
87
    fxGetNextToken(parser);
1060
87
  }
1061
1.89k
  else {
1062
1.89k
    fxPushNULL(parser);
1063
1.89k
    fxReportParserError(parser, parser->states[0].line, "missing module");
1064
1.89k
  }
1065
2.17k
  if (!parser->states[0].crlf && (parser->states[0].token == XS_TOKEN_WITH)) {
1066
0
    fxGetNextToken(parser);
1067
0
    fxWithAttributes(parser);
1068
0
  }
1069
2.17k
  else
1070
2.17k
    fxPushNULL(parser);
1071
2.17k
  fxPushNodeStruct(parser, 3, XS_TOKEN_IMPORT, parser->states[0].line);
1072
2.17k
  fxSemicolon(parser);
1073
2.17k
}
1074
1075
void fxSpecifiers(txParser* parser)
1076
5.32k
{
1077
//  txInteger aCount = 0;
1078
5.32k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1079
8.64k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1080
5.29k
    fxPushSymbol(parser, parser->states[0].symbol);
1081
5.29k
    fxGetNextToken(parser);
1082
5.29k
    if (fxIsKeyword(parser, parser->asSymbol)) {
1083
4.67k
      fxGetNextToken(parser);
1084
4.67k
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
1085
3.11k
        fxPushSymbol(parser, parser->states[0].symbol);
1086
3.11k
        fxGetNextToken(parser);
1087
3.11k
      }
1088
1.55k
      else {
1089
1.55k
        fxPushNULL(parser);
1090
1.55k
        fxReportParserError(parser, parser->states[0].line, "missing identifier");
1091
1.55k
      }
1092
4.67k
    }
1093
621
    else
1094
621
      fxPushNULL(parser);
1095
5.29k
    fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, parser->states[0].line);
1096
//    aCount++;
1097
5.29k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
1098
1.97k
      break;
1099
3.31k
    fxGetNextToken(parser);
1100
3.31k
  }
1101
5.32k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1102
5.32k
}
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
515k
{
1151
515k
  txInteger count = parser->nodeCount;
1152
515k
  txInteger line = parser->states[0].line;
1153
515k
  txNode* node;
1154
725k
  while (parser->states[0].token != XS_TOKEN_EOF) {
1155
522k
    fxStatement(parser, -1);
1156
522k
    node = parser->root;
1157
522k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1158
62.0k
      break;
1159
460k
    node = ((txStatementNode*)node)->expression;
1160
460k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1161
250k
      break;
1162
210k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1163
10.5k
      if (!(parser->flags & mxStrictFlag)) {
1164
7.52k
        parser->flags |= mxStrictFlag;
1165
7.52k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1166
5.41k
          fxCheckStrictKeyword(parser);
1167
7.52k
      }
1168
10.5k
    }
1169
210k
  }
1170
1.02M
  while (parser->states[0].token != XS_TOKEN_EOF) {
1171
511k
    fxStatement(parser, -1);
1172
511k
  }
1173
515k
  count = parser->nodeCount - count;
1174
515k
  if (count > 1) {
1175
38.3k
    fxPushNodeList(parser, count);
1176
38.3k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1177
38.3k
  }
1178
476k
  else if (count == 0) {
1179
8.43k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1180
8.43k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1181
8.43k
  }
1182
515k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PROGRAM, line);
1183
515k
  if (parser->flags & mxFieldFlag)
1184
0
    if (parser->flags & mxArgumentsFlag)
1185
0
      fxReportParserError(parser, parser->states[0].line, "invalid arguments");
1186
515k
  parser->root->flags = parser->flags & mxStrictFlag;
1187
515k
}
1188
1189
void fxBody(txParser* parser)
1190
265k
{
1191
265k
  txInteger count = parser->nodeCount;
1192
265k
  txInteger line = parser->states[0].line;
1193
265k
  txNode* node;
1194
265k
    fxCheckParserStack(parser, line);
1195
340k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1196
227k
    fxStatement(parser, 1);
1197
227k
    node = parser->root;
1198
227k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STATEMENT))
1199
32.7k
      break;
1200
195k
    node = ((txStatementNode*)node)->expression;
1201
195k
    if (!node || !node->description || (node->description->token != XS_TOKEN_STRING))
1202
120k
      break;
1203
74.7k
    if (!(node->flags & mxStringEscapeFlag) && (c_strcmp(((txStringNode*)node)->value, "use strict") == 0)) {
1204
3.26k
      if (parser->flags & mxNotSimpleParametersFlag)
1205
1
        fxReportParserError(parser, parser->states[0].line, "invalid directive");
1206
3.26k
      if (!(parser->flags & mxStrictFlag)) {
1207
2.99k
        parser->flags |= mxStrictFlag;
1208
2.99k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
1209
1.89k
          fxCheckStrictKeyword(parser);
1210
2.99k
      }
1211
3.26k
    }
1212
74.7k
  }
1213
475k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1214
209k
    fxStatement(parser, 1);
1215
209k
  }
1216
265k
  count = parser->nodeCount - count;
1217
265k
  if (count > 1) {
1218
23.0k
    fxPushNodeList(parser, count);
1219
23.0k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1220
23.0k
  }
1221
242k
  else if (count == 0) {
1222
41.7k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1223
41.7k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1224
41.7k
  }
1225
265k
}
1226
1227
void fxBlock(txParser* parser)
1228
96.5k
{
1229
96.5k
  txInteger aLine = parser->states[0].line;
1230
96.5k
  fxCheckParserStack(parser, aLine);
1231
96.5k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1232
96.5k
  fxStatements(parser);
1233
96.5k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1234
96.5k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BLOCK, aLine);
1235
96.5k
}
1236
1237
void fxStatements(txParser* parser)
1238
161k
{
1239
161k
  txInteger count = parser->nodeCount;
1240
161k
  txInteger line = parser->states[0].line;
1241
329k
  while ((parser->states[0].token != XS_TOKEN_EOF) && (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)) {
1242
168k
    fxStatement(parser, 1);
1243
168k
  }
1244
161k
  count = parser->nodeCount - count;
1245
161k
  fxPushNodeList(parser, count);
1246
161k
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, line);
1247
161k
}
1248
1249
void fxStatement(txParser* parser, txInteger blockIt)
1250
1.82M
{
1251
1.82M
  txInteger line = parser->states[0].line;
1252
1.82M
  txSymbol* symbol = C_NULL;
1253
1.82M
  txUnsigned flag = 0;
1254
1.82M
  switch (parser->states[0].token) {
1255
//  case XS_TOKEN_COMMA:
1256
63.1k
  case XS_TOKEN_SEMICOLON:
1257
63.1k
    fxGetNextToken(parser);
1258
63.1k
    if (!blockIt) {
1259
409
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
1260
409
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1261
409
    }
1262
63.1k
    break;
1263
4.10k
  case XS_TOKEN_BREAK:
1264
4.10k
    fxBreakStatement(parser);
1265
4.10k
    fxSemicolon(parser);
1266
4.10k
    break;
1267
71.4k
  case XS_TOKEN_CLASS:
1268
71.4k
    if (!blockIt)
1269
1.43k
      fxReportParserError(parser, parser->states[0].line, "no block");
1270
71.4k
    fxClassExpression(parser, line, &symbol);
1271
71.4k
    if (symbol) {
1272
3.96k
      fxPushSymbol(parser, symbol);
1273
3.96k
      fxPushNodeStruct(parser, 1, XS_TOKEN_LET, line);
1274
3.96k
      fxSwapNodes(parser);
1275
3.96k
      fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, line);
1276
3.96k
    }
1277
67.4k
    else
1278
67.4k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1279
71.4k
    break;
1280
19.7k
  case XS_TOKEN_CONST:
1281
19.7k
    if (!blockIt)
1282
509
      fxReportParserError(parser, parser->states[0].line, "no block");
1283
19.7k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1284
19.7k
    fxSemicolon(parser);
1285
19.7k
    break;
1286
5.51k
  case XS_TOKEN_CONTINUE:
1287
5.51k
    fxContinueStatement(parser);
1288
5.51k
    fxSemicolon(parser);
1289
5.51k
    break;
1290
1.77k
  case XS_TOKEN_DEBUGGER:
1291
1.77k
    fxDebuggerStatement(parser);
1292
1.77k
    fxSemicolon(parser);
1293
1.77k
    break;
1294
28.0k
  case XS_TOKEN_DO:
1295
28.0k
    fxDoStatement(parser);
1296
28.0k
    break;
1297
54.3k
  case XS_TOKEN_FOR:
1298
54.3k
    fxForStatement(parser);
1299
54.3k
    break;
1300
16.9k
  case XS_TOKEN_FUNCTION:
1301
    //if ((parser->flags & mxStrictFlag) && !blockIt) BROWSER
1302
17.7k
  again:
1303
17.7k
    if (!blockIt)
1304
37
      fxReportParserError(parser, parser->states[0].line, "no block (strict code)");
1305
17.7k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
1306
17.7k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
1307
12.2k
      fxGetNextToken(parser);
1308
12.2k
      fxGeneratorExpression(parser, line, &symbol, flag);
1309
12.2k
    }
1310
5.51k
    else
1311
5.51k
      fxFunctionExpression(parser, line, &symbol, flag);
1312
17.7k
    if (symbol) {
1313
11.0k
      txDefineNode* node = fxDefineNodeNew(parser, XS_TOKEN_DEFINE, symbol);
1314
11.0k
      node->initializer = fxPopNode(parser);
1315
11.0k
      fxPushNode(parser, (txNode*)node);
1316
11.0k
    }
1317
6.77k
    else
1318
6.77k
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
1319
17.7k
    break;
1320
5.86k
  case XS_TOKEN_IF:
1321
5.86k
    fxIfStatement(parser);
1322
5.86k
    break;
1323
12.0k
  case XS_TOKEN_RETURN:
1324
12.0k
    if (!(parser->flags & (mxArrowFlag | mxFunctionFlag | mxGeneratorFlag)))
1325
1.08k
      fxReportParserError(parser, parser->states[0].line, "invalid return");
1326
12.0k
    fxReturnStatement(parser);
1327
12.0k
    fxSemicolon(parser);
1328
12.0k
    break;
1329
88.0k
  case XS_TOKEN_LEFT_BRACE:
1330
88.0k
    fxBlock(parser);
1331
88.0k
    break;
1332
4.67k
  case XS_TOKEN_LET:
1333
4.67k
    if (!blockIt)
1334
14
      fxReportParserError(parser, parser->states[0].line, "no block");
1335
4.67k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1336
4.67k
    fxSemicolon(parser);
1337
4.67k
    break;
1338
4.18k
  case XS_TOKEN_SWITCH:
1339
4.18k
    fxSwitchStatement(parser);
1340
4.18k
    break;
1341
26.5k
  case XS_TOKEN_THROW:
1342
26.5k
    fxThrowStatement(parser);
1343
26.5k
    fxSemicolon(parser);
1344
26.5k
    break;
1345
8.43k
  case XS_TOKEN_TRY:
1346
8.43k
    fxTryStatement(parser);
1347
8.43k
    break;
1348
79.2k
  case XS_TOKEN_VAR:
1349
79.2k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1350
79.2k
    fxSemicolon(parser);
1351
79.2k
    break;
1352
540
  case XS_TOKEN_WHILE:
1353
540
    fxWhileStatement(parser);
1354
540
    break;
1355
5.39k
  case XS_TOKEN_WITH:
1356
5.39k
    if (parser->flags & mxStrictFlag)
1357
105
      fxReportParserError(parser, parser->states[0].line, "with (strict code)");
1358
5.39k
    fxWithStatement(parser);
1359
5.39k
    break;
1360
0
#if mxExplicitResourceManagement
1361
867
  case XS_TOKEN_AWAIT:
1362
867
    fxLookAheadOnce(parser);
1363
867
    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
867
    fxCommaExpression(parser);
1377
867
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1378
867
    fxSemicolon(parser);
1379
867
    break;
1380
0
#endif
1381
856k
  case XS_TOKEN_IDENTIFIER:
1382
856k
    fxLookAheadOnce(parser);
1383
856k
    if (parser->states[1].token == XS_TOKEN_COLON) {
1384
81.5k
      fxPushSymbol(parser, parser->states[0].symbol);
1385
81.5k
      fxGetNextToken(parser);
1386
81.5k
      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
81.5k
      if (parser->states[0].token == XS_TOKEN_FUNCTION)
1390
29
        fxReportParserError(parser, parser->states[0].line, "labeled function");
1391
81.5k
      fxCheckParserStack(parser, line);
1392
81.5k
      fxStatement(parser, 0);
1393
81.5k
      fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, line);
1394
81.5k
      break;
1395
81.5k
    }
1396
775k
    if ((parser->states[0].symbol == parser->asyncSymbol) && (!parser->states[0].escaped) 
1397
1.36k
        && (!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_FUNCTION)) {
1398
807
      fxGetNextToken(parser);
1399
807
      flag = mxAsyncFlag;
1400
807
      goto again;
1401
807
    }
1402
774k
    if ((parser->states[0].symbol == parser->letSymbol) && (!parser->states[0].escaped) 
1403
28.8k
        && ((gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING) || (parser->states[1].token == XS_TOKEN_AWAIT) || (parser->states[1].token == XS_TOKEN_YIELD))
1404
26.1k
        && (blockIt || (!parser->states[1].crlf) || (parser->states[1].token == XS_TOKEN_LEFT_BRACKET))) {
1405
26.0k
      parser->states[0].token = XS_TOKEN_LET;
1406
26.0k
      if (!blockIt)
1407
1.79k
        fxReportParserError(parser, parser->states[0].line, "no block");
1408
26.0k
      fxVariableStatement(parser, XS_TOKEN_LET, 0);
1409
26.0k
      fxSemicolon(parser);
1410
26.0k
      break;
1411
26.0k
    }
1412
748k
#if mxExplicitResourceManagement
1413
748k
    if ((parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1414
7.69k
        && (!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
3.08k
      parser->states[0].token = XS_TOKEN_USING;
1416
3.08k
      if (blockIt <= 0)
1417
2.67k
        fxReportParserError(parser, parser->states[0].line, "no block");
1418
3.08k
      fxVariableStatement(parser, XS_TOKEN_USING, 0);
1419
3.08k
      fxSemicolon(parser);
1420
3.08k
      break;
1421
3.08k
    }
1422
745k
#endif
1423
    /* continue */
1424
745k
    mxFallThrough;
1425
1.21M
  default:
1426
1.21M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1427
1.16M
      fxCommaExpression(parser);
1428
1.16M
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, line);
1429
1.16M
      fxSemicolon(parser);
1430
1.16M
    }
1431
50.3k
    else {
1432
50.3k
      fxReportParserError(parser, parser->states[0].line, "invalid token %s", gxTokenNames[parser->states[0].token]);
1433
50.3k
      fxPushNULL(parser);
1434
50.3k
      fxGetNextToken(parser);
1435
50.3k
    }
1436
1.21M
    break;
1437
1.82M
  }
1438
1.82M
}
1439
1440
void fxSemicolon(txParser* parser)
1441
1.05M
{
1442
1.05M
  if ((parser->states[0].crlf) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_END_STATEMENT)) {
1443
1.01M
    if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1444
325k
      fxGetNextToken(parser);
1445
1.01M
  }
1446
38.1k
  else
1447
38.1k
    fxReportParserError(parser, parser->states[0].line, "missing ;");
1448
1.05M
}
1449
1450
void fxBreakStatement(txParser* parser)
1451
4.10k
{
1452
4.10k
  txInteger aLine = parser->states[0].line;
1453
4.10k
  fxMatchToken(parser, XS_TOKEN_BREAK);
1454
4.10k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1455
404
    fxPushSymbol(parser, parser->states[0].symbol);
1456
404
    fxGetNextToken(parser);
1457
404
  }
1458
3.70k
  else {
1459
3.70k
    fxPushNULL(parser);
1460
3.70k
  }
1461
4.10k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BREAK, aLine);
1462
4.10k
}
1463
1464
void fxContinueStatement(txParser* parser)
1465
5.51k
{
1466
5.51k
  txInteger aLine = parser->states[0].line;
1467
5.51k
  fxMatchToken(parser, XS_TOKEN_CONTINUE);
1468
5.51k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_IDENTIFIER)) {
1469
711
    fxPushSymbol(parser, parser->states[0].symbol);
1470
711
    fxGetNextToken(parser);
1471
711
  }
1472
4.80k
  else {
1473
4.80k
    fxPushNULL(parser);
1474
4.80k
  }
1475
5.51k
  fxPushNodeStruct(parser, 1, XS_TOKEN_CONTINUE, aLine);
1476
5.51k
}
1477
1478
void fxDebuggerStatement(txParser* parser)
1479
1.77k
{
1480
1.77k
  txInteger aLine = parser->states[0].line;
1481
1.77k
  fxMatchToken(parser, XS_TOKEN_DEBUGGER);
1482
1.77k
  fxPushNodeStruct(parser, 0, XS_TOKEN_DEBUGGER, aLine);
1483
1.77k
}
1484
1485
void fxDoStatement(txParser* parser)
1486
28.0k
{
1487
28.0k
  txInteger aLine = parser->states[0].line;
1488
28.0k
  fxCheckParserStack(parser, aLine);
1489
28.0k
  fxPushNULL(parser);
1490
28.0k
  fxMatchToken(parser, XS_TOKEN_DO);
1491
28.0k
  fxStatement(parser, 0);
1492
28.0k
  fxMatchToken(parser, XS_TOKEN_WHILE);
1493
28.0k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1494
28.0k
  fxCommaExpression(parser);
1495
28.0k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1496
28.0k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON)
1497
194
    fxGetNextToken(parser);
1498
28.0k
  fxPushNodeStruct(parser, 2, XS_TOKEN_DO, aLine);
1499
28.0k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1500
28.0k
}
1501
1502
void fxForStatement(txParser* parser)
1503
54.3k
{
1504
54.3k
  txInteger aLine = parser->states[0].line;
1505
54.3k
  txBoolean awaitFlag = 0;
1506
54.3k
  txBoolean expressionFlag = 0;
1507
54.3k
  txToken aToken;
1508
54.3k
  fxPushNULL(parser);
1509
54.3k
  fxMatchToken(parser, XS_TOKEN_FOR);
1510
54.3k
  if (parser->states[0].token == XS_TOKEN_AWAIT) {
1511
11
    awaitFlag = 1;
1512
11
    fxMatchToken(parser, XS_TOKEN_AWAIT);
1513
11
  }
1514
54.3k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1515
54.3k
  fxLookAheadOnce(parser);
1516
54.3k
  parser->flags |= mxForFlag;
1517
54.3k
  if (parser->states[0].token == XS_TOKEN_SEMICOLON) {
1518
507
    fxPushNULL(parser);
1519
507
  }
1520
53.8k
  else if (parser->states[0].token == XS_TOKEN_CONST) {
1521
1.76k
    fxVariableStatement(parser, XS_TOKEN_CONST, 0);
1522
1.76k
  }
1523
52.1k
  else if (parser->states[0].token == XS_TOKEN_LET) {
1524
927
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1525
927
  }
1526
51.1k
  else if (fxIsKeyword(parser, parser->letSymbol) && (gxTokenFlags[parser->states[1].token] & XS_TOKEN_BEGIN_BINDING)) {
1527
10.4k
    parser->states[0].token = XS_TOKEN_LET;
1528
10.4k
    fxVariableStatement(parser, XS_TOKEN_LET, 0);
1529
10.4k
  }
1530
40.7k
#if mxExplicitResourceManagement
1531
40.7k
  else if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->usingSymbol) && (!parser->states[0].escaped)
1532
7
        && (!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))) {
1533
5
    fxLookAheadTwice(parser);
1534
5
    if ((parser->states[1].symbol == parser->ofSymbol) && (!parser->states[1].escaped) && (parser->states[2].token != XS_TOKEN_ASSIGN)) {
1535
0
      fxCommaExpression(parser);
1536
0
      expressionFlag = 1;
1537
0
    }
1538
5
    else {
1539
5
      parser->states[0].token = XS_TOKEN_USING;
1540
5
      fxVariableStatement(parser, XS_TOKEN_USING, 0);
1541
5
    }
1542
5
  }
1543
40.7k
  else if ((parser->states[0].token == XS_TOKEN_AWAIT)
1544
95
        && (!parser->states[1].crlf) && (parser->states[1].token == XS_TOKEN_IDENTIFIER) && (parser->states[1].symbol == parser->usingSymbol) && (!parser->states[1].escaped)) {
1545
0
    fxLookAheadTwice(parser);
1546
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))) {
1547
0
      fxGetNextToken(parser);
1548
0
      parser->states[0].token = XS_TOKEN_USING;
1549
0
      fxVariableStatement(parser, XS_TOKEN_USING, mxAwaitingFlag);
1550
0
      parser->flags |= mxAwaitingFlag;
1551
0
    }
1552
0
    else {
1553
0
      fxCommaExpression(parser);
1554
0
      expressionFlag = 1;
1555
0
    }
1556
0
  }
1557
40.7k
#endif
1558
40.7k
  else if (parser->states[0].token == XS_TOKEN_VAR) {
1559
17.1k
    fxVariableStatement(parser, XS_TOKEN_VAR, 0);
1560
17.1k
  }
1561
23.5k
  else {
1562
23.5k
    fxCommaExpression(parser);
1563
23.5k
    expressionFlag = 1;
1564
23.5k
  }
1565
54.3k
  parser->flags &= ~mxForFlag;
1566
54.3k
  if (awaitFlag && !fxIsKeyword(parser, parser->ofSymbol))
1567
1
    fxReportParserError(parser, parser->states[0].line, "invalid for await");
1568
54.3k
  if (fxIsToken(parser, XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)) {
1569
22.0k
    if (expressionFlag) {
1570
960
      if (!fxCheckReference(parser, XS_TOKEN_ASSIGN)) {
1571
2
        fxReportParserError(parser, parser->states[0].line, "no reference");
1572
2
      }
1573
960
    }
1574
21.1k
    else {
1575
21.1k
      aToken = parser->root->description->token;
1576
21.1k
      if (aToken == XS_TOKEN_BINDING) {
1577
0
        if (((txBindingNode*)(parser->root))->initializer)
1578
0
          fxReportParserError(parser, parser->states[0].line, "invalid binding initializer");
1579
0
      }
1580
21.1k
      if (fxIsToken(parser, XS_TOKEN_IN) && (aToken == XS_TOKEN_USING))
1581
1
        fxReportParserError(parser, parser->states[0].line, "invalid using in");
1582
      
1583
//      else if (aToken == XS_TOKEN_ARRAY_BINDING) {
1584
//        if (((txArrayBindingNode*)(parser->root))->initializer)
1585
//          fxReportParserError(parser, parser->states[0].line, "invalid array binding initializer");
1586
//      }
1587
//      else if (aToken == XS_TOKEN_OBJECT_BINDING) {
1588
//        if (((txObjectBindingNode*)(parser->root))->initializer)
1589
//          fxReportParserError(parser, parser->states[0].line, "invalid object binding initializer");
1590
//      }
1591
//      else
1592
//        fxReportParserError(parser, parser->states[0].line, "no reference %s", gxTokenNames[aToken]);
1593
21.1k
    }
1594
22.0k
    aToken = parser->states[0].token;
1595
22.0k
    fxGetNextToken(parser);
1596
22.0k
    if (aToken == XS_TOKEN_IN)
1597
13.1k
      fxCommaExpression(parser);
1598
8.95k
    else
1599
8.95k
      fxAssignmentExpression(parser);
1600
22.0k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1601
22.0k
    fxStatement(parser, 0);
1602
22.0k
    if (awaitFlag) {
1603
10
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_AWAIT_OF, aLine);
1604
10
      parser->flags |= mxAwaitingFlag;
1605
10
    }
1606
22.0k
    else if (aToken == XS_TOKEN_IN)
1607
12.9k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_IN, aLine);
1608
9.12k
    else
1609
9.12k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_OF, aLine);
1610
22.0k
  }
1611
32.2k
  else {
1612
32.2k
    if (expressionFlag)
1613
19.5k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1614
32.2k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1615
32.2k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1616
20.2k
      fxCommaExpression(parser);
1617
20.2k
    }
1618
12.0k
    else {
1619
12.0k
      fxPushNULL(parser);
1620
12.0k
    }
1621
32.2k
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1622
32.2k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1623
20.0k
      fxCommaExpression(parser);
1624
20.0k
    }
1625
12.2k
    else {
1626
12.2k
      fxPushNULL(parser);
1627
12.2k
    }
1628
32.2k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1629
32.2k
    fxCheckParserStack(parser, aLine);
1630
32.2k
    fxStatement(parser, 0);
1631
32.2k
    fxPushNodeStruct(parser, 4, XS_TOKEN_FOR, aLine);
1632
32.2k
  }
1633
54.3k
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1634
54.3k
}
1635
1636
void fxIfStatement(txParser* parser)
1637
5.86k
{
1638
5.86k
  txInteger aLine = parser->states[0].line;
1639
5.86k
  fxMatchToken(parser, XS_TOKEN_IF);
1640
5.86k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1641
5.86k
  fxCommaExpression(parser);
1642
5.86k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1643
5.86k
  fxStatement(parser, 0);
1644
5.86k
  if (parser->states[0].token == XS_TOKEN_ELSE) {
1645
764
    fxMatchToken(parser, XS_TOKEN_ELSE);
1646
764
    fxStatement(parser, 0);
1647
764
  }
1648
5.10k
  else {
1649
5.10k
    fxPushNULL(parser);
1650
5.10k
  }
1651
5.86k
  fxPushNodeStruct(parser, 3, XS_TOKEN_IF, aLine);
1652
5.86k
}
1653
1654
void fxReturnStatement(txParser* parser)
1655
10.9k
{
1656
10.9k
  txInteger aLine = parser->states[0].line;
1657
10.9k
  fxMatchToken(parser, XS_TOKEN_RETURN);
1658
10.9k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1659
9.14k
    fxCommaExpression(parser);
1660
9.14k
  }
1661
1.79k
  else {
1662
1.79k
    fxPushNULL(parser);
1663
1.79k
  }
1664
10.9k
  fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
1665
10.9k
}
1666
1667
void fxSwitchStatement(txParser* parser)
1668
4.18k
{
1669
4.18k
  txInteger aCount = 0;
1670
4.18k
  txBoolean aDefaultFlag = 0;
1671
4.18k
  txInteger aLine = parser->states[0].line;
1672
4.18k
  fxMatchToken(parser, XS_TOKEN_SWITCH);
1673
4.18k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1674
4.18k
  fxCommaExpression(parser);
1675
4.18k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1676
4.18k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1677
7.91k
  while ((parser->states[0].token == XS_TOKEN_CASE) || (parser->states[0].token == XS_TOKEN_DEFAULT)) {
1678
3.73k
    txInteger aCaseCount;
1679
3.73k
    txInteger aCaseLine = parser->states[0].line;
1680
3.73k
    if (parser->states[0].token == XS_TOKEN_CASE) {
1681
3.18k
      fxMatchToken(parser, XS_TOKEN_CASE);
1682
3.18k
      fxCommaExpression(parser);
1683
3.18k
      fxMatchToken(parser, XS_TOKEN_COLON);
1684
3.18k
      aCaseCount = parser->nodeCount;
1685
6.11k
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1686
2.92k
        fxStatement(parser, -1);
1687
3.18k
      aCaseCount = parser->nodeCount - aCaseCount;
1688
3.18k
      if (aCaseCount > 1) {
1689
1.04k
        fxPushNodeList(parser, aCaseCount);
1690
1.04k
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aCaseLine);
1691
1.04k
      }
1692
2.14k
      else if (aCaseCount == 0) {
1693
973
        fxPushNULL(parser);
1694
973
      }
1695
3.18k
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1696
3.18k
    }
1697
546
    else {
1698
546
      fxMatchToken(parser, XS_TOKEN_DEFAULT);
1699
546
      if (aDefaultFlag) 
1700
1
        fxReportParserError(parser, parser->states[0].line, "invalid default");
1701
546
      fxPushNULL(parser);
1702
546
      fxMatchToken(parser, XS_TOKEN_COLON);
1703
546
      aCaseCount = parser->nodeCount;
1704
790
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1705
244
        fxStatement(parser, -1);
1706
546
      aCaseCount = parser->nodeCount - aCaseCount;
1707
546
      if (aCaseCount > 1) {
1708
13
        fxPushNodeList(parser, aCaseCount);
1709
13
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1710
13
      }
1711
533
      else if (aCaseCount == 0) {
1712
2
        fxPushNULL(parser);
1713
2
      }
1714
546
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1715
546
      aDefaultFlag = 1;
1716
546
    }
1717
3.73k
    aCount++;
1718
3.73k
  }
1719
4.18k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1720
4.18k
  fxPushNodeList(parser, aCount);
1721
4.18k
  fxPushNodeStruct(parser, 2, XS_TOKEN_SWITCH, aLine);
1722
4.18k
}
1723
1724
void fxThrowStatement(txParser* parser)
1725
26.5k
{
1726
26.5k
  txInteger aLine = parser->states[0].line;
1727
26.5k
  fxMatchToken(parser, XS_TOKEN_THROW);
1728
26.5k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1729
25.2k
    fxCommaExpression(parser);
1730
25.2k
  }
1731
1.25k
  else {
1732
1.25k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1733
1.25k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
1734
1.25k
  }
1735
26.5k
  fxPushNodeStruct(parser, 1, XS_TOKEN_THROW, aLine);
1736
26.5k
}
1737
1738
void fxTryStatement(txParser* parser)
1739
8.43k
{
1740
8.43k
  txInteger aLine = parser->states[0].line;
1741
8.43k
  txBoolean ok = 0;
1742
8.43k
  fxMatchToken(parser, XS_TOKEN_TRY);
1743
8.43k
  fxBlock(parser);
1744
8.43k
  if (parser->states[0].token == XS_TOKEN_CATCH) {
1745
4.72k
    txInteger aCatchLine = parser->states[0].line;
1746
4.72k
    fxMatchToken(parser, XS_TOKEN_CATCH);
1747
4.72k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
1748
3.72k
      fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1749
3.72k
      fxBinding(parser, XS_TOKEN_LET, 1);
1750
3.72k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1751
3.72k
    }
1752
995
    else
1753
995
      fxPushNULL(parser);
1754
4.72k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1755
4.72k
    fxStatements(parser);
1756
4.72k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1757
4.72k
    fxPushNodeStruct(parser, 2, XS_TOKEN_CATCH, aCatchLine);
1758
4.72k
    ok = 1;
1759
4.72k
  }
1760
3.71k
  else {
1761
3.71k
    fxPushNULL(parser);
1762
3.71k
  }
1763
8.43k
  if (parser->states[0].token == XS_TOKEN_FINALLY) {
1764
95
    fxMatchToken(parser, XS_TOKEN_FINALLY);
1765
95
    fxBlock(parser);
1766
95
    ok = 1;
1767
95
  }
1768
8.34k
  else {
1769
8.34k
    fxPushNULL(parser);
1770
8.34k
  }
1771
8.43k
  if (!ok)
1772
1.63k
    fxReportParserError(parser, parser->states[0].line, "missing catch or finally");
1773
8.43k
  fxPushNodeStruct(parser, 3, XS_TOKEN_TRY, aLine);
1774
8.43k
}
1775
1776
void fxVariableStatement(txParser* parser, txToken theToken, txUnsigned flags)
1777
158k
{
1778
158k
  txBoolean commaFlag = 0;
1779
158k
  txInteger aCount = 0;
1780
158k
  txInteger aLine = parser->states[0].line;
1781
158k
  fxMatchToken(parser, theToken);
1782
161k
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
1783
156k
    commaFlag = 0;
1784
156k
    fxBinding(parser, theToken, 1 | flags);
1785
//    if (parser->states[0].token == XS_TOKEN_ASSIGN) {
1786
//      parser->flags &= ~mxForFlag;
1787
//      fxGetNextToken(parser);
1788
//      fxAssignmentExpression(parser);
1789
//      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, aLine);
1790
//      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1791
//    }
1792
156k
    aCount++;
1793
156k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
1794
3.05k
      parser->flags &= ~mxForFlag;
1795
3.05k
      fxGetNextToken(parser);
1796
3.05k
      commaFlag = 1;
1797
3.05k
    }
1798
153k
    else
1799
153k
      break;
1800
156k
  }
1801
158k
    if ((aCount == 0) || commaFlag) {
1802
2.99k
    fxPushNULL(parser);
1803
2.99k
    fxPushNULL(parser);
1804
2.99k
    fxPushNodeStruct(parser, 2, theToken, aLine);
1805
2.99k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
1806
2.99k
  }
1807
158k
  if (aCount > 1) {
1808
1.87k
    fxPushNodeList(parser, aCount);
1809
1.87k
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1810
1.87k
  }
1811
158k
}
1812
1813
void fxWhileStatement(txParser* parser)
1814
540
{
1815
540
  txInteger aLine = parser->states[0].line;
1816
540
  fxPushNULL(parser);
1817
540
  fxMatchToken(parser, XS_TOKEN_WHILE);
1818
540
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1819
540
  fxCommaExpression(parser);
1820
540
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1821
540
  fxStatement(parser, 0);
1822
540
  fxPushNodeStruct(parser, 2, XS_TOKEN_WHILE, aLine);
1823
540
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1824
540
}
1825
1826
void fxWithStatement(txParser* parser)
1827
5.29k
{
1828
5.29k
  txInteger aLine = parser->states[0].line;
1829
5.29k
  fxMatchToken(parser, XS_TOKEN_WITH);
1830
5.29k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1831
5.29k
  fxCommaExpression(parser);
1832
5.29k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1833
5.29k
  fxStatement(parser, 0);
1834
5.29k
  fxPushNodeStruct(parser, 2, XS_TOKEN_WITH, aLine);
1835
5.29k
}
1836
1837
void fxCommaExpression(txParser* parser)
1838
1.31M
{
1839
1.31M
  txInteger aCount = 0;
1840
1.31M
  txInteger aLine = parser->states[0].line;
1841
1.31M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1842
1.31M
    fxAssignmentExpression(parser);
1843
1.31M
    aCount++;
1844
1.36M
    while (parser->states[0].token == XS_TOKEN_COMMA) {
1845
48.8k
      fxGetNextToken(parser);
1846
48.8k
      fxAssignmentExpression(parser);
1847
48.8k
      aCount++;
1848
48.8k
    }
1849
1.31M
  }
1850
1.31M
  if (aCount > 1) {
1851
34.6k
    fxPushNodeList(parser, aCount);
1852
34.6k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
1853
34.6k
  }
1854
1.28M
  else if (aCount == 0) {
1855
1.98k
    fxPushNULL(parser);
1856
1.98k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1857
1.98k
  }
1858
1.31M
}
1859
1860
void fxAssignmentExpression(txParser* parser)
1861
2.75M
{
1862
2.75M
  fxCheckParserStack(parser, parser->states[0].line);
1863
2.75M
  if (parser->states[0].token == XS_TOKEN_YIELD)
1864
19.8k
    fxYieldExpression(parser);
1865
2.73M
  else {
1866
2.73M
    fxConditionalExpression(parser);
1867
2.88M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ASSIGN_EXPRESSION) {
1868
143k
      txToken aToken = parser->states[0].token;
1869
143k
      txInteger aLine = parser->states[0].line;
1870
143k
      if (!fxCheckReference(parser, aToken)) 
1871
7.68k
        fxReportParserError(parser, parser->states[0].line, "no reference");
1872
143k
      fxGetNextToken(parser);
1873
143k
      fxAssignmentExpression(parser);
1874
143k
      fxPushNodeStruct(parser, 2, aToken, aLine);
1875
143k
    }
1876
2.73M
  }
1877
2.75M
}
1878
1879
void fxConditionalExpression(txParser* parser)
1880
2.73M
{
1881
2.73M
  fxCoalesceExpression(parser);
1882
2.73M
  if (parser->states[0].token == XS_TOKEN_QUESTION_MARK) {
1883
6.08k
    txInteger aLine = parser->states[0].line;
1884
6.08k
    txUnsigned flags;
1885
6.08k
    fxCheckArrowFunction(parser, 1);
1886
6.08k
    fxGetNextToken(parser);
1887
6.08k
    flags = parser->flags & mxForFlag;
1888
6.08k
    parser->flags &= ~mxForFlag;
1889
6.08k
    fxAssignmentExpression(parser);
1890
6.08k
    parser->flags |= flags;
1891
6.08k
    fxMatchToken(parser, XS_TOKEN_COLON);
1892
6.08k
    fxAssignmentExpression(parser);
1893
6.08k
    fxPushNodeStruct(parser, 3, XS_TOKEN_QUESTION_MARK, aLine);
1894
6.08k
  }
1895
2.73M
}
1896
1897
void fxCoalesceExpression(txParser* parser)
1898
2.73M
{
1899
2.73M
  fxOrExpression(parser);
1900
2.74M
  while (parser->states[0].token == XS_TOKEN_COALESCE) {
1901
3.76k
    txInteger aLine = parser->states[0].line;
1902
3.76k
    fxGetNextToken(parser);
1903
3.76k
    fxOrExpression(parser);
1904
3.76k
    fxCheckArrowFunction(parser, 2);
1905
3.76k
    fxPushNodeStruct(parser, 2, XS_TOKEN_COALESCE, aLine);
1906
3.76k
  }
1907
2.73M
}
1908
1909
void fxOrExpression(txParser* parser)
1910
2.74M
{
1911
2.74M
  fxAndExpression(parser);
1912
2.75M
  while (parser->states[0].token == XS_TOKEN_OR) {
1913
8.17k
    txInteger aLine = parser->states[0].line;
1914
8.17k
    fxGetNextToken(parser);
1915
8.17k
    fxAndExpression(parser);
1916
8.17k
    fxCheckArrowFunction(parser, 2);
1917
8.17k
    fxPushNodeStruct(parser, 2, XS_TOKEN_OR, aLine);
1918
8.17k
  }
1919
2.74M
}
1920
1921
void fxAndExpression(txParser* parser)
1922
2.74M
{
1923
2.74M
  fxBitOrExpression(parser);
1924
2.75M
  while (parser->states[0].token == XS_TOKEN_AND) {
1925
4.85k
    txInteger aLine = parser->states[0].line;
1926
4.85k
    fxGetNextToken(parser);
1927
4.85k
    fxBitOrExpression(parser);
1928
4.85k
    fxCheckArrowFunction(parser, 2);
1929
4.85k
    fxPushNodeStruct(parser, 2, XS_TOKEN_AND, aLine);
1930
4.85k
  }
1931
2.74M
}
1932
1933
void fxBitOrExpression(txParser* parser)
1934
2.75M
{
1935
2.75M
  fxBitXorExpression(parser);
1936
2.76M
  while (parser->states[0].token == XS_TOKEN_BIT_OR) {
1937
8.73k
    txInteger aLine = parser->states[0].line;
1938
8.73k
    fxGetNextToken(parser);
1939
8.73k
    fxBitXorExpression(parser);
1940
8.73k
    fxCheckArrowFunction(parser, 2);
1941
8.73k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_OR, aLine);
1942
8.73k
  }
1943
2.75M
}
1944
1945
void fxBitXorExpression(txParser* parser)
1946
2.76M
{
1947
2.76M
  fxBitAndExpression(parser);
1948
2.76M
  while (parser->states[0].token == XS_TOKEN_BIT_XOR) {
1949
3.34k
    txInteger aLine = parser->states[0].line;
1950
3.34k
    fxGetNextToken(parser);
1951
3.34k
    fxBitAndExpression(parser);
1952
3.34k
    fxCheckArrowFunction(parser, 2);
1953
3.34k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_XOR, aLine);
1954
3.34k
  }
1955
2.76M
}
1956
1957
void fxBitAndExpression(txParser* parser)
1958
2.76M
{
1959
2.76M
  fxEqualExpression(parser);
1960
2.78M
  while (parser->states[0].token == XS_TOKEN_BIT_AND) {
1961
20.0k
    txInteger aLine = parser->states[0].line;
1962
20.0k
    fxGetNextToken(parser);
1963
20.0k
    fxEqualExpression(parser);
1964
20.0k
    fxCheckArrowFunction(parser, 2);
1965
20.0k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_AND, aLine);
1966
20.0k
  }
1967
2.76M
}
1968
1969
void fxEqualExpression(txParser* parser)
1970
2.78M
{
1971
2.78M
  fxRelationalExpression(parser);
1972
2.79M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EQUAL_EXPRESSION) {
1973
7.94k
    txToken aToken = parser->states[0].token;
1974
7.94k
    txInteger aLine = parser->states[0].line;
1975
7.94k
    fxGetNextToken(parser);
1976
7.94k
    fxRelationalExpression(parser);
1977
7.94k
    fxCheckArrowFunction(parser, 2);
1978
7.94k
    fxPushNodeStruct(parser, 2, aToken, aLine);
1979
7.94k
  }
1980
2.78M
}
1981
1982
void fxRelationalExpression(txParser* parser)
1983
2.79M
{
1984
2.79M
  if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
1985
2.78k
    txInteger aLine = parser->states[0].line;
1986
2.78k
    fxPushSymbol(parser, parser->states[0].symbol);
1987
2.78k
    fxGetNextToken(parser);
1988
2.78k
    fxMatchToken(parser, XS_TOKEN_IN);
1989
2.78k
    if (parser->flags & mxForFlag)
1990
1
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[XS_TOKEN_IN]);
1991
2.78k
    fxShiftExpression(parser);
1992
2.78k
    fxCheckArrowFunction(parser, 2);
1993
2.78k
    fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_IDENTIFIER, aLine);
1994
2.78k
  }
1995
2.79M
  else {
1996
2.79M
    fxShiftExpression(parser);
1997
2.79M
    if ((parser->flags & mxForFlag) && ((parser->states[0].token == XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)))
1998
960
      return;
1999
2.85M
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_RELATIONAL_EXPRESSION) {
2000
68.3k
      txToken aToken = parser->states[0].token;
2001
68.3k
      txInteger aLine = parser->states[0].line;
2002
68.3k
      fxMatchToken(parser, aToken);
2003
68.3k
      fxShiftExpression(parser);
2004
68.3k
      fxCheckArrowFunction(parser, 2);
2005
68.3k
      fxPushNodeStruct(parser, 2, aToken, aLine);
2006
68.3k
    }
2007
2.78M
  }
2008
2.79M
}
2009
2010
void fxShiftExpression(txParser* parser)
2011
2.85M
{
2012
2.85M
  fxAdditiveExpression(parser);
2013
2.88M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_SHIFT_EXPRESSION) {
2014
23.0k
    txToken aToken = parser->states[0].token;
2015
23.0k
    txInteger aLine = parser->states[0].line;
2016
23.0k
    fxGetNextToken(parser);
2017
23.0k
    fxAdditiveExpression(parser);
2018
23.0k
    fxCheckArrowFunction(parser, 2);
2019
23.0k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2020
23.0k
  }
2021
2.85M
}
2022
2023
void fxAdditiveExpression(txParser* parser)
2024
2.88M
{
2025
2.88M
  fxMultiplicativeExpression(parser);
2026
15.6M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ADDITIVE_EXPRESSION) {
2027
12.8M
    txToken aToken = parser->states[0].token;
2028
12.8M
    txInteger aLine = parser->states[0].line;
2029
12.8M
    fxGetNextToken(parser);
2030
12.8M
    fxMultiplicativeExpression(parser);
2031
12.8M
    fxCheckArrowFunction(parser, 2);
2032
12.8M
    fxPushNodeStruct(parser, 2, aToken, aLine);
2033
12.8M
  }
2034
2.88M
}
2035
2036
void fxMultiplicativeExpression(txParser* parser)
2037
15.6M
{
2038
15.6M
  fxExponentiationExpression(parser);
2039
15.8M
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_MULTIPLICATIVE_EXPRESSION) {
2040
128k
    txToken aToken = parser->states[0].token;
2041
128k
    txInteger aLine = parser->states[0].line;
2042
128k
    fxGetNextToken(parser);
2043
128k
    fxExponentiationExpression(parser);
2044
128k
    fxCheckArrowFunction(parser, 2);
2045
128k
    fxPushNodeStruct(parser, 2, aToken, aLine);
2046
128k
  }
2047
15.6M
}
2048
2049
void fxExponentiationExpression(txParser* parser)
2050
15.8M
{
2051
15.8M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION)
2052
109k
    fxUnaryExpression(parser);
2053
15.7M
  else {
2054
15.7M
    fxPrefixExpression(parser);
2055
15.7M
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EXPONENTIATION_EXPRESSION) {
2056
3.07k
      txToken aToken = parser->states[0].token;
2057
3.07k
      txInteger aLine = parser->states[0].line;
2058
3.07k
      fxGetNextToken(parser);
2059
3.07k
            fxExponentiationExpression(parser);
2060
3.07k
      fxCheckArrowFunction(parser, 2);
2061
3.07k
      fxPushNodeStruct(parser, 2, aToken, aLine);
2062
3.07k
    }
2063
15.7M
  }
2064
15.8M
}
2065
2066
void fxUnaryExpression(txParser* parser)
2067
391k
{
2068
391k
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION) {
2069
283k
    txToken aToken = parser->states[0].token;
2070
283k
    txInteger aLine = parser->states[0].line;
2071
283k
    fxCheckParserStack(parser, aLine);
2072
283k
    fxMatchToken(parser, aToken);
2073
283k
    fxUnaryExpression(parser);
2074
283k
    fxCheckArrowFunction(parser, 1);
2075
283k
    if (aToken == XS_TOKEN_ADD)
2076
8.03k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PLUS, aLine);
2077
275k
    else if (aToken == XS_TOKEN_SUBTRACT)
2078
54.9k
      fxPushNodeStruct(parser, 1, XS_TOKEN_MINUS, aLine);
2079
220k
    else if (aToken == XS_TOKEN_DELETE) {
2080
      //if ((parser->flags & mxStrictFlag) && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2081
      //  fxReportParserError(parser, parser->states[0].line, "no reference (strict mode)");
2082
      //}
2083
13.5k
      if (!fxCheckReference(parser, aToken)) 
2084
0
        fxReportParserError(parser, parser->states[0].line, "no reference");
2085
13.5k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2086
13.5k
    }
2087
207k
    else if (aToken == XS_TOKEN_AWAIT) {
2088
961
      if ((parser->flags & mxGeneratorFlag) && !(parser->flags & mxYieldFlag))
2089
3
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2090
958
      else
2091
958
        parser->flags |= mxAwaitingFlag;
2092
961
      fxPushNodeStruct(parser, 1, aToken, aLine);
2093
961
    }
2094
206k
    else
2095
206k
      fxPushNodeStruct(parser, 1, aToken, aLine);
2096
      
2097
283k
  }
2098
107k
  else
2099
107k
    fxPrefixExpression(parser);
2100
391k
}
2101
2102
void fxPrefixExpression(txParser* parser)
2103
15.9M
{
2104
15.9M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_PREFIX_EXPRESSION) {
2105
118k
    txToken aToken = parser->states[0].token;
2106
118k
    txInteger aLine = parser->states[0].line;
2107
118k
    fxCheckParserStack(parser, aLine);
2108
118k
    fxGetNextToken(parser);
2109
118k
    fxPrefixExpression(parser);
2110
118k
    fxCheckArrowFunction(parser, 1);
2111
118k
    if (!fxCheckReference(parser, aToken)) 
2112
1.82k
      fxReportParserError(parser, parser->states[0].line, "no reference");
2113
118k
    fxPushNodeStruct(parser, 1, aToken, aLine);
2114
118k
    parser->root->flags = mxExpressionNoValue;
2115
118k
  }
2116
15.8M
  else
2117
15.8M
    fxPostfixExpression(parser);
2118
15.9M
}
2119
2120
void fxPostfixExpression(txParser* parser)
2121
15.8M
{
2122
15.8M
  fxCallExpression(parser);
2123
15.8M
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_POSTFIX_EXPRESSION)) {
2124
22.8k
    fxCheckArrowFunction(parser, 1);
2125
22.8k
    if (!fxCheckReference(parser, parser->states[0].token)) 
2126
187
      fxReportParserError(parser, parser->states[0].line, "no reference");
2127
22.8k
    fxPushNodeStruct(parser, 1, parser->states[0].token, parser->states[0].line);
2128
22.8k
    fxGetNextToken(parser);
2129
22.8k
  }
2130
15.8M
}
2131
2132
void fxCallExpression(txParser* parser)
2133
15.8M
{
2134
15.8M
  txInteger chainLine = parser->states[0].line;
2135
15.8M
  fxLiteralExpression(parser, 0);
2136
15.8M
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_CALL_EXPRESSION) {
2137
435k
    txBoolean chainFlag = 0;
2138
435k
    fxCheckArrowFunction(parser, 1);
2139
1.25M
    for (;;) {
2140
1.25M
      txInteger aLine = parser->states[0].line;
2141
1.25M
      if (parser->states[0].token == XS_TOKEN_DOT) {
2142
355k
        fxGetNextToken(parser);
2143
355k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2144
340k
          fxPushSymbol(parser, parser->states[0].symbol);
2145
340k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2146
340k
          fxGetNextToken(parser);
2147
340k
        }
2148
14.6k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2149
13.7k
          if (parser->root->flags & mxSuperFlag)
2150
0
            fxReportParserError(parser, parser->states[0].line, "invalid super");
2151
13.7k
          fxPushSymbol(parser, parser->states[0].symbol);
2152
13.7k
          fxSwapNodes(parser);
2153
13.7k
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2154
13.7k
          fxGetNextToken(parser);
2155
13.7k
        }
2156
810
        else
2157
810
          fxReportParserError(parser, parser->states[0].line, "missing property");
2158
355k
      }
2159
      //else if (parser->states[0].crlf)
2160
      //  break;
2161
902k
      else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2162
16.8k
        fxGetNextToken(parser);
2163
16.8k
        fxCommaExpression(parser);
2164
16.8k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2165
16.8k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2166
16.8k
      }
2167
885k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2168
297k
        txUnsigned nativeFlags = 0;
2169
297k
        txAccessNode* access = NULL;
2170
297k
        if (parser->root->description && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2171
72.9k
          access = (txAccessNode*)parser->root;
2172
72.9k
          if (access->symbol == parser->evalSymbol) {
2173
4.92k
            parser->flags |= mxEvalFlag;
2174
4.92k
          }
2175
68.0k
          else if (parser->flags & mxCFlag) {
2176
0
            if (access->symbol == parser->NativeSymbol) {
2177
0
              nativeFlags = mxNativeConstructorFlag;
2178
0
            }
2179
0
            else if (access->symbol == parser->nativeSymbol) {
2180
0
              nativeFlags = mxNativeFunctionFlag;
2181
0
              parser->flags |= mxNativeFlag;
2182
0
            }
2183
0
          }
2184
72.9k
        }
2185
297k
        fxParameters(parser);
2186
297k
        if (nativeFlags) {
2187
0
          txParamsNode* params = (txParamsNode*)parser->root;
2188
0
          if (params->items->length == 0)
2189
0
             fxReportParserError(parser, aLine, "%s: no argument", access->symbol->string);
2190
0
          if (params->items->length > 1)
2191
0
             fxReportParserError(parser, aLine, "%s: too many arguments", access->symbol->string);
2192
0
          txStringNode* param = (txStringNode*)(params->items->first);
2193
0
          if (param->description->token != XS_TOKEN_STRING)
2194
0
             fxReportParserError(parser, aLine, "%s: argument is no string literal", access->symbol->string);
2195
0
          fxPopNode(parser);
2196
0
          fxPopNode(parser);
2197
0
          if (nativeFlags & mxNativeFunctionFlag) {
2198
0
            fxPushNULL(parser);
2199
0
            fxPushNodeList(parser, 0);
2200
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2201
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2202
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2203
0
          }
2204
0
          else {
2205
0
            fxPushNULL(parser);
2206
2207
0
            fxPushNULL(parser);
2208
0
            fxPushNULL(parser);
2209
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2210
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2211
            
2212
0
            fxPushNodeList(parser, 0);
2213
            
2214
0
            fxPushNULL(parser);
2215
0
            fxPushNULL(parser);
2216
            
2217
0
            fxPushNULL(parser);
2218
0
            fxPushNodeList(parser, 0);
2219
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2220
0
            fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2221
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2222
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2223
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2224
0
            parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2225
            
2226
0
            fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2227
0
          }
2228
0
        }
2229
297k
        else
2230
297k
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2231
297k
      }
2232
588k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
2233
203k
        if (chainFlag)
2234
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2235
203k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2236
203k
        fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2237
203k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2238
203k
        fxGetNextToken(parser);
2239
203k
        fxPushNodeList(parser, 1);
2240
203k
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2241
203k
      }
2242
385k
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
2243
332
        if (chainFlag)
2244
1
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2245
332
        fxTemplateExpression(parser);
2246
332
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2247
332
      }
2248
384k
      else if (parser->states[0].token == XS_TOKEN_CHAIN) {
2249
14.5k
        fxGetNextToken(parser);
2250
14.5k
        chainFlag = 1;
2251
14.5k
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2252
10.5k
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2253
10.5k
          fxPushSymbol(parser, parser->states[0].symbol);
2254
10.5k
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2255
10.5k
          fxGetNextToken(parser);
2256
10.5k
        }
2257
3.96k
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2258
646
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2259
646
          fxPushSymbol(parser, parser->states[0].symbol);
2260
646
          fxSwapNodes(parser);
2261
646
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2262
646
          fxGetNextToken(parser);
2263
646
        }
2264
3.32k
        else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2265
505
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2266
505
          fxGetNextToken(parser);
2267
505
          fxCommaExpression(parser);
2268
505
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2269
505
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2270
505
        }
2271
2.81k
        else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2272
1.97k
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2273
1.97k
          fxParameters(parser);
2274
1.97k
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2275
1.97k
        }
2276
838
        else
2277
838
          fxReportParserError(parser, parser->states[0].line, "invalid ?.");
2278
14.5k
      }
2279
370k
      else
2280
370k
        break;
2281
1.25M
    } 
2282
435k
    if (chainFlag)
2283
12.9k
      fxPushNodeStruct(parser, 1, XS_TOKEN_CHAIN, chainLine);
2284
435k
  } 
2285
15.8M
}
2286
2287
void fxLiteralExpression(txParser* parser, txUnsigned flag)
2288
15.8M
{
2289
15.8M
  int escaped;
2290
15.8M
  txSymbol* aSymbol;
2291
15.8M
  txInteger aLine = parser->states[0].line;
2292
15.8M
  txUnsigned flags = 0;
2293
15.8M
  char c = 0;
2294
15.8M
  fxCheckParserStack(parser, aLine);
2295
15.8M
  switch (parser->states[0].token) {
2296
11.4k
  case XS_TOKEN_NULL:
2297
18.7k
  case XS_TOKEN_TRUE:
2298
24.7k
  case XS_TOKEN_FALSE:
2299
24.7k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2300
24.7k
    fxMatchToken(parser, parser->states[0].token);
2301
24.7k
    break;
2302
7.77k
  case XS_TOKEN_IMPORT:
2303
7.77k
    fxMatchToken(parser, XS_TOKEN_IMPORT);
2304
7.77k
    if (!flag && (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)) {
2305
5.63k
      txUnsigned flags = parser->flags & mxForFlag;
2306
5.63k
      fxGetNextToken(parser);
2307
5.63k
      parser->flags &= ~mxForFlag;
2308
5.63k
      fxAssignmentExpression(parser);
2309
5.63k
      if (parser->states[0].token == XS_TOKEN_COMMA) {
2310
378
        fxGetNextToken(parser);
2311
378
        if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
2312
351
          fxAssignmentExpression(parser);
2313
351
          if (parser->states[0].token == XS_TOKEN_COMMA)
2314
43
            fxGetNextToken(parser);
2315
351
        }
2316
27
        else
2317
27
          fxPushNULL(parser);
2318
378
      }
2319
5.25k
      else
2320
5.25k
        fxPushNULL(parser);
2321
5.63k
      parser->flags |= flags;
2322
5.63k
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
2323
5.63k
      fxPushNodeStruct(parser, 2, XS_TOKEN_IMPORT_CALL, aLine);
2324
5.63k
    }
2325
2.14k
    else if (parser->states[0].token == XS_TOKEN_DOT) {
2326
968
      fxGetNextToken(parser);
2327
968
      if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->metaSymbol) && (!parser->states[0].escaped)) { 
2328
254
        fxGetNextToken(parser);
2329
254
        if (parser->flags & mxProgramFlag)
2330
157
          fxReportParserError(parser, parser->states[0].line, "invalid import.meta");
2331
97
        else
2332
97
          fxPushNodeStruct(parser, 0, XS_TOKEN_IMPORT_META, aLine);
2333
254
      }
2334
714
      else
2335
714
        fxReportParserError(parser, parser->states[0].line, "invalid import.");
2336
968
    }
2337
1.17k
    else
2338
1.17k
      fxReportParserError(parser, parser->states[0].line, "invalid import");
2339
7.77k
    break;
2340
1.75k
  case XS_TOKEN_SUPER:
2341
1.75k
    fxMatchToken(parser, XS_TOKEN_SUPER);
2342
1.75k
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2343
28
      if (parser->flags & mxDerivedFlag) {
2344
18
        fxParameters(parser);
2345
18
        fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2346
18
      }
2347
10
      else {
2348
10
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2349
10
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2350
10
      }
2351
28
    }
2352
1.72k
    else if ((parser->states[0].token == XS_TOKEN_DOT) || (parser->states[0].token == XS_TOKEN_LEFT_BRACKET)) {
2353
764
      if (parser->flags & mxSuperFlag) {
2354
664
        fxPushNodeStruct(parser, 0, XS_TOKEN_THIS, aLine);
2355
664
        parser->root->flags |= parser->flags & (mxDerivedFlag | mxSuperFlag);
2356
664
      }
2357
100
      else {
2358
100
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2359
100
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2360
100
      }
2361
764
    }
2362
959
    else
2363
959
      fxReportParserError(parser, parser->states[0].line, "invalid super");
2364
1.75k
    parser->flags |= mxSuperFlag;
2365
1.75k
    break;
2366
17.1k
  case XS_TOKEN_THIS:
2367
17.1k
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2368
17.1k
    parser->root->flags |= parser->flags & mxDerivedFlag;
2369
17.1k
    fxMatchToken(parser, XS_TOKEN_THIS);
2370
17.1k
    break;
2371
13.1M
  case XS_TOKEN_INTEGER:
2372
13.1M
    fxPushIntegerNode(parser, parser->states[0].integer, aLine);
2373
13.1M
    fxGetNextToken(parser);
2374
13.1M
    break;
2375
31.9k
  case XS_TOKEN_NUMBER:
2376
31.9k
    fxPushNumberNode(parser, parser->states[0].number, aLine);
2377
31.9k
    fxGetNextToken(parser);
2378
31.9k
    break;
2379
63.2k
  case XS_TOKEN_BIGINT:
2380
63.2k
    fxPushBigIntNode(parser, &parser->states[0].bigint, aLine);
2381
63.2k
    fxGetNextToken(parser);
2382
63.2k
    break;
2383
715
  case XS_TOKEN_DIVIDE_ASSIGN:
2384
715
    c = '=';
2385
    // continue
2386
715
    mxFallThrough;
2387
30.4k
  case XS_TOKEN_DIVIDE:
2388
30.4k
    fxGetNextRegExp(parser, c);
2389
30.4k
    fxPushStringNode(parser, parser->states[0].modifierLength, parser->states[0].modifier, aLine);
2390
30.4k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2391
30.4k
    fxPushNodeStruct(parser, 2, XS_TOKEN_REGEXP, aLine);
2392
30.4k
    fxGetNextToken(parser);
2393
30.4k
    break;
2394
265k
  case XS_TOKEN_STRING:
2395
265k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2396
265k
    fxGetNextToken(parser);
2397
265k
    break;
2398
1.43M
  case XS_TOKEN_IDENTIFIER:
2399
1.43M
    escaped = parser->states[0].escaped;
2400
1.43M
    aSymbol = parser->states[0].symbol;
2401
1.43M
    fxGetNextToken(parser);
2402
//    if (aSymbol == parser->undefinedSymbol) {
2403
//      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2404
//      break;
2405
//    }
2406
1.43M
    flags = 0;
2407
1.43M
    if ((aSymbol == parser->asyncSymbol) && (!escaped) && (!parser->states[0].crlf)) {
2408
5.33k
      if (parser->states[0].token == XS_TOKEN_FUNCTION) {
2409
1.67k
        fxMatchToken(parser, XS_TOKEN_FUNCTION);
2410
1.67k
        if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2411
305
          fxGetNextToken(parser);
2412
305
          fxGeneratorExpression(parser, aLine, C_NULL, mxAsyncFlag);
2413
305
        }
2414
1.37k
        else
2415
1.37k
          fxFunctionExpression(parser, aLine, C_NULL, mxAsyncFlag);
2416
1.67k
        break;
2417
1.67k
      }
2418
3.65k
      if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2419
509
        fxGroupExpression(parser, mxAsyncFlag);
2420
509
        break;
2421
509
      }
2422
3.14k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2423
//        if (!(parser->flags & mxForFlag) || !fxIsKeyword(parser, parser->ofSymbol)) {
2424
2.83k
          aSymbol = parser->states[0].symbol;
2425
2.83k
          fxGetNextToken(parser);
2426
2.83k
          flags = mxAsyncFlag;
2427
//        }
2428
2.83k
      }
2429
3.14k
    }
2430
1.43M
    if (aSymbol == parser->awaitSymbol)
2431
895
      parser->flags |= mxAwaitingFlag;
2432
1.43M
    if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
2433
18.0k
      fxCheckStrictSymbol(parser, aSymbol);
2434
18.0k
      if (flags && (aSymbol == parser->awaitSymbol))
2435
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2436
18.0k
      fxPushSymbol(parser, aSymbol);
2437
18.0k
      fxPushNULL(parser);
2438
18.0k
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2439
18.0k
      fxPushNodeList(parser, 1);
2440
18.0k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2441
18.0k
      fxArrowExpression(parser, flags);
2442
18.0k
      break;
2443
18.0k
    }
2444
1.41M
    if (aSymbol == parser->argumentsSymbol)
2445
1.05k
      parser->flags |= mxArgumentsFlag;
2446
1.41M
    fxPushSymbol(parser, aSymbol);
2447
1.41M
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2448
1.41M
    break;
2449
11.1k
  case XS_TOKEN_CLASS:
2450
11.1k
    flags = parser->flags & mxForFlag;
2451
11.1k
    parser->flags &= ~mxForFlag;
2452
11.1k
    fxClassExpression(parser, aLine, C_NULL);
2453
11.1k
    parser->flags |= flags;
2454
11.1k
    break;
2455
209k
  case XS_TOKEN_FUNCTION:
2456
209k
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
2457
209k
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2458
6.44k
      fxGetNextToken(parser);
2459
6.44k
      fxGeneratorExpression(parser, aLine, C_NULL, 0);
2460
6.44k
    }
2461
202k
    else
2462
202k
      fxFunctionExpression(parser, aLine, C_NULL, 0);
2463
209k
    break;
2464
48.1k
  case XS_TOKEN_NEW:
2465
48.1k
    fxNewExpression(parser);
2466
48.1k
    break;
2467
90.9k
  case XS_TOKEN_LEFT_BRACE:
2468
90.9k
    flags = parser->flags & mxForFlag;
2469
90.9k
    parser->flags &= ~mxForFlag;
2470
90.9k
    fxObjectExpression(parser);
2471
90.9k
    parser->flags |= flags;
2472
90.9k
    break;
2473
147k
  case XS_TOKEN_LEFT_BRACKET:
2474
147k
    flags = parser->flags & mxForFlag;
2475
147k
    parser->flags &= ~mxForFlag;
2476
147k
    fxArrayExpression(parser);
2477
147k
    parser->flags |= flags;
2478
147k
    break;
2479
236k
  case XS_TOKEN_LEFT_PARENTHESIS:
2480
236k
    fxGroupExpression(parser, 0);
2481
236k
    break;
2482
25.1k
  case XS_TOKEN_TEMPLATE:
2483
25.1k
    fxPushNULL(parser);
2484
25.1k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2485
25.1k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2486
25.1k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2487
25.1k
    fxGetNextToken(parser);
2488
25.1k
    fxPushNodeList(parser, 1);
2489
25.1k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2490
25.1k
    break;
2491
760
  case XS_TOKEN_TEMPLATE_HEAD:
2492
760
    fxPushNULL(parser);
2493
760
    fxTemplateExpression(parser);
2494
760
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2495
760
    break;
2496
0
  case XS_TOKEN_HOST:
2497
0
    fxGetNextToken(parser);
2498
0
    fxPushNULL(parser);
2499
0
    fxPushNULL(parser);
2500
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2501
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2502
0
      fxGetNextToken(parser);
2503
0
    }
2504
0
    else {
2505
0
      fxReportParserError(parser, parser->states[0].line, "invalid host object");
2506
0
      fxPushNULL(parser);
2507
0
    }
2508
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2509
0
    break;
2510
35.9k
  case XS_TOKEN_LESS:
2511
35.9k
    fxGetNextToken(parser);
2512
35.9k
    fxJSXElement(parser);
2513
35.9k
    fxGetNextToken(parser);
2514
35.9k
    break;
2515
11.8k
  default:
2516
11.8k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2517
11.8k
    fxReportParserError(parser, parser->states[0].line, "missing expression");
2518
11.8k
    break;
2519
15.8M
  }
2520
15.8M
}
2521
2522
void fxArrayExpression(txParser* parser)
2523
147k
{
2524
147k
  txInteger aCount = 0;
2525
147k
  int elision = 1;
2526
147k
  txInteger aLine = parser->states[0].line;
2527
147k
  txBoolean aSpreadFlag = 0;
2528
147k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
2529
679k
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2530
532k
    txInteger anItemLine = parser->states[0].line;
2531
532k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
2532
230k
      fxGetNextToken(parser);
2533
230k
      if (elision) {
2534
64.3k
        fxPushNodeStruct(parser, 0, XS_TOKEN_ELISION, anItemLine);
2535
64.3k
        aCount++;
2536
64.3k
      }
2537
166k
      else
2538
166k
        elision = 1;
2539
230k
    }
2540
302k
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
2541
1.36k
      fxGetNextToken(parser);
2542
1.36k
      if (!elision)
2543
2
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2544
1.36k
      fxAssignmentExpression(parser);
2545
1.36k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, anItemLine);
2546
1.36k
      aCount++;
2547
1.36k
      elision = 0;
2548
1.36k
      aSpreadFlag = 1;
2549
1.36k
    }
2550
300k
    else {
2551
300k
      if (!elision)
2552
1.45k
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2553
300k
      fxAssignmentExpression(parser);
2554
300k
      aCount++;
2555
300k
      elision = 0;
2556
300k
    }
2557
532k
  }
2558
147k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2559
147k
  fxPushNodeList(parser, aCount);
2560
147k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
2561
147k
  if (aCount && elision)
2562
2.22k
    parser->root->flags |= mxElisionFlag;
2563
147k
  if (aSpreadFlag)
2564
787
    parser->root->flags |= mxSpreadFlag;
2565
147k
}
2566
2567
void fxArrowExpression(txParser* parser, txUnsigned flag)
2568
57.8k
{
2569
57.8k
  txInteger aLine = parser->states[0].line;
2570
57.8k
  txUnsigned flags = parser->flags;
2571
57.8k
  parser->flags &= ~(mxAsyncFlag | mxGeneratorFlag);
2572
57.8k
  parser->flags |= mxArrowFlag | flag;
2573
57.8k
  fxMatchToken(parser, XS_TOKEN_ARROW);
2574
57.8k
  fxPushNULL(parser);
2575
57.8k
  fxSwapNodes(parser);  
2576
57.8k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2577
35.9k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2578
35.9k
    fxBody(parser);
2579
35.9k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2580
35.9k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2581
35.9k
  }
2582
21.8k
  else {
2583
21.8k
    fxAssignmentExpression(parser);
2584
21.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
2585
21.8k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2586
21.8k
    if (!(flags & mxAsyncFlag) && (flag & mxAsyncFlag)) {
2587
1.25k
      if (parser->states[0].token == XS_TOKEN_AWAIT) {
2588
1
        parser->states[0].token = XS_TOKEN_IDENTIFIER;
2589
1
      }
2590
1.25k
    }
2591
21.8k
  }
2592
57.8k
  fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2593
57.8k
  parser->root->flags = parser->flags & (mxStrictFlag | mxFieldFlag | mxNotSimpleParametersFlag | mxArrowFlag | mxSuperFlag | flag);
2594
57.8k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2595
746
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2596
57.8k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag | mxEvalFlag));
2597
57.8k
}
2598
2599
void fxClassExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol)
2600
81.1k
{
2601
81.1k
  txBoolean heritageFlag = 0;
2602
//  txBoolean hostFlag = 0;
2603
81.1k
  txNode* constructor = NULL;
2604
81.1k
  txInteger aCount = 0;
2605
81.1k
  txInteger aLine = parser->states[0].line;
2606
81.1k
  txUnsigned flags = parser->flags;
2607
81.1k
  txUnsigned constructorFlags = mxSuperFlag;
2608
81.1k
  txInteger constructorInitCount = 0;
2609
81.1k
  txInteger instanceInitCount = 0;
2610
81.1k
  parser->flags |= mxStrictFlag;
2611
81.1k
  fxMatchToken(parser, XS_TOKEN_CLASS);
2612
81.1k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2613
11.2k
    fxPushSymbol(parser, parser->states[0].symbol);
2614
11.2k
    if (theSymbol)
2615
8.80k
      *theSymbol = parser->states[0].symbol;
2616
11.2k
    fxGetNextToken(parser);
2617
11.2k
  }
2618
69.8k
  else
2619
69.8k
    fxPushNULL(parser);
2620
81.1k
  if (parser->states[0].token == XS_TOKEN_EXTENDS) {
2621
642
    fxMatchToken(parser, XS_TOKEN_EXTENDS);
2622
642
    fxCallExpression(parser);
2623
642
    fxCheckArrowFunction(parser, 1);
2624
642
    fxCheckNativeConstructor(parser);
2625
642
    flags |= parser->flags & mxAwaitingFlag;
2626
642
    constructorFlags |= mxDerivedFlag;
2627
642
    if (parser->root->description->token == XS_TOKEN_HOST)
2628
0
      constructorFlags |= mxHostFlag;
2629
642
    heritageFlag = 1;
2630
642
  }
2631
80.4k
  else if (parser->states[0].token == XS_TOKEN_HOST) {
2632
0
    fxGetNextToken(parser);
2633
0
    fxPushNULL(parser);
2634
0
    fxPushNULL(parser);
2635
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2636
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2637
0
      fxGetNextToken(parser);
2638
0
    }
2639
0
    else {
2640
0
      fxReportParserError(parser, parser->states[0].line, "invalid host class");
2641
0
      fxPushNULL(parser);
2642
0
    }
2643
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2644
0
    constructorFlags |= mxBaseFlag | mxHostFlag;
2645
//    hostFlag = 1;
2646
0
  }
2647
80.4k
  else {
2648
80.4k
    fxPushNULL(parser);
2649
80.4k
    constructorFlags |= mxBaseFlag;
2650
80.4k
  }
2651
81.1k
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2652
80.2k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2653
113k
    for (;;) {
2654
113k
      txBoolean aStaticFlag;
2655
113k
      txInteger aPropertyLine = parser->states[0].line;
2656
113k
      txSymbol* aSymbol;
2657
113k
      txToken aToken0;
2658
113k
      txToken aToken1;
2659
113k
      txToken aToken2;
2660
113k
      txUnsigned flag;
2661
128k
      while (parser->states[0].token == XS_TOKEN_SEMICOLON)
2662
15.0k
        fxGetNextToken(parser);
2663
113k
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
2664
7.44k
        break;
2665
106k
      aStaticFlag = 0;
2666
106k
      if ((parser->states[0].token == XS_TOKEN_STATIC) && (!parser->states[0].escaped)) {
2667
69.3k
        fxGetNextToken(parser);
2668
69.3k
        if ((parser->states[0].token == XS_TOKEN_ASSIGN) || parser->states[0].token == XS_TOKEN_SEMICOLON) {
2669
968
          fxPushSymbol(parser, parser->staticSymbol);
2670
968
          aToken1 = XS_TOKEN_PROPERTY;
2671
968
          goto field;
2672
968
        }
2673
68.3k
        if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2674
61.5k
          txUnsigned flags = parser->flags;
2675
61.5k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag | mxAsyncFlag;
2676
61.5k
          fxCheckParserStack(parser, aPropertyLine);
2677
61.5k
          fxGetNextToken(parser);
2678
61.5k
          fxStatements(parser);
2679
61.5k
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2680
61.5k
          fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aPropertyLine);
2681
61.5k
          if (parser->flags & mxArgumentsFlag)
2682
0
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2683
61.5k
          if (parser->flags & mxAwaitingFlag)
2684
0
            fxReportParserError(parser, parser->states[0].line, "invalid await");
2685
61.5k
          parser->flags = flags;
2686
61.5k
          parser->root->flags |= mxStaticFlag;
2687
61.5k
          constructorInitCount++;
2688
61.5k
          aCount++;
2689
61.5k
          continue;
2690
61.5k
        }
2691
6.78k
        aStaticFlag = 1;
2692
6.78k
      }
2693
43.5k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flag);
2694
43.5k
      if ((aStaticFlag == 0) && (aSymbol == parser->constructorSymbol)) {
2695
266
        fxPopNode(parser); // symbol
2696
266
        if (constructor || (aToken2 == XS_TOKEN_GENERATOR) || (aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER) || (flag & mxAsyncFlag)) 
2697
2
          fxReportParserError(parser, parser->states[0].line, "invalid constructor");
2698
266
        fxFunctionExpression(parser, aPropertyLine, C_NULL, constructorFlags);
2699
266
        constructor = fxPopNode(parser);
2700
266
      }
2701
43.3k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2702
6.16k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2703
1
          fxReportParserError(parser, parser->states[0].line, "invalid method: #constructor");
2704
6.16k
        if (aStaticFlag && (aSymbol == parser->prototypeSymbol))
2705
0
          fxReportParserError(parser, parser->states[0].line, "invalid static method: prototype");
2706
6.16k
        if (aStaticFlag)
2707
2.70k
          flag |= mxStaticFlag;
2708
6.16k
        if (aToken2 == XS_TOKEN_GETTER) 
2709
372
          flag |= mxGetterFlag;
2710
5.79k
        else if (aToken2 == XS_TOKEN_SETTER) 
2711
253
          flag |= mxSetterFlag;
2712
5.53k
        else
2713
5.53k
          flag |= mxMethodFlag;
2714
6.16k
        if (aToken2 == XS_TOKEN_GENERATOR)
2715
1.68k
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2716
4.47k
        else
2717
4.47k
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2718
6.16k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2719
6.16k
        parser->root->flags |= flag & (mxStaticFlag | mxGetterFlag | mxSetterFlag | mxMethodFlag);
2720
6.16k
        if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
2721
879
          if (aStaticFlag)
2722
35
            constructorInitCount++;
2723
844
          else
2724
844
            instanceInitCount++;
2725
879
        }
2726
6.16k
        aCount++;
2727
6.16k
      }
2728
37.1k
      else {
2729
37.1k
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2730
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: #constructor");
2731
37.1k
        if (aSymbol == parser->constructorSymbol)
2732
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: constructor");
2733
37.1k
        if (aSymbol == parser->prototypeSymbol)
2734
1
          fxReportParserError(parser, parser->states[0].line, "invalid field: prototype");
2735
37.1k
      field:
2736
33.3k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
2737
6.58k
          txUnsigned flags = parser->flags;
2738
6.58k
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag;
2739
6.58k
          fxGetNextToken(parser);
2740
6.58k
          fxAssignmentExpression(parser);
2741
6.58k
          if (parser->flags & mxArgumentsFlag)
2742
87
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2743
6.58k
          parser->flags = flags;
2744
6.58k
        }
2745
26.7k
        else {
2746
26.7k
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2747
26.7k
        }
2748
33.3k
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2749
33.3k
        if (aStaticFlag) {
2750
2.25k
          parser->root->flags |= mxStaticFlag;
2751
2.25k
          constructorInitCount++;
2752
2.25k
        }
2753
31.0k
        else
2754
31.0k
          instanceInitCount++;
2755
33.3k
        fxSemicolon(parser);
2756
33.3k
        aCount++;
2757
33.3k
      }
2758
43.5k
    }
2759
80.2k
  }
2760
76.3k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2761
76.3k
  fxPushNodeList(parser, aCount);
2762
  
2763
76.3k
  if (constructorInitCount || instanceInitCount) {
2764
5.22k
    txNodeList* itemsList = (txNodeList*)(parser->root);
2765
5.22k
    txNodeList* constructorInitList = C_NULL;
2766
5.22k
    txNode** constructorInitAddress = C_NULL;
2767
5.22k
    txNodeList* instanceInitList = C_NULL;
2768
5.22k
    txNode** instanceInitAddress = C_NULL;
2769
5.22k
    txNode** address;
2770
5.22k
    txNode* item;
2771
5.22k
    if (constructorInitCount) {
2772
1.27k
      fxPushNULL(parser);
2773
1.27k
      fxPushNodeList(parser, 0);
2774
1.27k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2775
1.27k
      fxPushNodeList(parser, 0);
2776
1.27k
      constructorInitList = (txNodeList*)(parser->root);
2777
1.27k
      constructorInitList->length = constructorInitCount;
2778
1.27k
      constructorInitAddress = &(((txNodeList*)(parser->root))->first);
2779
1.27k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2780
1.27k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2781
1.27k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2782
1.27k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2783
1.27k
    }
2784
3.94k
    else 
2785
3.94k
      fxPushNULL(parser);
2786
5.22k
    if (instanceInitCount) {
2787
4.32k
      fxPushNULL(parser);
2788
4.32k
      fxPushNodeList(parser, 0);
2789
4.32k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2790
4.32k
      fxPushNodeList(parser, 0);
2791
4.32k
      instanceInitList = (txNodeList*)(parser->root);
2792
4.32k
      instanceInitList->length = instanceInitCount;
2793
4.32k
      instanceInitAddress = &(((txNodeList*)(parser->root))->first);
2794
4.32k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2795
4.32k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2796
4.32k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2797
4.32k
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2798
4.32k
    }
2799
894
    else 
2800
894
      fxPushNULL(parser);
2801
5.22k
    address = &(itemsList->first);
2802
26.3k
    while ((item = *address)) {
2803
21.1k
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2804
1.68k
        if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) {
2805
877
          txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2806
877
          field->item = item;
2807
877
          if (item->flags & mxStaticFlag) {
2808
33
            *constructorInitAddress = (txNode*)field;
2809
33
            constructorInitAddress = &field->next;
2810
33
          }
2811
844
          else {
2812
844
            *instanceInitAddress = (txNode*)field;
2813
844
            instanceInitAddress = &field->next;
2814
844
          }
2815
877
        }
2816
1.68k
      }
2817
21.1k
      address = &(item->next);
2818
21.1k
    }
2819
5.22k
    address = &(itemsList->first);
2820
26.3k
    while ((item = *address)) {
2821
21.1k
      if (item->description->token == XS_TOKEN_BODY) {
2822
823
        *address = item->next;
2823
823
        item->next = C_NULL;
2824
823
        itemsList->length--;
2825
823
        *constructorInitAddress = (txNode*)item;
2826
823
        constructorInitAddress = &item->next;
2827
823
      }
2828
20.3k
      else if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2829
1.68k
        address = &(item->next);
2830
1.68k
      }
2831
18.6k
      else {
2832
18.6k
        txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2833
18.6k
        field->item = item;
2834
18.6k
        if (item->description->token == XS_TOKEN_PROPERTY) {
2835
6.71k
          field->value = ((txPropertyNode*)item)->value;
2836
6.71k
          ((txPropertyNode*)item)->value = C_NULL;
2837
6.71k
        }
2838
11.9k
        else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
2839
7.88k
          field->value = ((txPropertyAtNode*)item)->value;
2840
7.88k
          ((txPropertyAtNode*)item)->value = C_NULL;
2841
7.88k
        }
2842
4.06k
        else {
2843
4.06k
          field->value = ((txPrivatePropertyNode*)item)->value;
2844
4.06k
          ((txPrivatePropertyNode*)item)->value = C_NULL;
2845
4.06k
        }
2846
18.6k
        if (item->flags & mxStaticFlag) {
2847
415
          *constructorInitAddress = (txNode*)field;
2848
415
          constructorInitAddress = &field->next;
2849
415
        }
2850
18.2k
        else {
2851
18.2k
          *instanceInitAddress = (txNode*)field;
2852
18.2k
          instanceInitAddress = &field->next;
2853
18.2k
        }
2854
18.6k
        address = &(item->next);
2855
18.6k
      }
2856
21.1k
    }
2857
5.22k
  }
2858
71.1k
  else {
2859
71.1k
    fxPushNULL(parser);
2860
71.1k
    fxPushNULL(parser);
2861
71.1k
  }
2862
76.3k
  if (constructor) {
2863
221
    fxPushNode(parser, constructor);
2864
221
  }
2865
76.1k
  else {
2866
76.1k
    if (heritageFlag) {
2867
345
      fxPushNULL(parser);
2868
    
2869
345
      fxPushSymbol(parser, parser->argsSymbol);
2870
345
      fxPushNULL(parser);
2871
345
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2872
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
2873
345
      fxPushNodeList(parser, 1);
2874
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2875
      
2876
345
      fxPushSymbol(parser, parser->argsSymbol);
2877
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2878
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2879
345
      fxPushNodeList(parser, 1);
2880
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
2881
345
      parser->root->flags |= mxSpreadFlag;
2882
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2883
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2884
345
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2885
      
2886
345
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2887
345
      parser->root->flags = mxStrictFlag | mxDerivedFlag | mxMethodFlag | mxTargetFlag | mxSuperFlag;
2888
345
    }
2889
75.7k
    else {
2890
75.7k
      fxPushNULL(parser);
2891
    
2892
75.7k
      fxPushNodeList(parser, 0);
2893
75.7k
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2894
      
2895
75.7k
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2896
75.7k
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2897
75.7k
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2898
      
2899
75.7k
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2900
75.7k
      parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2901
75.7k
    }
2902
76.1k
  }
2903
76.3k
  fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2904
76.3k
  parser->flags = flags | (parser->flags & (mxArgumentsFlag));
2905
76.3k
}
2906
2907
void fxFunctionExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2908
217k
{
2909
217k
  txUnsigned flags = parser->flags;
2910
217k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxFunctionFlag | mxTargetFlag | flag;
2911
217k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2912
67.4k
      || ((flags & mxGeneratorFlag) && !(flags & mxStrictFlag) && (parser->states[0].token == XS_TOKEN_YIELD))
2913
150k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2914
150k
    fxPushSymbol(parser, parser->states[0].symbol);
2915
150k
    if (theSymbol)
2916
5.02k
      *theSymbol = parser->states[0].symbol;
2917
150k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2918
150k
    fxGetNextToken(parser);
2919
150k
  }
2920
67.3k
  else
2921
67.3k
    fxPushNULL(parser);
2922
217k
  fxParametersBinding(parser);
2923
217k
  if (parser->states[0].token == XS_TOKEN_HOST) {
2924
0
    fxGetNextToken(parser);
2925
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2926
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, theLine);
2927
0
      fxGetNextToken(parser);
2928
0
    }
2929
0
    else {
2930
0
      fxReportParserError(parser, parser->states[0].line, "invalid host function");
2931
0
      fxPushNULL(parser);
2932
0
    }
2933
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, theLine);
2934
0
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2935
0
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2936
0
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2937
0
        parser->flags = flags;
2938
0
  }
2939
217k
  else {
2940
217k
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2941
217k
    fxBody(parser);
2942
217k
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2943
217k
    fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, theLine);
2944
217k
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2945
217k
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2946
847
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2947
217k
        if (parser->flags & mxNativeFlag) {
2948
0
          fxCheckNativeFunction(parser);
2949
0
        }     
2950
217k
        parser->flags = flags;
2951
217k
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2952
217k
  }
2953
217k
}
2954
2955
void fxGeneratorExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2956
23.3k
{
2957
23.3k
  txUnsigned flags = parser->flags;
2958
23.3k
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxGeneratorFlag | mxTargetFlag | flag;
2959
23.3k
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2960
15.8k
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2961
15.8k
    fxPushSymbol(parser, parser->states[0].symbol);
2962
15.8k
    if (theSymbol)
2963
11.0k
      *theSymbol = parser->states[0].symbol;
2964
4.84k
    else if (parser->states[0].symbol == parser->yieldSymbol)
2965
213
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
2966
4.63k
    else if ((parser->flags & mxAsyncFlag) && (parser->states[0].symbol == parser->awaitSymbol))
2967
0
      fxReportParserError(parser, parser->states[0].line, "invalid await");
2968
15.8k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2969
15.8k
    fxGetNextToken(parser);
2970
15.8k
  }
2971
7.46k
  else
2972
7.46k
    fxPushNULL(parser);
2973
23.3k
  fxParametersBinding(parser);
2974
23.3k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2975
23.3k
  parser->flags |= mxYieldFlag;
2976
23.3k
    fxBody(parser);
2977
23.3k
  parser->flags &= ~mxYieldFlag;
2978
23.3k
  fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2979
23.3k
  fxPushNodeStruct(parser, 3, XS_TOKEN_GENERATOR, theLine);
2980
23.3k
  parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxGeneratorFlag | mxArgumentsFlag | mxEvalFlag | flag);
2981
23.3k
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2982
161
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2983
23.3k
  parser->flags = flags;
2984
23.3k
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2985
23.3k
}
2986
2987
void fxGroupExpression(txParser* parser, txUnsigned flag)
2988
236k
{
2989
236k
  txBoolean commaFlag = 0;
2990
236k
  txBoolean spreadFlag = 0;
2991
236k
  txInteger aCount = 0;
2992
236k
  txInteger aLine;
2993
236k
  txUnsigned formerAwaitingYieldingFlags = parser->flags & (mxAwaitingFlag | mxYieldingFlag);
2994
236k
  parser->flags &= ~(mxAwaitingFlag | mxYieldingFlag);
2995
236k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
2996
353k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2997
203k
    aLine = parser->states[0].line;
2998
203k
    commaFlag = 0;
2999
203k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3000
565
      fxGetNextToken(parser);
3001
565
      fxAssignmentExpression(parser);
3002
565
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
3003
565
      spreadFlag = 1;
3004
565
    }
3005
202k
    else
3006
202k
      fxAssignmentExpression(parser);
3007
203k
    aCount++;
3008
203k
    if (parser->states[0].token != XS_TOKEN_COMMA) 
3009
86.7k
      break;
3010
116k
    fxGetNextToken(parser);
3011
116k
    commaFlag = 1;
3012
116k
  }
3013
236k
  aLine = parser->states[0].line;
3014
236k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3015
236k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
3016
40.0k
    fxPushNodeList(parser, aCount);
3017
40.0k
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3018
40.0k
    if (commaFlag && spreadFlag)
3019
0
      fxReportParserError(parser, parser->states[0].line, "invalid parameters");
3020
40.0k
    if (!fxParametersBindingFromExpressions(parser, parser->root))
3021
265
      fxReportParserError(parser, parser->states[0].line, "no parameters");
3022
40.0k
    fxCheckStrictBinding(parser, parser->root);
3023
40.0k
    parser->root->flags |= flag;
3024
40.0k
    if (parser->flags & mxAwaitingFlag) {
3025
97
      if (flag || (parser->flags & mxAsyncFlag))
3026
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
3027
97
      else
3028
97
        formerAwaitingYieldingFlags |= mxAwaitingFlag;
3029
97
    }
3030
40.0k
    if (parser->flags & mxYieldingFlag)
3031
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
3032
40.0k
    fxArrowExpression(parser, flag);
3033
40.0k
  }
3034
196k
  else if (flag) {
3035
163
    fxPushNodeList(parser, aCount);
3036
163
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3037
163
    if (spreadFlag)
3038
1
      parser->root->flags |= mxSpreadFlag;
3039
    
3040
163
    fxPushSymbol(parser, parser->asyncSymbol);
3041
163
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
3042
163
    fxSwapNodes(parser);
3043
163
    fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
3044
163
  }
3045
196k
  else {
3046
196k
        if ((aCount == 0) || commaFlag) {
3047
3.83k
            fxPushNULL(parser);
3048
3.83k
      fxReportParserError(parser, parser->states[0].line, "missing expression");
3049
3.83k
        }
3050
192k
    else /*if (aCount > 1)*/ {
3051
192k
      fxPushNodeList(parser, aCount);
3052
192k
      fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3053
192k
    }
3054
196k
  }
3055
236k
  parser->flags |= formerAwaitingYieldingFlags;
3056
236k
}
3057
3058
void fxNewExpression(txParser* parser)
3059
48.1k
{
3060
48.1k
  txInteger aLine = parser->states[0].line;
3061
48.1k
  fxMatchToken(parser, XS_TOKEN_NEW);
3062
48.1k
  if (parser->states[0].token == XS_TOKEN_DOT) {
3063
670
    fxGetNextToken(parser);
3064
670
    if (fxIsKeyword(parser, parser->targetSymbol)) {
3065
162
      if (!(parser->flags & mxTargetFlag))
3066
131
        fxReportParserError(parser, parser->states[0].line, "invalid new.target");
3067
162
      fxGetNextToken(parser);
3068
162
      fxPushNodeStruct(parser, 0, XS_TOKEN_TARGET, aLine);
3069
162
    }
3070
508
    else
3071
508
      fxReportParserError(parser, parser->states[0].line, "missing target");
3072
670
    return;
3073
670
  }
3074
47.4k
  fxLiteralExpression(parser, 1);
3075
47.4k
  fxCheckArrowFunction(parser, 1);
3076
50.9k
  for (;;) {
3077
50.9k
    txInteger aMemberLine = parser->states[0].line;
3078
50.9k
    if (parser->states[0].token == XS_TOKEN_DOT) {
3079
5.34k
      fxGetNextToken(parser);
3080
5.34k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3081
5.33k
        fxPushSymbol(parser, parser->states[0].symbol);
3082
5.33k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aMemberLine);
3083
5.33k
        fxGetNextToken(parser);
3084
5.33k
      }
3085
11
      else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3086
10
        fxPushSymbol(parser, parser->states[0].symbol);
3087
10
        fxSwapNodes(parser);
3088
10
        fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aMemberLine);
3089
10
        fxGetNextToken(parser);
3090
10
      }
3091
1
      else
3092
1
        fxReportParserError(parser, parser->states[0].line, "missing property");
3093
5.34k
    }
3094
45.6k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3095
1.22k
      fxGetNextToken(parser);
3096
1.22k
      fxCommaExpression(parser);
3097
1.22k
      fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aMemberLine);
3098
1.22k
      fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3099
1.22k
    }
3100
44.3k
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
3101
213
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3102
213
      fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3103
213
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3104
213
      fxGetNextToken(parser);
3105
213
      fxPushNodeList(parser, 1);
3106
213
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3107
213
    }
3108
44.1k
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
3109
5
      fxTemplateExpression(parser);
3110
5
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3111
5
    }
3112
44.1k
    else
3113
44.1k
      break;
3114
50.9k
  } 
3115
47.4k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3116
33.4k
    fxParameters(parser);
3117
14.0k
  else {
3118
14.0k
    fxPushNodeList(parser, 0);
3119
14.0k
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3120
14.0k
  }
3121
47.4k
  fxPushNodeStruct(parser, 2, XS_TOKEN_NEW, aLine);
3122
47.4k
}
3123
3124
void fxObjectExpression(txParser* parser)
3125
90.9k
{
3126
90.9k
  txInteger aCount = 0;
3127
90.9k
  txSymbol* aSymbol;
3128
90.9k
  txToken aToken0;
3129
90.9k
  txToken aToken1;
3130
90.9k
  txToken aToken2;
3131
90.9k
  txInteger aLine = parser->states[0].line;
3132
90.9k
  txNode* base = parser->root;
3133
90.9k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3134
161k
  for (;;) {
3135
161k
    txInteger aPropertyLine = parser->states[0].line;
3136
161k
    txUnsigned flags = 0;
3137
161k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3138
30.7k
            break;
3139
130k
        if (parser->states[0].token == XS_TOKEN_SPREAD) {
3140
1.84k
      fxGetNextToken(parser);
3141
1.84k
      fxAssignmentExpression(parser);
3142
1.84k
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aPropertyLine);
3143
1.84k
        }
3144
128k
        else {
3145
128k
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flags);
3146
128k
      if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
3147
469
        fxReportParserError(parser, parser->states[0].line, "invalid private property");
3148
469
      }
3149
128k
      else if ((aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER)) {
3150
901
        flags |= mxShorthandFlag;
3151
901
        if (aToken2 == XS_TOKEN_GETTER)
3152
800
          flags |= mxGetterFlag;
3153
101
        else if (aToken2 == XS_TOKEN_SETTER)
3154
101
          flags |= mxSetterFlag;
3155
901
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3156
891
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag);
3157
10
        else
3158
10
          fxReportParserError(parser, parser->states[0].line, "missing (");
3159
901
      }
3160
127k
      else if (aToken2 == XS_TOKEN_GENERATOR) {
3161
3.24k
        flags |= mxShorthandFlag | mxMethodFlag;
3162
3.24k
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3163
2.70k
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3164
536
        else
3165
536
          fxReportParserError(parser, parser->states[0].line, "missing (");
3166
3.24k
      }
3167
124k
      else if (aToken2 == XS_TOKEN_FUNCTION) {
3168
163
        flags |= mxShorthandFlag | mxMethodFlag;
3169
163
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3170
162
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3171
1
        else
3172
1
          fxReportParserError(parser, parser->states[0].line, "missing (");
3173
163
      }
3174
124k
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3175
2.50k
        flags |= mxShorthandFlag | mxMethodFlag;
3176
2.50k
        fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3177
2.50k
      }
3178
121k
      else if (parser->states[0].token == XS_TOKEN_COLON) {
3179
115k
        fxGetNextToken(parser);
3180
115k
        fxAssignmentExpression(parser);
3181
115k
      }
3182
5.57k
      else if (aToken1 == XS_TOKEN_PROPERTY) {
3183
4.20k
        flags |= mxShorthandFlag;
3184
4.20k
        fxPushSymbol(parser, aSymbol);
3185
4.20k
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
3186
2.38k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3187
2.38k
          fxGetNextToken(parser);
3188
2.38k
          fxAssignmentExpression(parser);
3189
2.38k
          fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aPropertyLine);
3190
2.38k
        }
3191
1.81k
        else if (aToken0 == XS_TOKEN_IDENTIFIER) {
3192
1.25k
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3193
1.25k
        }
3194
568
        else {
3195
568
          fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3196
568
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3197
568
        }
3198
4.20k
      }
3199
1.36k
      else {
3200
1.36k
        fxReportParserError(parser, parser->states[0].line, "missing :");
3201
1.36k
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3202
1.36k
      }
3203
128k
      fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
3204
128k
      parser->root->flags |= flags;
3205
128k
      fxCheckUniqueProperty(parser, base, parser->root); 
3206
128k
    }
3207
130k
    aCount++;
3208
130k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3209
36.3k
            break;
3210
94.2k
    fxMatchToken(parser, XS_TOKEN_COMMA);
3211
94.2k
  }
3212
90.9k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3213
90.9k
  fxPushNodeList(parser, aCount);
3214
90.9k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
3215
90.9k
}
3216
3217
void fxTemplateExpression(txParser* parser)
3218
1.09k
{
3219
1.09k
  txInteger aCount = 0;
3220
1.09k
  txInteger aLine = parser->states[0].line;
3221
1.09k
  fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3222
1.09k
  fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3223
1.09k
  fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3224
1.09k
  aCount++;
3225
5.33k
  for (;;) {
3226
5.33k
    fxGetNextToken(parser);
3227
5.33k
        if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3228
3.79k
            fxCommaExpression(parser);
3229
3.79k
            aCount++;
3230
3.79k
        }
3231
5.33k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3232
1
      fxReportParserError(parser, parser->states[0].line, "missing }");
3233
1
    }
3234
5.33k
    fxGetNextTokenTemplate(parser);
3235
5.33k
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3236
5.33k
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3237
5.33k
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3238
5.33k
    aCount++;
3239
5.33k
    if (parser->states[0].token == XS_TOKEN_TEMPLATE_TAIL) {
3240
1.07k
      fxGetNextToken(parser);
3241
1.07k
      break;
3242
1.07k
    }
3243
5.33k
  }
3244
1.09k
  fxPushNodeList(parser, aCount);
3245
1.09k
}
3246
3247
void fxYieldExpression(txParser* parser)
3248
19.8k
{
3249
19.8k
  txInteger aLine = parser->states[0].line;
3250
19.8k
  if (!(parser->flags & mxYieldFlag))
3251
34
    fxReportParserError(parser, parser->states[0].line, "invalid yield");
3252
19.8k
  else
3253
19.8k
    parser->flags |= mxYieldingFlag;
3254
19.8k
  fxMatchToken(parser, XS_TOKEN_YIELD);
3255
19.8k
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_MULTIPLY)) {
3256
1.27k
    fxGetNextToken(parser);
3257
1.27k
    fxAssignmentExpression(parser);
3258
1.27k
    fxPushNodeStruct(parser, 1, XS_TOKEN_DELEGATE, aLine);
3259
1.27k
    return;
3260
1.27k
  }
3261
18.6k
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3262
17.8k
    fxAssignmentExpression(parser);
3263
17.8k
  }
3264
805
  else {
3265
805
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
3266
805
  }
3267
18.6k
  fxPushNodeStruct(parser, 1, XS_TOKEN_YIELD, aLine);
3268
18.6k
}
3269
3270
void fxParameters(txParser* parser)
3271
332k
{
3272
332k
  txInteger aCount = 0;
3273
332k
  txInteger aLine = parser->states[0].line;
3274
332k
  txBoolean aSpreadFlag = 0;
3275
332k
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
3276
814k
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3277
482k
    txInteger aParamLine = parser->states[0].line;
3278
482k
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3279
677
      fxGetNextToken(parser);
3280
677
      fxAssignmentExpression(parser);
3281
677
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aParamLine);
3282
677
      aSpreadFlag = 1;
3283
677
    }
3284
481k
    else
3285
481k
      fxAssignmentExpression(parser);
3286
482k
    aCount++;
3287
482k
    if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3288
202k
      fxMatchToken(parser, XS_TOKEN_COMMA);
3289
482k
  }
3290
332k
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3291
332k
  fxPushNodeList(parser, aCount);
3292
332k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3293
332k
  if (aSpreadFlag)
3294
568
    parser->root->flags |= mxSpreadFlag;
3295
332k
}
3296
3297
void fxPropertyName(txParser* parser, txSymbol** theSymbol, txToken* theToken0, txToken* theToken1, txToken* theToken2, txUnsigned* flag)
3298
170k
{
3299
170k
  txSymbol* aSymbol = C_NULL;
3300
170k
  txToken aToken0 = XS_NO_TOKEN;
3301
170k
  txToken aToken1 = XS_NO_TOKEN;
3302
170k
  txToken aToken2 = XS_NO_TOKEN;
3303
170k
  txInteger aLine = parser->states[0].line;
3304
170k
  txIndex index;
3305
170k
  *flag = 0;
3306
170k
  fxLookAheadOnce(parser);
3307
170k
  aToken0 = parser->states[0].token;
3308
170k
  if ((gxTokenFlags[aToken0] & XS_TOKEN_IDENTIFIER_NAME)) {
3309
123k
    aSymbol = parser->states[0].symbol;
3310
123k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3311
97.6k
      fxPushSymbol(parser, aSymbol);
3312
97.6k
      aToken1 = XS_TOKEN_PROPERTY;
3313
97.6k
    }
3314
25.5k
    else if (fxIsKeyword(parser, parser->asyncSymbol) && (!parser->states[1].crlf)) {
3315
4.46k
      *flag = mxAsyncFlag;
3316
4.46k
      fxGetNextToken(parser);
3317
4.46k
      if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3318
3.20k
        aToken2 = XS_TOKEN_GENERATOR;
3319
3.20k
        fxGetNextToken(parser);
3320
3.20k
      }
3321
1.26k
      else
3322
1.26k
        aToken2 = XS_TOKEN_FUNCTION;
3323
4.46k
    }
3324
21.0k
    else if (fxIsKeyword(parser, parser->getSymbol)) {
3325
2.36k
      aToken2 = XS_TOKEN_GETTER;
3326
2.36k
      fxGetNextToken(parser);
3327
2.36k
    }
3328
18.7k
    else if (fxIsKeyword(parser, parser->setSymbol)) {
3329
728
      aToken2 = XS_TOKEN_SETTER;
3330
728
      fxGetNextToken(parser);
3331
728
    }
3332
17.9k
    else {
3333
17.9k
      fxPushSymbol(parser, aSymbol);
3334
17.9k
      aToken1 = XS_TOKEN_PROPERTY;
3335
17.9k
    }
3336
123k
  }
3337
47.7k
  else if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3338
4.28k
    aToken2 = XS_TOKEN_GENERATOR;
3339
4.28k
    fxGetNextToken(parser);
3340
4.28k
  }
3341
43.4k
  else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3342
7.81k
    aSymbol = parser->states[0].symbol;
3343
7.81k
    fxPushSymbol(parser, aSymbol);
3344
7.81k
    aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3345
7.81k
  }
3346
35.6k
  else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3347
13.0k
    if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3348
13.0k
      fxPushIndexNode(parser, index, aLine);
3349
13.0k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3350
13.0k
    }
3351
0
    else {
3352
0
      aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3353
0
      fxPushSymbol(parser, aSymbol);
3354
0
      aToken1 = XS_TOKEN_PROPERTY;
3355
0
    }
3356
13.0k
  }
3357
22.5k
  else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3358
454
    if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3359
79
      fxPushIndexNode(parser, index, aLine);
3360
79
      aToken1 = XS_TOKEN_PROPERTY_AT;
3361
79
    }
3362
375
    else {
3363
375
      aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3364
375
      fxPushSymbol(parser, aSymbol);
3365
375
      aToken1 = XS_TOKEN_PROPERTY;
3366
375
    }
3367
454
  }
3368
22.1k
  else if (parser->states[0].token == XS_TOKEN_STRING) {
3369
14.5k
    if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3370
4.68k
      fxPushIndexNode(parser, index, aLine);
3371
4.68k
      aToken1 = XS_TOKEN_PROPERTY_AT;
3372
4.68k
    }
3373
9.85k
    else {
3374
9.85k
      aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3375
9.85k
      fxPushSymbol(parser, aSymbol);
3376
9.85k
      aToken1 = XS_TOKEN_PROPERTY;
3377
9.85k
    }
3378
14.5k
  }
3379
7.56k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3380
4.01k
    fxGetNextToken(parser);
3381
4.01k
    fxCommaExpression(parser);
3382
4.01k
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3383
232
      fxReportParserError(parser, parser->states[0].line, "missing ]");
3384
232
    }
3385
4.01k
    aToken1 = XS_TOKEN_PROPERTY_AT;
3386
4.01k
  }
3387
3.55k
  else {
3388
3.55k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3389
3.55k
    fxPushNULL(parser);
3390
3.55k
  }
3391
170k
  if (aToken2 != XS_NO_TOKEN) {
3392
11.8k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3393
5.73k
      aSymbol = parser->states[0].symbol;
3394
5.73k
      fxPushSymbol(parser, aSymbol);
3395
5.73k
      aToken1 = XS_TOKEN_PROPERTY;
3396
5.73k
      fxGetNextToken(parser);
3397
5.73k
    }
3398
6.10k
    else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3399
217
      aSymbol = parser->states[0].symbol;
3400
217
      fxPushSymbol(parser, aSymbol);
3401
217
      aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3402
217
      fxGetNextToken(parser);
3403
217
    }
3404
5.89k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3405
1.56k
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3406
1.56k
        fxPushIndexNode(parser, index, aLine);
3407
1.56k
        aToken1 = XS_TOKEN_PROPERTY_AT;
3408
1.56k
      }
3409
0
      else {
3410
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3411
0
        fxPushSymbol(parser, aSymbol);
3412
0
        aToken1 = XS_TOKEN_PROPERTY;
3413
0
      }
3414
1.56k
      fxGetNextToken(parser);
3415
1.56k
    }
3416
4.32k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3417
836
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3418
5
        fxPushIndexNode(parser, index, aLine);
3419
5
        aToken1 = XS_TOKEN_PROPERTY_AT;
3420
5
      }
3421
831
      else {
3422
831
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3423
831
        fxPushSymbol(parser, aSymbol);
3424
831
        aToken1 = XS_TOKEN_PROPERTY;
3425
831
      }
3426
836
      fxGetNextToken(parser);
3427
836
    }
3428
3.49k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3429
1.30k
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3430
446
        fxPushIndexNode(parser, index, aLine);
3431
446
        aToken1 = XS_TOKEN_PROPERTY_AT;
3432
446
      }
3433
860
      else {
3434
860
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3435
860
        fxPushSymbol(parser, aSymbol);
3436
860
        aToken1 = XS_TOKEN_PROPERTY;
3437
860
      }
3438
1.30k
      fxGetNextToken(parser);
3439
1.30k
    }
3440
2.18k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3441
526
      fxGetNextToken(parser);
3442
526
      fxCommaExpression(parser);
3443
526
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3444
197
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3445
197
      }
3446
526
      aToken1 = XS_TOKEN_PROPERTY_AT;
3447
526
      fxGetNextToken(parser);
3448
526
    }
3449
1.66k
    else if (aToken2 == XS_TOKEN_GETTER) {
3450
1.18k
      fxPushSymbol(parser, aSymbol);
3451
1.18k
      aToken1 = XS_TOKEN_PROPERTY;
3452
1.18k
      aToken2 = XS_NO_TOKEN;
3453
1.18k
    }
3454
472
    else if (aToken2 == XS_TOKEN_SETTER) {
3455
192
      fxPushSymbol(parser, aSymbol);
3456
192
      aToken1 = XS_TOKEN_PROPERTY;
3457
192
      aToken2 = XS_NO_TOKEN;
3458
192
    }
3459
280
    else {
3460
280
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3461
280
      fxPushNULL(parser);
3462
280
    }
3463
11.8k
  }
3464
159k
  else
3465
159k
    fxGetNextToken(parser);
3466
170k
  *theSymbol = aSymbol;
3467
170k
  *theToken0 = aToken0;
3468
170k
  *theToken1 = aToken1;
3469
170k
  *theToken2 = aToken2;
3470
170k
}
3471
3472
void fxBinding(txParser* parser, txToken theToken, txUnsigned flags)
3473
183k
{
3474
183k
  txInteger aLine = parser->states[0].line;
3475
183k
  fxCheckParserStack(parser, aLine);
3476
183k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3477
152k
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
3478
152k
    if (((theToken == XS_TOKEN_CONST) || (theToken == XS_TOKEN_LET) || (theToken == XS_TOKEN_USING)) && (parser->states[0].symbol == parser->letSymbol))
3479
273
      fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3480
152k
    fxPushSymbol(parser, parser->states[0].symbol);
3481
152k
    fxPushNodeStruct(parser, 1, theToken, aLine);
3482
152k
    if (flags & mxAwaitingFlag)
3483
0
      parser->root->flags |= mxAwaitingFlag;
3484
152k
    fxGetNextToken(parser);
3485
152k
  }
3486
31.0k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
3487
11.4k
    if (theToken == XS_TOKEN_USING)
3488
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3489
11.4k
    fxObjectBinding(parser, theToken);
3490
11.4k
  }
3491
19.6k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3492
18.6k
    if (theToken == XS_TOKEN_USING)
3493
1
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3494
18.6k
    fxArrayBinding(parser, theToken);
3495
18.6k
  }
3496
995
  else {
3497
995
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3498
995
    fxPushNULL(parser);
3499
995
  }
3500
183k
  if ((flags & 1) && (parser->states[0].token == XS_TOKEN_ASSIGN)) {
3501
79.3k
    parser->flags &= ~mxForFlag;
3502
79.3k
    fxGetNextToken(parser);
3503
79.3k
    fxAssignmentExpression(parser);
3504
79.3k
    fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aLine);
3505
79.3k
  }
3506
183k
}
3507
3508
txNode* fxBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3509
89.6k
{
3510
89.6k
  txToken aToken = (theNode && theNode->description) ? theNode->description->token : XS_NO_TOKEN;
3511
89.6k
  txNode* binding;
3512
89.7k
again:
3513
89.7k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
3514
751
    txNode* item = ((txExpressionsNode*)theNode)->items->first;
3515
751
    if (item && !item->next) {
3516
726
      aToken = item->description->token;
3517
726
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3518
668
        item->next = theNode->next;
3519
668
        theNode = item;
3520
668
      }
3521
58
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
3522
57
        item->next = theNode->next;
3523
57
        theNode = item;
3524
57
        goto again;
3525
57
      }
3526
1
      else
3527
1
        return NULL;
3528
726
    }
3529
751
  }
3530
89.6k
  if (aToken == XS_TOKEN_BINDING) {
3531
25.6k
    binding = fxBindingFromExpression(parser, ((txBindingNode*)theNode)->target, theToken);
3532
25.6k
    ((txBindingNode*)theNode)->target = binding;
3533
//    fxCheckStrictBinding(parser, theNode);
3534
//    fxCheckStrictSymbol(parser, ((txBindingNode*)theNode)->symbol);
3535
//    theNode->description = &gxTokenDescriptions[theToken];
3536
25.6k
    return theNode;
3537
25.6k
  }
3538
64.0k
  if (aToken == XS_TOKEN_ARRAY_BINDING) {
3539
37.0k
    txNodeList* list = ((txArrayBindingNode*)theNode)->items;
3540
37.0k
    txNode** address = &(list->first);
3541
37.0k
    txNode* item;
3542
74.3k
    while ((item = *address)) {
3543
37.3k
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3544
37.3k
      binding->next = item->next;
3545
37.3k
      address = &(binding->next);
3546
37.3k
    }
3547
37.0k
    return theNode;
3548
37.0k
  }
3549
27.0k
  if (aToken == XS_TOKEN_OBJECT_BINDING) {
3550
959
    txNodeList* list = ((txObjectBindingNode*)theNode)->items;
3551
959
    txNode** address = &(list->first);
3552
959
    txNode* item;
3553
2.37k
    while ((item = *address)) {
3554
1.41k
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3555
1.41k
      binding->next = item->next;
3556
1.41k
      address = &(binding->next);
3557
1.41k
    }
3558
959
    return theNode;
3559
959
  }
3560
26.1k
  if (aToken == XS_TOKEN_PROPERTY_BINDING) {
3561
1.41k
    ((txPropertyBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingNode*)theNode)->binding, theToken);
3562
1.41k
    return theNode;
3563
1.41k
  }
3564
24.6k
  if (aToken == XS_TOKEN_PROPERTY_BINDING_AT) {
3565
0
    ((txPropertyBindingAtNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingAtNode*)theNode)->binding, theToken);
3566
0
    return theNode;
3567
0
  }
3568
24.6k
  if (aToken == XS_TOKEN_REST_BINDING) {
3569
108
    ((txRestBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txRestBindingNode*)theNode)->binding, theToken);
3570
108
    return theNode;
3571
108
  }
3572
24.5k
  if (aToken == XS_TOKEN_SKIP_BINDING)
3573
323
    return theNode;
3574
  
3575
24.2k
  if (aToken == XS_TOKEN_ACCESS) {
3576
15.3k
    fxCheckStrictSymbol(parser, ((txAccessNode*)theNode)->symbol);
3577
15.3k
    if (theToken == XS_TOKEN_ACCESS)
3578
5.02k
      return theNode;
3579
10.3k
    fxPushSymbol(parser, ((txAccessNode*)theNode)->symbol);
3580
10.3k
    fxPushNodeStruct(parser, 1, theToken, ((txAccessNode*)theNode)->line);
3581
10.3k
    return fxPopNode(parser);
3582
15.3k
  }
3583
8.91k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3584
2.28k
    return theNode;
3585
2.28k
  }
3586
6.63k
  if (aToken == XS_TOKEN_ASSIGN) {
3587
1.49k
    binding = fxBindingFromExpression(parser, ((txAssignNode*)theNode)->reference, theToken);
3588
1.49k
    if (!binding)
3589
0
      return NULL;
3590
1.49k
    ((txBindingNode*)theNode)->description = &gxTokenDescriptions[XS_TOKEN_BINDING];
3591
1.49k
    ((txBindingNode*)theNode)->target = binding;
3592
1.49k
    ((txBindingNode*)theNode)->initializer = ((txAssignNode*)theNode)->value;
3593
1.49k
    return theNode;
3594
1.49k
  }
3595
  
3596
5.14k
  if (aToken == XS_TOKEN_ARRAY)
3597
1.02k
    return fxArrayBindingFromExpression(parser, theNode, theToken);
3598
4.11k
  if (aToken == XS_TOKEN_OBJECT)
3599
161
    return fxObjectBindingFromExpression(parser, theNode, theToken);
3600
3.95k
  return NULL;
3601
4.11k
}
3602
3603
void fxArrayBinding(txParser* parser, txToken theToken)
3604
18.6k
{
3605
18.6k
  txInteger aCount = 0;
3606
18.6k
  txInteger aLine = parser->states[0].line;
3607
18.6k
  int elision = 1;
3608
18.6k
  fxCheckParserStack(parser, aLine);
3609
18.6k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
3610
25.9k
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING)) {
3611
7.35k
    txInteger anItemLine = parser->states[0].line;
3612
7.35k
    if (parser->states[0].token == XS_TOKEN_COMMA) {
3613
3.52k
      fxGetNextToken(parser);
3614
3.52k
      if (elision) {
3615
1.32k
        fxPushNodeStruct(parser, 0, XS_TOKEN_SKIP_BINDING, anItemLine);
3616
1.32k
        aCount++;
3617
1.32k
      }
3618
2.19k
      else
3619
2.19k
        elision = 1;
3620
3.52k
    }
3621
3.83k
    else {
3622
3.83k
      if (!elision)
3623
289
        fxReportParserError(parser, parser->states[0].line, "missing ,");
3624
3.83k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3625
38
        fxRestBinding(parser, theToken, 0);
3626
38
        aCount++;
3627
38
        break;
3628
38
      }
3629
3.79k
      fxBinding(parser, theToken, 1);
3630
3.79k
      aCount++;
3631
3.79k
      elision = 0;
3632
3.79k
    }
3633
7.35k
  }
3634
18.6k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3635
18.6k
  fxPushNodeList(parser, aCount);
3636
18.6k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, aLine);
3637
18.6k
}
3638
3639
txNode* fxArrayBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3640
5.49k
{
3641
5.49k
  txNodeList* list = ((txArrayNode*)theNode)->items;
3642
5.49k
  txNode** address = &(list->first);
3643
5.49k
  txNode* item;
3644
5.49k
  txNode* binding;
3645
8.73k
  while ((item = *address)) {
3646
7.21k
        if (!item->description) {
3647
0
            parser->errorSymbol = parser->SyntaxErrorSymbol;
3648
0
            return NULL;
3649
0
        }
3650
7.21k
    if (item->description->token == XS_TOKEN_SPREAD) {
3651
156
      if (theNode->flags & mxElisionFlag) {
3652
1
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3653
1
        return NULL;
3654
1
      }
3655
155
      binding = fxRestBindingFromExpression(parser, item, theToken, 0);
3656
155
      if (!binding) {
3657
6
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3658
6
        return NULL;
3659
6
      }
3660
149
      break;
3661
155
    }
3662
7.06k
    if (item->description->token == XS_TOKEN_ELISION) {
3663
418
      item->description = &gxTokenDescriptions[XS_TOKEN_SKIP_BINDING];
3664
418
    }
3665
6.64k
    else {
3666
//      if ((theToken == XS_TOKEN_BINDING) && ((item->description->token== XS_TOKEN_MEMBER) || (item->description->token == XS_TOKEN_MEMBER_AT)))
3667
//        binding = item;
3668
//      else {      
3669
6.64k
        binding = fxBindingFromExpression(parser, item, theToken);
3670
6.64k
        if (!binding) {
3671
3.82k
          parser->errorSymbol = parser->SyntaxErrorSymbol;
3672
3.82k
          return NULL;
3673
3.82k
        }
3674
2.82k
        binding->next = item->next;
3675
2.82k
        item = *address = binding;
3676
//      }
3677
2.82k
    }
3678
3.24k
    address = &(item->next);
3679
3.24k
  }
3680
1.67k
  fxPushNode(parser, (txNode*)list);
3681
1.67k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, theNode->line);
3682
1.67k
  return fxPopNode(parser);
3683
5.49k
}
3684
3685
txUnsigned fxObjectBinding(txParser* parser, txToken theToken)
3686
11.4k
{
3687
11.4k
  txUnsigned flags = 0;
3688
11.4k
  txInteger aCount = 0;
3689
11.4k
  txInteger aLine = parser->states[0].line;
3690
11.4k
  txSymbol* aSymbol;
3691
11.4k
  txToken aToken;
3692
11.4k
  txIndex index;
3693
11.4k
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3694
13.1k
  for (;;) {
3695
13.1k
    txInteger aPropertyLine = parser->states[0].line;
3696
13.1k
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3697
2.44k
      break;
3698
10.7k
    aSymbol = NULL;
3699
10.7k
    aToken = XS_TOKEN_PROPERTY_BINDING;
3700
10.7k
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3701
4.49k
      aSymbol = parser->states[0].symbol;
3702
4.49k
      fxPushSymbol(parser, aSymbol);
3703
4.49k
      aToken = XS_TOKEN_PROPERTY_BINDING;
3704
4.49k
    }
3705
6.23k
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3706
1.33k
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3707
1.33k
        fxPushIndexNode(parser, index, aPropertyLine);
3708
1.33k
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3709
1.33k
      }
3710
0
      else {
3711
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3712
0
        fxPushSymbol(parser, aSymbol);
3713
0
        aToken = XS_TOKEN_PROPERTY_BINDING;
3714
0
      }
3715
1.33k
    }
3716
4.89k
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3717
85
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3718
4
        fxPushIndexNode(parser, index, aPropertyLine);
3719
4
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3720
4
      }
3721
81
      else {
3722
81
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3723
81
        fxPushSymbol(parser, aSymbol);
3724
81
        aToken = XS_TOKEN_PROPERTY_BINDING;
3725
81
      }
3726
85
    }
3727
4.81k
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3728
682
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3729
22
        fxPushIndexNode(parser, index, aPropertyLine);
3730
22
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3731
22
      }
3732
660
      else {
3733
660
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3734
660
        fxPushSymbol(parser, aSymbol);
3735
660
        aToken = XS_TOKEN_PROPERTY_BINDING;
3736
660
      }
3737
682
    }
3738
4.12k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3739
3.66k
      fxGetNextToken(parser);
3740
3.66k
      fxCommaExpression(parser);
3741
3.66k
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3742
1.00k
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3743
1.00k
      }
3744
3.66k
      aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3745
3.66k
    }
3746
460
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
3747
118
      flags |= mxSpreadFlag;
3748
118
      fxRestBinding(parser, theToken, 1);
3749
118
      aCount++;
3750
118
            break;
3751
118
    }
3752
342
    else {
3753
342
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3754
342
      fxPushNULL(parser);
3755
342
    }
3756
10.6k
    fxLookAheadOnce(parser);
3757
10.6k
    if (parser->states[1].token == XS_TOKEN_COLON) {
3758
634
      fxGetNextToken(parser);
3759
634
      fxGetNextToken(parser);
3760
634
      fxBinding(parser, theToken, 1);
3761
634
    }
3762
9.97k
    else if (aSymbol) {
3763
4.61k
      fxBinding(parser, theToken, 1);
3764
4.61k
    }
3765
5.36k
    else {
3766
5.36k
      fxReportParserError(parser, parser->states[0].line, "missing :");
3767
5.36k
      fxPushNULL(parser);
3768
5.36k
    }
3769
10.6k
    fxPushNodeStruct(parser, 2, aToken, aPropertyLine);
3770
10.6k
    aCount++;
3771
10.6k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3772
1.59k
            break;
3773
9.01k
    if (parser->states[0].token == XS_TOKEN_COMMA)
3774
1.71k
      fxGetNextToken(parser);
3775
7.29k
    else
3776
7.29k
            break;
3777
9.01k
  }
3778
11.4k
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3779
11.4k
  fxPushNodeList(parser, aCount);
3780
11.4k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, aLine);
3781
11.4k
  parser->root->flags |= flags;
3782
11.4k
  return flags;
3783
11.4k
}
3784
3785
txNode* fxObjectBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3786
14.1k
{
3787
14.1k
  txNodeList* list = ((txObjectNode*)theNode)->items;
3788
14.1k
  txNode* property = list->first;
3789
14.1k
  txNode* binding;
3790
14.1k
  txUnsigned flags = 0;
3791
19.8k
  while (property) {
3792
6.80k
    if (!property->description) {
3793
0
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3794
0
      return NULL;
3795
0
    }
3796
6.80k
    if (property->description->token == XS_TOKEN_PROPERTY) {
3797
3.72k
      binding = fxBindingFromExpression(parser, ((txPropertyNode*)property)->value, theToken);
3798
3.72k
      if (!binding) {
3799
92
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3800
92
        return NULL;
3801
92
      }
3802
3.63k
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING];
3803
3.63k
      ((txPropertyBindingNode*)property)->binding = binding;
3804
3.63k
    }
3805
3.08k
    else if (property->description->token == XS_TOKEN_PROPERTY_AT) {
3806
2.07k
      binding = fxBindingFromExpression(parser, ((txPropertyAtNode*)property)->value, theToken);
3807
2.07k
      if (!binding) {
3808
10
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3809
10
        return NULL;
3810
10
      }
3811
2.06k
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING_AT];
3812
2.06k
      ((txPropertyBindingAtNode*)property)->binding = binding;
3813
2.06k
    }
3814
1.00k
    else if (property->description->token == XS_TOKEN_SPREAD) {
3815
1.00k
      binding = fxRestBindingFromExpression(parser, property, theToken, 1);
3816
1.00k
      if (!binding) {
3817
56
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3818
56
        return NULL;
3819
56
      }
3820
952
      flags |= mxSpreadFlag;
3821
952
      break;
3822
1.00k
    }
3823
5.69k
    property = property->next;
3824
5.69k
  }
3825
13.9k
  fxPushNode(parser, (txNode*)list);
3826
13.9k
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, theNode->line);
3827
13.9k
  parser->root->flags |= flags;
3828
13.9k
  return fxPopNode(parser);
3829
14.1k
}
3830
3831
void fxParametersBinding(txParser* parser)
3832
240k
{
3833
240k
  txInteger aCount = 0;
3834
240k
  txInteger aLine = parser->states[0].line;
3835
240k
  txBindingNode* binding;
3836
240k
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3837
238k
    fxGetNextToken(parser);
3838
252k
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
3839
14.1k
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3840
360
        parser->flags |= mxNotSimpleParametersFlag;
3841
360
        fxRestBinding(parser, XS_TOKEN_ARG, 0);
3842
360
        aCount++;
3843
360
        break;
3844
360
      }
3845
13.7k
      fxBinding(parser, XS_TOKEN_ARG, 1);
3846
13.7k
      binding = (txBindingNode*)parser->root;
3847
13.7k
      if (binding->description->token != XS_TOKEN_ARG)
3848
615
        parser->flags |= mxNotSimpleParametersFlag;
3849
13.7k
      aCount++;
3850
13.7k
      if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3851
6.08k
        fxMatchToken(parser, XS_TOKEN_COMMA);
3852
13.7k
    }
3853
238k
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3854
238k
  }
3855
2.02k
  else
3856
2.02k
    fxReportParserError(parser, parser->states[0].line, "missing (");
3857
240k
  fxPushNodeList(parser, aCount);
3858
240k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
3859
240k
}
3860
3861
txNode* fxParametersBindingFromExpressions(txParser* parser, txNode* theNode)
3862
40.0k
{
3863
40.0k
  txNodeList* list = ((txParamsNode*)theNode)->items;
3864
40.0k
  txNode** address = &(list->first);
3865
40.0k
  txNode* item;
3866
40.0k
  txBindingNode* binding;
3867
48.5k
  while ((item = *address)) {
3868
8.75k
    txToken aToken = (item && item->description) ? item->description->token : XS_NO_TOKEN;
3869
8.75k
    if (aToken == XS_TOKEN_SPREAD) {
3870
16
      binding = (txBindingNode*)fxRestBindingFromExpression(parser, item, XS_TOKEN_ARG, 0);
3871
16
      if (!binding)
3872
1
        return NULL;
3873
15
      parser->flags |= mxNotSimpleParametersFlag;
3874
15
      break;
3875
16
    }
3876
8.73k
    binding = (txBindingNode*)fxBindingFromExpression(parser, item, XS_TOKEN_ARG);
3877
8.73k
    if (!binding)
3878
264
      return NULL;
3879
8.47k
    if (binding->description->token != XS_TOKEN_ARG)
3880
1.11k
      parser->flags |= mxNotSimpleParametersFlag;
3881
8.47k
    binding->next = item->next;
3882
8.47k
    item = *address = (txNode*)binding;
3883
8.47k
    address = &(item->next);
3884
8.47k
  }
3885
39.8k
  theNode->description = &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING];
3886
39.8k
  return theNode;
3887
40.0k
}
3888
3889
void fxRestBinding(txParser* parser, txToken theToken, txUnsigned flag)
3890
516
{
3891
516
  txInteger aLine = parser->states[0].line;
3892
516
  fxMatchToken(parser, XS_TOKEN_SPREAD);
3893
516
  fxBinding(parser, theToken, 0);
3894
516
  if (flag && ((parser->root->description->token == XS_TOKEN_ARRAY_BINDING) || (parser->root->description->token == XS_TOKEN_OBJECT_BINDING))) {
3895
64
    fxReportParserError(parser, parser->states[0].line, "invalid rest");
3896
64
  }
3897
516
  fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
3898
516
}
3899
3900
txNode* fxRestBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken, txUnsigned flag)
3901
1.17k
{
3902
1.17k
  txNode* expression = ((txSpreadNode*)theNode)->expression;
3903
1.17k
  txNode* binding;
3904
1.17k
  if (theNode->next) {
3905
3
    parser->errorSymbol = parser->SyntaxErrorSymbol;
3906
3
    return NULL;
3907
3
  }
3908
1.17k
  if (!expression)
3909
0
    return NULL;
3910
/*  if ((theToken == XS_TOKEN_BINDING) && ((expression->description->token == XS_TOKEN_MEMBER) || (expression->description->token == XS_TOKEN_MEMBER_AT)))
3911
    binding = expression;
3912
  else */
3913
1.17k
  {
3914
1.17k
    binding = fxBindingFromExpression(parser, expression, theToken);
3915
1.17k
    if (!binding) {
3916
60
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3917
60
      return NULL;
3918
60
    }
3919
1.11k
    if (binding->description->token == XS_TOKEN_BINDING) {
3920
59
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3921
59
      return NULL;
3922
59
    }
3923
1.05k
    if (flag && ((binding->description->token == XS_TOKEN_ARRAY_BINDING) || (binding->description->token == XS_TOKEN_OBJECT_BINDING))) {
3924
93
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3925
93
      return NULL;
3926
93
    }
3927
1.05k
  }
3928
964
  theNode->description = &gxTokenDescriptions[XS_TOKEN_REST_BINDING];
3929
964
  ((txRestBindingNode*)theNode)->binding = binding;
3930
964
  return theNode;
3931
1.05k
}
3932
3933
void fxCheckArrowFunction(txParser* parser, txInteger count)
3934
13.6M
{
3935
13.6M
  txNode* node = parser->root;
3936
40.3M
  while (count) {
3937
26.6M
    if (node->flags & mxArrowFlag)
3938
15.8k
      fxReportParserError(parser, parser->states[0].line, "invalid arrow function");
3939
26.6M
    count--;
3940
26.6M
    node = node->next;
3941
26.6M
  }
3942
13.6M
}
3943
3944
static void fxReportWarning(txParser* parser, txInteger line, txString theFormat, ...)
3945
0
{
3946
0
  c_va_list arguments;
3947
0
  c_va_start(arguments, theFormat);
3948
0
    (*parser->reportWarning)(parser->console, parser->path ? parser->path->string : C_NULL, line, theFormat, arguments);
3949
0
  c_va_end(arguments);
3950
0
}
3951
3952
void fxCheckNativeConstructor(txParser* parser)
3953
638
{
3954
638
  txClassNode* root = (txClassNode*)(parser->root);
3955
638
  if (root->description != &gxTokenDescriptions[XS_TOKEN_CLASS])
3956
605
    return;
3957
33
  if (root->symbol != C_NULL)
3958
5
    return;
3959
28
  txHostNode* host = (txHostNode*)(root->heritage);
3960
28
  if (host == C_NULL)
3961
27
    return;
3962
1
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
3963
1
    return;
3964
0
  if (root->constructorInit != C_NULL)
3965
0
    return;
3966
0
  if (root->instanceInit != C_NULL)
3967
0
    return;
3968
0
  txFunctionNode* constructor = (txFunctionNode*)(root->constructor);
3969
0
  if (constructor->description != &gxTokenDescriptions[XS_TOKEN_FUNCTION])
3970
0
    return;
3971
0
  txParamsBindingNode* args = (txParamsBindingNode*)(constructor->params);
3972
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
3973
0
    return;
3974
0
  if (args->items->length != 0)
3975
0
    return;
3976
0
  txBodyNode* body = (txBodyNode*)(constructor->body);
3977
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3978
0
    return;
3979
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3980
0
  if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
3981
0
    return;
3982
0
  txNode* undefined = (txNode*)(statement->expression);
3983
0
  if (undefined->description != &gxTokenDescriptions[XS_TOKEN_UNDEFINED])
3984
0
    return;
3985
0
  fxPopNode(parser);
3986
0
  fxPushNode(parser, (txNode*)host);
3987
0
}
3988
3989
void fxCheckNativeFunction(txParser* parser)
3990
0
{
3991
0
  txFunctionNode* function = (txFunctionNode*)(parser->root);
3992
0
  txBodyNode* body = (txBodyNode*)(function->body);
3993
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3994
0
    goto bail;
3995
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3996
0
  if ((function->flags & mxDerivedFlag) && (function->flags & mxHostFlag)) {
3997
0
    txStatementsNode* statements = (txStatementsNode*)(statement);
3998
0
    if (statements->description != &gxTokenDescriptions[XS_TOKEN_STATEMENTS])
3999
0
      goto bail;
4000
0
    if (statements->items->length != 2)
4001
0
      goto bail;
4002
0
    statement = (txStatementNode*)(statements->items->first);
4003
0
    if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
4004
0
      goto bail;
4005
0
    txSuperNode* super = (txSuperNode*)(statement->expression);
4006
0
    if (super->description != &gxTokenDescriptions[XS_TOKEN_SUPER])
4007
0
      goto bail;
4008
0
    txParamsNode* params = (txParamsNode*)(super->params);
4009
0
    if (params->items->length != 0)
4010
0
      goto bail;
4011
0
    statement = (txStatementNode*)(statement->next);
4012
0
  }
4013
0
  if ((statement->description != &gxTokenDescriptions[XS_TOKEN_RETURN]) && (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT]))
4014
0
    goto bail;
4015
0
  txCallNewNode* call = (txCallNewNode*)(statement->expression);
4016
0
  if (call->description != &gxTokenDescriptions[XS_TOKEN_CALL])
4017
0
    goto bail;
4018
0
  txMemberNode* member = (txMemberNode*)(call->reference);
4019
0
  if (member->description != &gxTokenDescriptions[XS_TOKEN_MEMBER])
4020
0
    goto bail;
4021
0
  if (member->symbol != parser->callSymbol)
4022
0
    goto bail;
4023
0
  txHostNode* host = (txHostNode*)(member->reference);
4024
0
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
4025
0
    goto bail;
4026
0
  txParamsNode* params = (txParamsNode*)(call->params);
4027
0
  if (params->description != &gxTokenDescriptions[XS_TOKEN_PARAMS])
4028
0
    goto bail;
4029
0
  txParamsBindingNode* args = (txParamsBindingNode*)(function->params);
4030
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
4031
0
    goto bail;
4032
0
  if (params->items->length != args->items->length + 1)
4033
0
    goto bail;
4034
0
  txNode* arg = args->items->first;
4035
0
  txNode* param = params->items->first;
4036
0
  if (param->description != &gxTokenDescriptions[XS_TOKEN_THIS])
4037
0
    goto bail;
4038
0
  param = param->next;
4039
0
  while (arg) {
4040
0
    txDeclareNode* binding;
4041
0
    txAccessNode* access;
4042
0
    if (arg->description == &gxTokenDescriptions[XS_TOKEN_REST_BINDING]) {
4043
0
      if (param->description != &gxTokenDescriptions[XS_TOKEN_SPREAD])
4044
0
        goto bail;
4045
0
      binding = (txDeclareNode*)(((txRestBindingNode*)arg)->binding);
4046
0
      access = (txAccessNode*)(((txSpreadNode*)param)->expression);
4047
0
    }
4048
0
    else {
4049
0
      binding = (txDeclareNode*)arg;
4050
0
      access = (txAccessNode*)param;
4051
0
    }
4052
0
    if (binding->description != &gxTokenDescriptions[XS_TOKEN_ARG])
4053
0
      goto bail;
4054
0
    if (access->description != &gxTokenDescriptions[XS_TOKEN_ACCESS])
4055
0
      goto bail;
4056
0
    if (binding->symbol != access->symbol)
4057
0
      goto bail;
4058
0
    arg = arg->next;
4059
0
    param = param->next;
4060
0
  }
4061
0
  host->flags |= function->flags;
4062
0
  host->params = (txNode*)args;
4063
0
  fxPopNode(parser);
4064
0
  fxPushNode(parser, (txNode*)host);
4065
0
  return;
4066
0
bail:
4067
0
    fxReportWarning(parser, function->line, "cannot optimize native");
4068
0
}
4069
4070
txBoolean fxCheckReference(txParser* parser, txToken theToken)
4071
186k
{
4072
186k
  txNode* node = parser->root;
4073
186k
  txToken aToken = (node && node->description) ? node->description->token : XS_NO_TOKEN;
4074
186k
  if (aToken == XS_TOKEN_EXPRESSIONS) {
4075
1.56k
    txNode* item;
4076
1.83k
  again:
4077
1.83k
    item = ((txExpressionsNode*)node)->items->first;
4078
1.83k
    if (item && !item->next) {
4079
1.70k
      aToken = (item->description) ? item->description->token : XS_NO_TOKEN;
4080
1.70k
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
4081
393
        item->next = node->next;
4082
393
        node = parser->root = item;
4083
393
      }
4084
1.31k
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
4085
272
        item->next = node->next;
4086
272
        node = item;
4087
272
        goto again;
4088
272
      }
4089
1.03k
      else
4090
1.03k
        aToken = XS_TOKEN_EXPRESSIONS;
4091
1.70k
    }
4092
1.83k
  }
4093
186k
  if (aToken == XS_TOKEN_ACCESS) {
4094
136k
    fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4095
136k
    return 1;
4096
136k
  }
4097
49.9k
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED))
4098
23.9k
    return 1;
4099
    
4100
25.9k
  if (theToken == XS_TOKEN_ASSIGN) {
4101
20.8k
    if (aToken == XS_TOKEN_ARRAY) {
4102
4.47k
      txNode* binding = fxArrayBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4103
4.47k
            if (binding) {
4104
844
                binding->next = node->next;
4105
844
                parser->root = binding;
4106
844
        return 1;
4107
844
           }
4108
4.47k
        }
4109
16.3k
    else if (aToken == XS_TOKEN_OBJECT) {
4110
13.9k
      txNode* binding = fxObjectBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4111
13.9k
            if (binding) {
4112
13.7k
                binding->next = node->next;
4113
13.7k
                parser->root = binding;
4114
13.7k
        return 1;
4115
13.7k
            }
4116
13.9k
        }
4117
20.8k
  }
4118
5.11k
  else if (theToken == XS_TOKEN_DELETE)
4119
1.50k
    return 1;
4120
9.85k
  return 0;
4121
25.9k
}
4122
4123
void fxCheckStrictBinding(txParser* parser, txNode* node)
4124
55.4k
{
4125
55.4k
  if (node && node->description) {
4126
55.4k
    if (node->description->token == XS_TOKEN_ACCESS) {
4127
0
      fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4128
0
    }
4129
55.4k
    else if (node->description->token == XS_TOKEN_ARG) {
4130
10.4k
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4131
10.4k
    }
4132
45.0k
    else if (node->description->token == XS_TOKEN_CONST) {
4133
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4134
0
    }
4135
45.0k
    else if (node->description->token == XS_TOKEN_LET) {
4136
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4137
0
    }
4138
45.0k
    else if (node->description->token == XS_TOKEN_USING) {
4139
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4140
0
    }
4141
45.0k
    else if (node->description->token == XS_TOKEN_VAR) {
4142
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4143
0
    }
4144
45.0k
    else if (node->description->token == XS_TOKEN_BINDING) {
4145
704
      fxCheckStrictBinding(parser, ((txBindingNode*)node)->target);
4146
704
    }
4147
44.3k
    else if (node->description->token == XS_TOKEN_ARRAY_BINDING) {
4148
355
      node = ((txArrayBindingNode*)node)->items->first;
4149
1.69k
      while (node) {
4150
1.34k
        fxCheckStrictBinding(parser, node);
4151
1.34k
        node = node->next;
4152
1.34k
      }
4153
355
    }
4154
43.9k
    else if (node->description->token == XS_TOKEN_OBJECT_BINDING) {
4155
736
      node = ((txObjectBindingNode*)node)->items->first;
4156
2.17k
      while (node) {
4157
1.44k
        fxCheckStrictBinding(parser, node);
4158
1.44k
        node = node->next;
4159
1.44k
      }
4160
736
    }
4161
43.2k
    else if (node->description->token == XS_TOKEN_PARAMS_BINDING) {
4162
41.5k
      node = ((txParamsBindingNode*)node)->items->first;
4163
50.5k
      while (node) {
4164
8.92k
        fxCheckStrictBinding(parser, node);
4165
8.92k
        node = node->next;
4166
8.92k
      }
4167
41.5k
    }
4168
1.65k
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING)
4169
1.43k
      fxCheckStrictBinding(parser, ((txPropertyBindingNode*)node)->binding);
4170
219
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING_AT)
4171
11
      fxCheckStrictBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
4172
208
    else if (node->description->token == XS_TOKEN_REST_BINDING)
4173
15
      fxCheckStrictBinding(parser, ((txRestBindingNode*)node)->binding);
4174
55.4k
  }
4175
55.4k
}
4176
4177
void fxCheckStrictFunction(txParser* parser, txFunctionNode* function)
4178
1.75k
{
4179
1.75k
  parser->states[0].line = function->line;
4180
1.75k
  fxCheckStrictSymbol(parser, function->symbol);
4181
1.75k
  fxCheckStrictBinding(parser, function->params);
4182
1.75k
}
4183
4184
void fxCheckStrictSymbol(txParser* parser, txSymbol* symbol)
4185
500k
{
4186
500k
  if (parser->flags & mxStrictFlag) {
4187
18.0k
    if (symbol == parser->argumentsSymbol)
4188
3
      fxReportParserError(parser, parser->states[0].line, "invalid arguments (strict mode)");
4189
18.0k
    else if (symbol == parser->evalSymbol)
4190
81
      fxReportParserError(parser, parser->states[0].line, "invalid eval (strict mode)");
4191
17.9k
    else if (symbol == parser->yieldSymbol)
4192
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield (strict mode)");
4193
18.0k
  }
4194
482k
  else if (parser->flags & mxYieldFlag) {
4195
4.53k
    if (symbol == parser->yieldSymbol)
4196
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
4197
4.53k
  }
4198
500k
}
4199
4200
void fxCheckUniqueProperty(txParser* parser, txNode* base, txNode* current)
4201
106k
{
4202
106k
  return; // no more!
4203
0
  if (current->description->token == XS_TOKEN_PROPERTY) {
4204
0
    txPropertyNode* currentNode = (txPropertyNode*)current;
4205
0
    while (base != current) {
4206
0
      txPropertyNode* baseNode = (txPropertyNode*)base;
4207
0
      if (baseNode->description->token == XS_TOKEN_PROPERTY) {
4208
0
        if (baseNode->symbol == currentNode->symbol) {
4209
0
          fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4210
0
        }
4211
0
      }
4212
0
      base = base->next;
4213
0
    }
4214
0
  }
4215
0
  else {
4216
0
    txPropertyAtNode* currentNode = (txPropertyAtNode*)current;
4217
0
    txIntegerNode* currentAt = (txIntegerNode*)(currentNode->at);
4218
0
    if (currentAt->description->token == XS_TOKEN_INTEGER) {
4219
0
      while (base != current) {
4220
0
        txPropertyAtNode* baseNode = (txPropertyAtNode*)base;
4221
0
        if (baseNode->description->token == XS_TOKEN_PROPERTY_AT) {
4222
0
          txIntegerNode* baseAt = (txIntegerNode*)(baseNode->at);
4223
0
          if (baseAt->description->token == XS_TOKEN_INTEGER) {
4224
0
            if (baseAt->value == currentAt->value) {
4225
0
              fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4226
0
            }
4227
0
          }
4228
0
        }
4229
0
        base = base->next;
4230
0
      }
4231
0
    }
4232
0
  }
4233
0
}
4234
4235
void fxCheckUniquePropertyAux(txParser* parser, txNode* baseNode, txNode* currentNode)
4236
0
{
4237
0
  if (currentNode->flags & mxGetterFlag) {
4238
0
    if (baseNode->flags & mxGetterFlag)
4239
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4240
0
    else if (!(baseNode->flags & mxSetterFlag))
4241
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4242
0
  }
4243
0
  else if (currentNode->flags & mxSetterFlag) {
4244
0
    if (baseNode->flags & mxSetterFlag)
4245
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4246
0
    else if (!(baseNode->flags & mxGetterFlag))
4247
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4248
0
  }
4249
0
  else {
4250
0
    if (baseNode->flags & mxGetterFlag)
4251
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4252
0
    else if (baseNode->flags & mxSetterFlag)
4253
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4254
0
    else if (parser->flags & mxStrictFlag)
4255
0
      fxReportParserError(parser, parser->states[0].line, "property already defined (strict mode)");
4256
0
  }
4257
0
}
4258
4259
4260
void fxJSONValue(txParser* parser)
4261
0
{
4262
0
  switch (parser->states[0].token) {
4263
0
  case XS_TOKEN_FALSE:
4264
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4265
0
    fxGetNextTokenJSON(parser);
4266
0
    break;
4267
0
  case XS_TOKEN_TRUE:
4268
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4269
0
    fxGetNextTokenJSON(parser);
4270
0
    break;
4271
0
  case XS_TOKEN_NULL:
4272
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4273
0
    fxGetNextTokenJSON(parser);
4274
0
    break;
4275
0
  case XS_TOKEN_INTEGER:
4276
0
    fxPushIntegerNode(parser, parser->states[0].integer, parser->states[0].line);
4277
0
    fxGetNextTokenJSON(parser);
4278
0
    break;
4279
0
  case XS_TOKEN_NUMBER:
4280
0
    fxPushNumberNode(parser, parser->states[0].number, parser->states[0].line);
4281
0
    fxGetNextTokenJSON(parser);
4282
0
    break;
4283
0
  case XS_TOKEN_STRING:
4284
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4285
0
    fxGetNextTokenJSON(parser);
4286
0
    break;
4287
0
  case XS_TOKEN_LEFT_BRACE:
4288
0
    fxJSONObject(parser);
4289
0
    break;
4290
0
  case XS_TOKEN_LEFT_BRACKET:
4291
0
    fxJSONArray(parser);
4292
0
    break;
4293
0
  default:
4294
0
    fxPushNULL(parser);
4295
0
    fxReportParserError(parser, parser->states[0].line, "invalid value");
4296
0
    break;
4297
0
  }
4298
0
}
4299
4300
void fxJSONObject(txParser* parser)
4301
0
{
4302
0
  txIndex aLength = 0;
4303
0
  txInteger aLine = parser->states[0].line;
4304
0
  fxGetNextTokenJSON(parser);
4305
0
  for (;;) {
4306
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4307
0
      break;
4308
0
    if (parser->states[0].token != XS_TOKEN_STRING) {
4309
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4310
0
      break;
4311
0
    }
4312
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4313
0
    fxGetNextTokenJSON(parser);
4314
0
    if (parser->states[0].token != XS_TOKEN_COLON) {
4315
0
      fxReportParserError(parser, parser->states[0].line, "missing :");
4316
0
      break;
4317
0
    }
4318
0
    fxGetNextTokenJSON(parser);
4319
0
    fxJSONValue(parser);
4320
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY_AT, parser->states[0].line);
4321
0
    aLength++;
4322
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4323
0
      break;
4324
0
    fxGetNextTokenJSON(parser);
4325
0
  }
4326
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4327
0
    fxReportParserError(parser, parser->states[0].line, "missing }");
4328
0
  fxGetNextTokenJSON(parser);
4329
0
  fxPushNodeList(parser, aLength);
4330
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
4331
0
}
4332
4333
void fxJSONArray(txParser* parser)
4334
0
{
4335
0
  txIndex aLength = 0;
4336
0
  txInteger aLine = parser->states[0].line;
4337
0
  fxGetNextTokenJSON(parser);
4338
0
  for (;;) {
4339
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACKET)
4340
0
      break;
4341
0
    fxJSONValue(parser);
4342
0
    aLength++;
4343
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4344
0
      break;
4345
0
    fxGetNextTokenJSON(parser);
4346
0
  }
4347
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET)
4348
0
    fxReportParserError(parser, parser->states[0].line, "missing ]");
4349
0
  fxGetNextTokenJSON(parser);
4350
0
  fxPushNodeList(parser, aLength);
4351
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
4352
0
}
4353
4354
void fxJSONModule(txParser* parser)
4355
0
{
4356
0
  fxJSONValue(parser);
4357
  
4358
0
  fxPushSymbol(parser, parser->defaultSymbol);
4359
0
  fxPushNULL(parser);
4360
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, 1);
4361
0
  fxSwapNodes(parser);
4362
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, 1);
4363
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, 1);
4364
  
4365
0
  fxPushSymbol(parser, parser->defaultSymbol);
4366
0
  fxPushNULL(parser);
4367
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, 1);
4368
0
  fxPushNodeList(parser, 1);
4369
0
  fxPushNULL(parser);
4370
0
  fxPushNULL(parser);
4371
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, 1);
4372
  
4373
0
  fxPushNodeList(parser, 2);
4374
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, 1);
4375
  
4376
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, 1);
4377
0
}
4378
4379
static txSymbol* fxJSXName(txParser* parser, txSymbol* before, txSymbol* after)
4380
3.06k
{
4381
3.06k
  txSize beforeLength = before->length;
4382
3.06k
  txSize afterLength = after->length;
4383
3.06k
  txSize length = beforeLength + 1 + afterLength + 1;
4384
3.06k
  txString string = fxNewParserChunk(parser, length);
4385
3.06k
  snprintf(string, length, "%s-%s", before->string, after->string);
4386
3.06k
  return fxNewParserSymbol(parser, string);
4387
3.06k
}
4388
4389
void fxJSXAttributeName(txParser* parser)
4390
18.4k
{
4391
18.4k
  txSymbol* symbol = parser->states[0].symbol;
4392
18.4k
  fxGetNextToken(parser);
4393
21.7k
  while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4394
3.27k
    fxGetNextToken(parser);
4395
3.27k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4396
2.49k
      symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4397
779
    else
4398
779
      fxReportParserError(parser, parser->states[0].line, "missing name");
4399
3.27k
    fxGetNextToken(parser);
4400
3.27k
  }
4401
18.4k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4402
2.60k
    fxGetNextToken(parser);
4403
2.60k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4404
443
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4405
2.16k
    else
4406
2.16k
      fxReportParserError(parser, parser->states[0].line, "missing name");
4407
2.60k
    fxGetNextToken(parser);
4408
3.18k
    while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4409
581
      fxGetNextToken(parser);
4410
581
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4411
571
        symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4412
10
      else
4413
10
        fxReportParserError(parser, parser->states[0].line, "missing name");
4414
581
      fxGetNextToken(parser);
4415
581
    }  
4416
2.60k
  }
4417
18.4k
  fxPushSymbol(parser, symbol);
4418
18.4k
}
4419
4420
void fxJSXAttributeValue(txParser* parser)
4421
3.09k
{
4422
3.09k
  txInteger line = parser->states[0].line;
4423
3.09k
  fxGetNextTokenJSXAttribute(parser);
4424
3.09k
  if (parser->states[0].token == XS_TOKEN_STRING) {
4425
505
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
4426
505
    fxGetNextToken(parser);
4427
505
  }
4428
2.59k
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4429
224
    fxGetNextToken(parser);
4430
224
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE) {
4431
2
      fxGetNextToken(parser);
4432
2
      fxReportParserError(parser, parser->states[0].line, "missing expression");
4433
2
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4434
2
    }
4435
222
    else {
4436
222
      fxAssignmentExpression(parser);
4437
222
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4438
34
        fxGetNextToken(parser);
4439
188
      else
4440
188
        fxReportParserError(parser, parser->states[0].line, "missing }");
4441
222
    }
4442
224
  }
4443
2.36k
  else {
4444
2.36k
    fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4445
2.36k
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4446
2.36k
  }
4447
3.09k
}
4448
4449
void fxJSXElement(txParser* parser)
4450
101k
{
4451
101k
  txBoolean closed = 0;
4452
101k
  txInteger line = parser->states[0].line;
4453
101k
  txNode* name = NULL;
4454
101k
  txInteger nodeCount = parser->nodeCount;
4455
101k
  txInteger propertyCount = 0;
4456
101k
  fxCheckParserStack(parser, line);
4457
101k
  fxPushSymbol(parser, parser->__jsx__Symbol);
4458
101k
  fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, parser->states[0].line);
4459
101k
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4460
99.3k
    fxJSXElementName(parser);
4461
99.3k
    name = parser->root;
4462
99.3k
  }
4463
1.69k
  else {
4464
1.69k
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
4465
1.69k
    fxPushNULL(parser);
4466
1.69k
  }
4467
109k
  for (;;) {
4468
109k
    if (parser->states[0].token == XS_TOKEN_MORE)
4469
47.4k
      break;
4470
61.5k
    if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4471
40.3k
      fxGetNextToken(parser);
4472
40.3k
      if (parser->states[0].token != XS_TOKEN_MORE)
4473
1.29k
        fxReportParserError(parser, parser->states[0].line, "missing >");
4474
40.3k
      closed = 1;
4475
40.3k
      break;
4476
40.3k
    }
4477
21.2k
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
4478
18.4k
      fxJSXAttributeName(parser);
4479
18.4k
      if (parser->states[0].token == XS_TOKEN_ASSIGN)
4480
3.09k
        fxJSXAttributeValue(parser);
4481
15.3k
      else
4482
15.3k
        fxPushNodeStruct(parser, 0, XS_TOKEN_TRUE, parser->states[0].line);
4483
18.4k
      fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY, parser->states[0].line);
4484
18.4k
      propertyCount++;
4485
18.4k
    }
4486
2.81k
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4487
998
      fxGetNextToken(parser);
4488
998
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
4489
2
        fxGetNextToken(parser);
4490
2
        fxAssignmentExpression(parser);
4491
2
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4492
1
          fxGetNextToken(parser);
4493
1
        else
4494
1
          fxReportParserError(parser, parser->states[0].line, "missing }");
4495
2
        fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, parser->states[0].line);
4496
2
        propertyCount++;
4497
2
      }
4498
996
      else
4499
996
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4500
998
    }
4501
1.81k
    else {
4502
1.81k
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4503
1.81k
      break;
4504
1.81k
    }
4505
21.2k
  }
4506
101k
  if (propertyCount > 0) {
4507
8.05k
    fxPushNodeList(parser, propertyCount);
4508
8.05k
    fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, parser->states[0].line);
4509
8.05k
  }
4510
93.0k
  else
4511
93.0k
    fxPushNodeStruct(parser, 0, XS_TOKEN_NULL, parser->states[0].line);
4512
101k
  if (!closed) {
4513
90.9k
    for (;;) {
4514
90.9k
      fxGetNextTokenJSXChild(parser);
4515
90.9k
      if (parser->states[0].stringLength)
4516
15.1k
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4517
90.9k
      if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4518
8.89k
        fxGetNextToken(parser);
4519
8.89k
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4520
1.95k
          fxGetNextToken(parser);
4521
6.93k
        else {
4522
6.93k
          fxAssignmentExpression(parser);
4523
6.93k
          if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4524
3.04k
            fxReportParserError(parser, parser->states[0].line, "missing }");
4525
6.93k
        }
4526
8.89k
      }
4527
82.0k
      else if (parser->states[0].token == XS_TOKEN_LESS) {
4528
76.0k
        fxGetNextToken(parser);
4529
76.0k
        if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4530
10.7k
          fxGetNextToken(parser);
4531
10.7k
          if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4532
9.16k
            fxJSXElementName(parser);
4533
9.16k
            if (!fxJSXMatch(parser, name, parser->root)) {
4534
6.94k
              fxReportParserError(parser, parser->states[0].line, "invalid element");
4535
6.94k
              fxPushNULL(parser);
4536
6.94k
            }
4537
9.16k
          }
4538
1.62k
          else {
4539
1.62k
            fxReportParserError(parser, parser->states[0].line, "missing identifier");
4540
1.62k
            fxPushNULL(parser);
4541
1.62k
          }
4542
10.7k
          if (parser->states[0].token != XS_TOKEN_MORE)
4543
1.60k
            fxReportParserError(parser, parser->states[0].line, "missing >");
4544
10.7k
          fxPopNode(parser);
4545
10.7k
          break;
4546
10.7k
        }
4547
65.3k
        else
4548
65.3k
          fxJSXElement(parser);
4549
76.0k
      }
4550
5.96k
      else {
4551
5.96k
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4552
5.96k
        break;
4553
5.96k
      }
4554
90.9k
    }
4555
47.4k
  }
4556
101k
  fxPushNodeList(parser, parser->nodeCount - nodeCount - 1);
4557
101k
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, line);
4558
101k
  fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, line);
4559
101k
}
4560
4561
void fxJSXElementName(txParser* parser)
4562
108k
{
4563
108k
  txInteger line = parser->states[0].line;
4564
108k
  txSymbol* symbol = parser->states[0].symbol;
4565
108k
  fxGetNextToken(parser);
4566
108k
  if (parser->states[0].token == XS_TOKEN_COLON) {
4567
930
    fxGetNextToken(parser);
4568
930
    if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
4569
261
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4570
669
    else
4571
669
      fxReportParserError(parser, parser->states[0].line, "missing name");
4572
930
    fxPushSymbol(parser, symbol);
4573
930
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4574
930
    fxGetNextToken(parser);
4575
930
  }
4576
107k
  else {
4577
107k
    fxPushSymbol(parser, symbol);
4578
107k
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4579
135k
    while (parser->states[0].token == XS_TOKEN_DOT) {
4580
27.6k
      fxGetNextToken(parser);
4581
27.6k
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4582
25.6k
        fxPushSymbol(parser, parser->states[0].symbol);
4583
25.6k
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, parser->states[0].line);
4584
25.6k
        fxGetNextToken(parser);
4585
25.6k
      }
4586
1.99k
      else
4587
1.99k
        fxReportParserError(parser, parser->states[0].line, "missing property");
4588
27.6k
    }
4589
107k
  }
4590
108k
}
4591
4592
txBoolean fxJSXMatch(txParser* parser, txNode* opening, txNode* closing)
4593
8.75k
{
4594
8.75k
  if (opening && closing) {
4595
8.76k
    while (opening->description->token == XS_TOKEN_MEMBER) {
4596
3.88k
      if (closing->description->token != XS_TOKEN_MEMBER)
4597
2.03k
        return 0;
4598
1.85k
      if (((txMemberNode*)opening)->symbol != ((txMemberNode*)closing)->symbol)
4599
1.85k
        return 0;
4600
4
      opening = ((txMemberNode*)opening)->reference;
4601
4
      closing = ((txMemberNode*)closing)->reference;
4602
4
    }
4603
4.87k
    if (opening->description->token == XS_TOKEN_ACCESS) {
4604
4.87k
      if (closing->description->token != XS_TOKEN_ACCESS)
4605
1.49k
        return 0;
4606
3.38k
      if (((txAccessNode*)opening)->symbol != ((txAccessNode*)closing)->symbol)
4607
1.57k
        return 0;
4608
1.81k
      return 1;
4609
3.38k
    }
4610
4.87k
  }
4611
0
  return 0;
4612
8.75k
}
4613
4614
txSymbol* fxJSXNamespace(txParser* parser, txSymbol* namespace, txSymbol* name)
4615
704
{
4616
704
  txSize namespaceLength = namespace->length;
4617
704
  txSize nameLength = name->length;
4618
704
  txSize length = namespaceLength + 1 + nameLength + 1;
4619
704
  txString string = fxNewParserChunk(parser, length);
4620
704
  snprintf(string, length, "%s:%s", namespace->string, name->string);
4621
704
  return fxNewParserSymbol(parser, string);
4622
704
}