Coverage Report

Created: 2026-06-10 06:56

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