Coverage Report

Created: 2026-07-14 06:30

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
      parser->flags |= mxAwaitingFlag;
1605
0
    }
1606
0
    else if (aToken == XS_TOKEN_IN)
1607
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_IN, aLine);
1608
0
    else
1609
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FOR_OF, aLine);
1610
0
  }
1611
0
  else {
1612
0
    if (expressionFlag)
1613
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1614
0
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1615
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1616
0
      fxCommaExpression(parser);
1617
0
    }
1618
0
    else {
1619
0
      fxPushNULL(parser);
1620
0
    }
1621
0
    fxMatchToken(parser, XS_TOKEN_SEMICOLON);
1622
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1623
0
      fxCommaExpression(parser);
1624
0
    }
1625
0
    else {
1626
0
      fxPushNULL(parser);
1627
0
    }
1628
0
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1629
0
    fxCheckParserStack(parser, aLine);
1630
0
    fxStatement(parser, 0);
1631
0
    fxPushNodeStruct(parser, 4, XS_TOKEN_FOR, aLine);
1632
0
  }
1633
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1634
0
}
1635
1636
void fxIfStatement(txParser* parser)
1637
0
{
1638
0
  txInteger aLine = parser->states[0].line;
1639
0
  fxMatchToken(parser, XS_TOKEN_IF);
1640
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1641
0
  fxCommaExpression(parser);
1642
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1643
0
  fxStatement(parser, 0);
1644
0
  if (parser->states[0].token == XS_TOKEN_ELSE) {
1645
0
    fxMatchToken(parser, XS_TOKEN_ELSE);
1646
0
    fxStatement(parser, 0);
1647
0
  }
1648
0
  else {
1649
0
    fxPushNULL(parser);
1650
0
  }
1651
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_IF, aLine);
1652
0
}
1653
1654
void fxReturnStatement(txParser* parser)
1655
0
{
1656
0
  txInteger aLine = parser->states[0].line;
1657
0
  fxMatchToken(parser, XS_TOKEN_RETURN);
1658
0
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1659
0
    fxCommaExpression(parser);
1660
0
  }
1661
0
  else {
1662
0
    fxPushNULL(parser);
1663
0
  }
1664
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
1665
0
}
1666
1667
void fxSwitchStatement(txParser* parser)
1668
0
{
1669
0
  txInteger aCount = 0;
1670
0
  txBoolean aDefaultFlag = 0;
1671
0
  txInteger aLine = parser->states[0].line;
1672
0
  fxMatchToken(parser, XS_TOKEN_SWITCH);
1673
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1674
0
  fxCommaExpression(parser);
1675
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1676
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1677
0
  while ((parser->states[0].token == XS_TOKEN_CASE) || (parser->states[0].token == XS_TOKEN_DEFAULT)) {
1678
0
    txInteger aCaseCount;
1679
0
    txInteger aCaseLine = parser->states[0].line;
1680
0
    if (parser->states[0].token == XS_TOKEN_CASE) {
1681
0
      fxMatchToken(parser, XS_TOKEN_CASE);
1682
0
      fxCommaExpression(parser);
1683
0
      fxMatchToken(parser, XS_TOKEN_COLON);
1684
0
      aCaseCount = parser->nodeCount;
1685
0
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1686
0
        fxStatement(parser, -1);
1687
0
      aCaseCount = parser->nodeCount - aCaseCount;
1688
0
      if (aCaseCount > 1) {
1689
0
        fxPushNodeList(parser, aCaseCount);
1690
0
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aCaseLine);
1691
0
      }
1692
0
      else if (aCaseCount == 0) {
1693
0
        fxPushNULL(parser);
1694
0
      }
1695
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1696
0
    }
1697
0
    else {
1698
0
      fxMatchToken(parser, XS_TOKEN_DEFAULT);
1699
0
      if (aDefaultFlag) 
1700
0
        fxReportParserError(parser, parser->states[0].line, "invalid default");
1701
0
      fxPushNULL(parser);
1702
0
      fxMatchToken(parser, XS_TOKEN_COLON);
1703
0
      aCaseCount = parser->nodeCount;
1704
0
      while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_STATEMENT)
1705
0
        fxStatement(parser, -1);
1706
0
      aCaseCount = parser->nodeCount - aCaseCount;
1707
0
      if (aCaseCount > 1) {
1708
0
        fxPushNodeList(parser, aCaseCount);
1709
0
        fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1710
0
      }
1711
0
      else if (aCaseCount == 0) {
1712
0
        fxPushNULL(parser);
1713
0
      }
1714
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_CASE, aCaseLine);
1715
0
      aDefaultFlag = 1;
1716
0
    }
1717
0
    aCount++;
1718
0
  }
1719
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1720
0
  fxPushNodeList(parser, aCount);
1721
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_SWITCH, aLine);
1722
0
}
1723
1724
void fxThrowStatement(txParser* parser)
1725
0
{
1726
0
  txInteger aLine = parser->states[0].line;
1727
0
  fxMatchToken(parser, XS_TOKEN_THROW);
1728
0
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
1729
0
    fxCommaExpression(parser);
1730
0
  }
1731
0
  else {
1732
0
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1733
0
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
1734
0
  }
1735
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_THROW, aLine);
1736
0
}
1737
1738
void fxTryStatement(txParser* parser)
1739
0
{
1740
0
  txInteger aLine = parser->states[0].line;
1741
0
  txBoolean ok = 0;
1742
0
  fxMatchToken(parser, XS_TOKEN_TRY);
1743
0
  fxBlock(parser);
1744
0
  if (parser->states[0].token == XS_TOKEN_CATCH) {
1745
0
    txInteger aCatchLine = parser->states[0].line;
1746
0
    fxMatchToken(parser, XS_TOKEN_CATCH);
1747
0
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
1748
0
      fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1749
0
      fxBinding(parser, XS_TOKEN_LET, 1);
1750
0
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1751
0
    }
1752
0
    else
1753
0
      fxPushNULL(parser);
1754
0
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
1755
0
    fxStatements(parser);
1756
0
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
1757
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_CATCH, aCatchLine);
1758
0
    ok = 1;
1759
0
  }
1760
0
  else {
1761
0
    fxPushNULL(parser);
1762
0
  }
1763
0
  if (parser->states[0].token == XS_TOKEN_FINALLY) {
1764
0
    fxMatchToken(parser, XS_TOKEN_FINALLY);
1765
0
    fxBlock(parser);
1766
0
    ok = 1;
1767
0
  }
1768
0
  else {
1769
0
    fxPushNULL(parser);
1770
0
  }
1771
0
  if (!ok)
1772
0
    fxReportParserError(parser, parser->states[0].line, "missing catch or finally");
1773
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_TRY, aLine);
1774
0
}
1775
1776
void fxVariableStatement(txParser* parser, txToken theToken, txUnsigned flags)
1777
0
{
1778
0
  txBoolean commaFlag = 0;
1779
0
  txInteger aCount = 0;
1780
0
  txInteger aLine = parser->states[0].line;
1781
0
  fxMatchToken(parser, theToken);
1782
0
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
1783
0
    commaFlag = 0;
1784
0
    fxBinding(parser, theToken, 1 | flags);
1785
//    if (parser->states[0].token == XS_TOKEN_ASSIGN) {
1786
//      parser->flags &= ~mxForFlag;
1787
//      fxGetNextToken(parser);
1788
//      fxAssignmentExpression(parser);
1789
//      fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, aLine);
1790
//      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
1791
//    }
1792
0
    aCount++;
1793
0
    if (parser->states[0].token == XS_TOKEN_COMMA) {
1794
0
      parser->flags &= ~mxForFlag;
1795
0
      fxGetNextToken(parser);
1796
0
      commaFlag = 1;
1797
0
    }
1798
0
    else
1799
0
      break;
1800
0
  }
1801
0
    if ((aCount == 0) || commaFlag) {
1802
0
    fxPushNULL(parser);
1803
0
    fxPushNULL(parser);
1804
0
    fxPushNodeStruct(parser, 2, theToken, aLine);
1805
0
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
1806
0
  }
1807
0
  if (aCount > 1) {
1808
0
    fxPushNodeList(parser, aCount);
1809
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
1810
0
  }
1811
0
}
1812
1813
void fxWhileStatement(txParser* parser)
1814
0
{
1815
0
  txInteger aLine = parser->states[0].line;
1816
0
  fxPushNULL(parser);
1817
0
  fxMatchToken(parser, XS_TOKEN_WHILE);
1818
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1819
0
  fxCommaExpression(parser);
1820
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1821
0
  fxStatement(parser, 0);
1822
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_WHILE, aLine);
1823
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_LABEL, aLine);
1824
0
}
1825
1826
void fxWithStatement(txParser* parser)
1827
0
{
1828
0
  txInteger aLine = parser->states[0].line;
1829
0
  fxMatchToken(parser, XS_TOKEN_WITH);
1830
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
1831
0
  fxCommaExpression(parser);
1832
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
1833
0
  fxStatement(parser, 0);
1834
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_WITH, aLine);
1835
0
}
1836
1837
void fxCommaExpression(txParser* parser)
1838
0
{
1839
0
  txInteger aCount = 0;
1840
0
  txInteger aLine = parser->states[0].line;
1841
0
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
1842
0
    fxAssignmentExpression(parser);
1843
0
    aCount++;
1844
0
    while (parser->states[0].token == XS_TOKEN_COMMA) {
1845
0
      fxGetNextToken(parser);
1846
0
      fxAssignmentExpression(parser);
1847
0
      aCount++;
1848
0
    }
1849
0
  }
1850
0
  if (aCount > 1) {
1851
0
    fxPushNodeList(parser, aCount);
1852
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
1853
0
  }
1854
0
  else if (aCount == 0) {
1855
0
    fxPushNULL(parser);
1856
0
    fxReportParserError(parser, parser->states[0].line, "missing expression");
1857
0
  }
1858
0
}
1859
1860
void fxAssignmentExpression(txParser* parser)
1861
0
{
1862
0
  fxCheckParserStack(parser, parser->states[0].line);
1863
0
  if (parser->states[0].token == XS_TOKEN_YIELD)
1864
0
    fxYieldExpression(parser);
1865
0
  else {
1866
0
    fxConditionalExpression(parser);
1867
0
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ASSIGN_EXPRESSION) {
1868
0
      txToken aToken = parser->states[0].token;
1869
0
      txInteger aLine = parser->states[0].line;
1870
0
      if (!fxCheckReference(parser, aToken)) 
1871
0
        fxReportParserError(parser, parser->states[0].line, "no reference");
1872
0
      fxGetNextToken(parser);
1873
0
      fxAssignmentExpression(parser);
1874
0
      fxPushNodeStruct(parser, 2, aToken, aLine);
1875
0
    }
1876
0
  }
1877
0
}
1878
1879
void fxConditionalExpression(txParser* parser)
1880
0
{
1881
0
  fxCoalesceExpression(parser);
1882
0
  if (parser->states[0].token == XS_TOKEN_QUESTION_MARK) {
1883
0
    txInteger aLine = parser->states[0].line;
1884
0
    txUnsigned flags;
1885
0
    fxCheckArrowFunction(parser, 1);
1886
0
    fxGetNextToken(parser);
1887
0
    flags = parser->flags & mxForFlag;
1888
0
    parser->flags &= ~mxForFlag;
1889
0
    fxAssignmentExpression(parser);
1890
0
    parser->flags |= flags;
1891
0
    fxMatchToken(parser, XS_TOKEN_COLON);
1892
0
    fxAssignmentExpression(parser);
1893
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_QUESTION_MARK, aLine);
1894
0
  }
1895
0
}
1896
1897
void fxCoalesceExpression(txParser* parser)
1898
0
{
1899
0
  fxOrExpression(parser);
1900
0
  while (parser->states[0].token == XS_TOKEN_COALESCE) {
1901
0
    txInteger aLine = parser->states[0].line;
1902
0
    fxGetNextToken(parser);
1903
0
    fxOrExpression(parser);
1904
0
    fxCheckArrowFunction(parser, 2);
1905
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_COALESCE, aLine);
1906
0
  }
1907
0
}
1908
1909
void fxOrExpression(txParser* parser)
1910
0
{
1911
0
  fxAndExpression(parser);
1912
0
  while (parser->states[0].token == XS_TOKEN_OR) {
1913
0
    txInteger aLine = parser->states[0].line;
1914
0
    fxGetNextToken(parser);
1915
0
    fxAndExpression(parser);
1916
0
    fxCheckArrowFunction(parser, 2);
1917
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_OR, aLine);
1918
0
  }
1919
0
}
1920
1921
void fxAndExpression(txParser* parser)
1922
0
{
1923
0
  fxBitOrExpression(parser);
1924
0
  while (parser->states[0].token == XS_TOKEN_AND) {
1925
0
    txInteger aLine = parser->states[0].line;
1926
0
    fxGetNextToken(parser);
1927
0
    fxBitOrExpression(parser);
1928
0
    fxCheckArrowFunction(parser, 2);
1929
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_AND, aLine);
1930
0
  }
1931
0
}
1932
1933
void fxBitOrExpression(txParser* parser)
1934
0
{
1935
0
  fxBitXorExpression(parser);
1936
0
  while (parser->states[0].token == XS_TOKEN_BIT_OR) {
1937
0
    txInteger aLine = parser->states[0].line;
1938
0
    fxGetNextToken(parser);
1939
0
    fxBitXorExpression(parser);
1940
0
    fxCheckArrowFunction(parser, 2);
1941
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_OR, aLine);
1942
0
  }
1943
0
}
1944
1945
void fxBitXorExpression(txParser* parser)
1946
0
{
1947
0
  fxBitAndExpression(parser);
1948
0
  while (parser->states[0].token == XS_TOKEN_BIT_XOR) {
1949
0
    txInteger aLine = parser->states[0].line;
1950
0
    fxGetNextToken(parser);
1951
0
    fxBitAndExpression(parser);
1952
0
    fxCheckArrowFunction(parser, 2);
1953
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_XOR, aLine);
1954
0
  }
1955
0
}
1956
1957
void fxBitAndExpression(txParser* parser)
1958
0
{
1959
0
  fxEqualExpression(parser);
1960
0
  while (parser->states[0].token == XS_TOKEN_BIT_AND) {
1961
0
    txInteger aLine = parser->states[0].line;
1962
0
    fxGetNextToken(parser);
1963
0
    fxEqualExpression(parser);
1964
0
    fxCheckArrowFunction(parser, 2);
1965
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_BIT_AND, aLine);
1966
0
  }
1967
0
}
1968
1969
void fxEqualExpression(txParser* parser)
1970
0
{
1971
0
  fxRelationalExpression(parser);
1972
0
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EQUAL_EXPRESSION) {
1973
0
    txToken aToken = parser->states[0].token;
1974
0
    txInteger aLine = parser->states[0].line;
1975
0
    fxGetNextToken(parser);
1976
0
    fxRelationalExpression(parser);
1977
0
    fxCheckArrowFunction(parser, 2);
1978
0
    fxPushNodeStruct(parser, 2, aToken, aLine);
1979
0
  }
1980
0
}
1981
1982
void fxRelationalExpression(txParser* parser)
1983
0
{
1984
0
  if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
1985
0
    txInteger aLine = parser->states[0].line;
1986
0
    fxPushSymbol(parser, parser->states[0].symbol);
1987
0
    fxGetNextToken(parser);
1988
0
    fxMatchToken(parser, XS_TOKEN_IN);
1989
0
    if (parser->flags & mxForFlag)
1990
0
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[XS_TOKEN_IN]);
1991
0
    fxShiftExpression(parser);
1992
0
    fxCheckArrowFunction(parser, 2);
1993
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_IDENTIFIER, aLine);
1994
0
  }
1995
0
  else {
1996
0
    fxShiftExpression(parser);
1997
0
    if ((parser->flags & mxForFlag) && ((parser->states[0].token == XS_TOKEN_IN) || fxIsKeyword(parser, parser->ofSymbol)))
1998
0
      return;
1999
0
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_RELATIONAL_EXPRESSION) {
2000
0
      txToken aToken = parser->states[0].token;
2001
0
      txInteger aLine = parser->states[0].line;
2002
0
      fxMatchToken(parser, aToken);
2003
0
      fxShiftExpression(parser);
2004
0
      fxCheckArrowFunction(parser, 2);
2005
0
      fxPushNodeStruct(parser, 2, aToken, aLine);
2006
0
    }
2007
0
  }
2008
0
}
2009
2010
void fxShiftExpression(txParser* parser)
2011
0
{
2012
0
  fxAdditiveExpression(parser);
2013
0
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_SHIFT_EXPRESSION) {
2014
0
    txToken aToken = parser->states[0].token;
2015
0
    txInteger aLine = parser->states[0].line;
2016
0
    fxGetNextToken(parser);
2017
0
    fxAdditiveExpression(parser);
2018
0
    fxCheckArrowFunction(parser, 2);
2019
0
    fxPushNodeStruct(parser, 2, aToken, aLine);
2020
0
  }
2021
0
}
2022
2023
void fxAdditiveExpression(txParser* parser)
2024
0
{
2025
0
  fxMultiplicativeExpression(parser);
2026
0
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_ADDITIVE_EXPRESSION) {
2027
0
    txToken aToken = parser->states[0].token;
2028
0
    txInteger aLine = parser->states[0].line;
2029
0
    fxGetNextToken(parser);
2030
0
    fxMultiplicativeExpression(parser);
2031
0
    fxCheckArrowFunction(parser, 2);
2032
0
    fxPushNodeStruct(parser, 2, aToken, aLine);
2033
0
  }
2034
0
}
2035
2036
void fxMultiplicativeExpression(txParser* parser)
2037
0
{
2038
0
  fxExponentiationExpression(parser);
2039
0
  while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_MULTIPLICATIVE_EXPRESSION) {
2040
0
    txToken aToken = parser->states[0].token;
2041
0
    txInteger aLine = parser->states[0].line;
2042
0
    fxGetNextToken(parser);
2043
0
    fxExponentiationExpression(parser);
2044
0
    fxCheckArrowFunction(parser, 2);
2045
0
    fxPushNodeStruct(parser, 2, aToken, aLine);
2046
0
  }
2047
0
}
2048
2049
void fxExponentiationExpression(txParser* parser)
2050
0
{
2051
0
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION)
2052
0
    fxUnaryExpression(parser);
2053
0
  else {
2054
0
    fxPrefixExpression(parser);
2055
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_EXPONENTIATION_EXPRESSION) {
2056
0
      txToken aToken = parser->states[0].token;
2057
0
      txInteger aLine = parser->states[0].line;
2058
0
      fxGetNextToken(parser);
2059
0
            fxExponentiationExpression(parser);
2060
0
      fxCheckArrowFunction(parser, 2);
2061
0
      fxPushNodeStruct(parser, 2, aToken, aLine);
2062
0
    }
2063
0
  }
2064
0
}
2065
2066
void fxUnaryExpression(txParser* parser)
2067
0
{
2068
0
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_UNARY_EXPRESSION) {
2069
0
    txToken aToken = parser->states[0].token;
2070
0
    txInteger aLine = parser->states[0].line;
2071
0
    fxCheckParserStack(parser, aLine);
2072
0
    fxMatchToken(parser, aToken);
2073
0
    fxUnaryExpression(parser);
2074
0
    fxCheckArrowFunction(parser, 1);
2075
0
    if (aToken == XS_TOKEN_ADD)
2076
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PLUS, aLine);
2077
0
    else if (aToken == XS_TOKEN_SUBTRACT)
2078
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_MINUS, aLine);
2079
0
    else if (aToken == XS_TOKEN_DELETE) {
2080
      //if ((parser->flags & mxStrictFlag) && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2081
      //  fxReportParserError(parser, parser->states[0].line, "no reference (strict mode)");
2082
      //}
2083
0
      if (!fxCheckReference(parser, aToken)) 
2084
0
        fxReportParserError(parser, parser->states[0].line, "no reference");
2085
0
      fxPushNodeStruct(parser, 1, aToken, aLine);
2086
0
    }
2087
0
    else if (aToken == XS_TOKEN_AWAIT) {
2088
0
      if ((parser->flags & mxGeneratorFlag) && !(parser->flags & mxYieldFlag))
2089
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2090
0
      else
2091
0
        parser->flags |= mxAwaitingFlag;
2092
0
      fxPushNodeStruct(parser, 1, aToken, aLine);
2093
0
    }
2094
0
    else
2095
0
      fxPushNodeStruct(parser, 1, aToken, aLine);
2096
      
2097
0
  }
2098
0
  else
2099
0
    fxPrefixExpression(parser);
2100
0
}
2101
2102
void fxPrefixExpression(txParser* parser)
2103
0
{
2104
0
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_PREFIX_EXPRESSION) {
2105
0
    txToken aToken = parser->states[0].token;
2106
0
    txInteger aLine = parser->states[0].line;
2107
0
    fxCheckParserStack(parser, aLine);
2108
0
    fxGetNextToken(parser);
2109
0
    fxPrefixExpression(parser);
2110
0
    fxCheckArrowFunction(parser, 1);
2111
0
    if (!fxCheckReference(parser, aToken)) 
2112
0
      fxReportParserError(parser, parser->states[0].line, "no reference");
2113
0
    fxPushNodeStruct(parser, 1, aToken, aLine);
2114
0
    parser->root->flags = mxExpressionNoValue;
2115
0
  }
2116
0
  else
2117
0
    fxPostfixExpression(parser);
2118
0
}
2119
2120
void fxPostfixExpression(txParser* parser)
2121
0
{
2122
0
  fxCallExpression(parser);
2123
0
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_POSTFIX_EXPRESSION)) {
2124
0
    fxCheckArrowFunction(parser, 1);
2125
0
    if (!fxCheckReference(parser, parser->states[0].token)) 
2126
0
      fxReportParserError(parser, parser->states[0].line, "no reference");
2127
0
    fxPushNodeStruct(parser, 1, parser->states[0].token, parser->states[0].line);
2128
0
    fxGetNextToken(parser);
2129
0
  }
2130
0
}
2131
2132
void fxCallExpression(txParser* parser)
2133
0
{
2134
0
  txInteger chainLine = parser->states[0].line;
2135
0
  fxLiteralExpression(parser, 0);
2136
0
  if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_CALL_EXPRESSION) {
2137
0
    txBoolean chainFlag = 0;
2138
0
    fxCheckArrowFunction(parser, 1);
2139
0
    for (;;) {
2140
0
      txInteger aLine = parser->states[0].line;
2141
0
      if (parser->states[0].token == XS_TOKEN_DOT) {
2142
0
        fxGetNextToken(parser);
2143
0
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2144
0
          fxPushSymbol(parser, parser->states[0].symbol);
2145
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2146
0
          fxGetNextToken(parser);
2147
0
        }
2148
0
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2149
0
          if (parser->root->flags & mxSuperFlag)
2150
0
            fxReportParserError(parser, parser->states[0].line, "invalid super");
2151
0
          fxPushSymbol(parser, parser->states[0].symbol);
2152
0
          fxSwapNodes(parser);
2153
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2154
0
          fxGetNextToken(parser);
2155
0
        }
2156
0
        else
2157
0
          fxReportParserError(parser, parser->states[0].line, "missing property");
2158
0
      }
2159
      //else if (parser->states[0].crlf)
2160
      //  break;
2161
0
      else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2162
0
        fxGetNextToken(parser);
2163
0
        fxCommaExpression(parser);
2164
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2165
0
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2166
0
      }
2167
0
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2168
0
        txUnsigned nativeFlags = 0;
2169
0
        txAccessNode* access = NULL;
2170
0
        if (parser->root->description && (parser->root->description->token == XS_TOKEN_ACCESS)) {
2171
0
          access = (txAccessNode*)parser->root;
2172
0
          if (access->symbol == parser->evalSymbol) {
2173
0
            parser->flags |= mxEvalFlag;
2174
0
          }
2175
0
          else if (parser->flags & mxCFlag) {
2176
0
            if (access->symbol == parser->NativeSymbol) {
2177
0
              nativeFlags = mxNativeConstructorFlag;
2178
0
            }
2179
0
            else if (access->symbol == parser->nativeSymbol) {
2180
0
              nativeFlags = mxNativeFunctionFlag;
2181
0
              parser->flags |= mxNativeFlag;
2182
0
            }
2183
0
          }
2184
0
        }
2185
0
        fxParameters(parser);
2186
0
        if (nativeFlags) {
2187
0
          txParamsNode* params = (txParamsNode*)parser->root;
2188
0
          if (params->items->length == 0)
2189
0
             fxReportParserError(parser, aLine, "%s: no argument", access->symbol->string);
2190
0
          if (params->items->length > 1)
2191
0
             fxReportParserError(parser, aLine, "%s: too many arguments", access->symbol->string);
2192
0
          txStringNode* param = (txStringNode*)(params->items->first);
2193
0
          if (param->description->token != XS_TOKEN_STRING)
2194
0
             fxReportParserError(parser, aLine, "%s: argument is no string literal", access->symbol->string);
2195
0
          fxPopNode(parser);
2196
0
          fxPopNode(parser);
2197
0
          if (nativeFlags & mxNativeFunctionFlag) {
2198
0
            fxPushNULL(parser);
2199
0
            fxPushNodeList(parser, 0);
2200
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2201
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2202
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2203
0
          }
2204
0
          else {
2205
0
            fxPushNULL(parser);
2206
2207
0
            fxPushNULL(parser);
2208
0
            fxPushNULL(parser);
2209
0
            fxPushStringNode(parser, param->length, param->value, aLine);
2210
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2211
            
2212
0
            fxPushNodeList(parser, 0);
2213
            
2214
0
            fxPushNULL(parser);
2215
0
            fxPushNULL(parser);
2216
            
2217
0
            fxPushNULL(parser);
2218
0
            fxPushNodeList(parser, 0);
2219
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2220
0
            fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2221
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2222
0
            fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2223
0
            fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2224
0
            parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2225
            
2226
0
            fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2227
0
          }
2228
0
        }
2229
0
        else
2230
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2231
0
      }
2232
0
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
2233
0
        if (chainFlag)
2234
0
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2235
0
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2236
0
        fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2237
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2238
0
        fxGetNextToken(parser);
2239
0
        fxPushNodeList(parser, 1);
2240
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2241
0
      }
2242
0
      else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
2243
0
        if (chainFlag)
2244
0
          fxReportParserError(parser, parser->states[0].line, "invalid template");
2245
0
        fxTemplateExpression(parser);
2246
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2247
0
      }
2248
0
      else if (parser->states[0].token == XS_TOKEN_CHAIN) {
2249
0
        fxGetNextToken(parser);
2250
0
        chainFlag = 1;
2251
0
        if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2252
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2253
0
          fxPushSymbol(parser, parser->states[0].symbol);
2254
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aLine);
2255
0
          fxGetNextToken(parser);
2256
0
        }
2257
0
        else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
2258
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2259
0
          fxPushSymbol(parser, parser->states[0].symbol);
2260
0
          fxSwapNodes(parser);
2261
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aLine);
2262
0
          fxGetNextToken(parser);
2263
0
        }
2264
0
        else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
2265
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2266
0
          fxGetNextToken(parser);
2267
0
          fxCommaExpression(parser);
2268
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aLine);
2269
0
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2270
0
        }
2271
0
        else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2272
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_OPTION, aLine);
2273
0
          fxParameters(parser);
2274
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
2275
0
        }
2276
0
        else
2277
0
          fxReportParserError(parser, parser->states[0].line, "invalid ?.");
2278
0
      }
2279
0
      else
2280
0
        break;
2281
0
    } 
2282
0
    if (chainFlag)
2283
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_CHAIN, chainLine);
2284
0
  } 
2285
0
}
2286
2287
void fxLiteralExpression(txParser* parser, txUnsigned flag)
2288
0
{
2289
0
  int escaped;
2290
0
  txSymbol* aSymbol;
2291
0
  txInteger aLine = parser->states[0].line;
2292
0
  txUnsigned flags = 0;
2293
0
  char c = 0;
2294
0
  fxCheckParserStack(parser, aLine);
2295
0
  switch (parser->states[0].token) {
2296
0
  case XS_TOKEN_NULL:
2297
0
  case XS_TOKEN_TRUE:
2298
0
  case XS_TOKEN_FALSE:
2299
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2300
0
    fxMatchToken(parser, parser->states[0].token);
2301
0
    break;
2302
0
  case XS_TOKEN_IMPORT:
2303
0
    fxMatchToken(parser, XS_TOKEN_IMPORT);
2304
0
    if (!flag && (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)) {
2305
0
      txUnsigned flags = parser->flags & mxForFlag;
2306
0
      fxGetNextToken(parser);
2307
0
      parser->flags &= ~mxForFlag;
2308
0
      fxAssignmentExpression(parser);
2309
0
      if (parser->states[0].token == XS_TOKEN_COMMA) {
2310
0
        fxGetNextToken(parser);
2311
0
        if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION) {
2312
0
          fxAssignmentExpression(parser);
2313
0
          if (parser->states[0].token == XS_TOKEN_COMMA)
2314
0
            fxGetNextToken(parser);
2315
0
        }
2316
0
        else
2317
0
          fxPushNULL(parser);
2318
0
      }
2319
0
      else
2320
0
        fxPushNULL(parser);
2321
0
      parser->flags |= flags;
2322
0
      fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
2323
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_IMPORT_CALL, aLine);
2324
0
    }
2325
0
    else if (parser->states[0].token == XS_TOKEN_DOT) {
2326
0
      fxGetNextToken(parser);
2327
0
      if ((parser->states[0].token == XS_TOKEN_IDENTIFIER) && (parser->states[0].symbol == parser->metaSymbol) && (!parser->states[0].escaped)) { 
2328
0
        fxGetNextToken(parser);
2329
0
        if (parser->flags & mxProgramFlag)
2330
0
          fxReportParserError(parser, parser->states[0].line, "invalid import.meta");
2331
0
        else
2332
0
          fxPushNodeStruct(parser, 0, XS_TOKEN_IMPORT_META, aLine);
2333
0
      }
2334
0
      else
2335
0
        fxReportParserError(parser, parser->states[0].line, "invalid import.");
2336
0
    }
2337
0
    else
2338
0
      fxReportParserError(parser, parser->states[0].line, "invalid import");
2339
0
    break;
2340
0
  case XS_TOKEN_SUPER:
2341
0
    fxMatchToken(parser, XS_TOKEN_SUPER);
2342
0
    if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2343
0
      if (parser->flags & mxDerivedFlag) {
2344
0
        fxParameters(parser);
2345
0
        fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2346
0
      }
2347
0
      else {
2348
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2349
0
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2350
0
      }
2351
0
    }
2352
0
    else if ((parser->states[0].token == XS_TOKEN_DOT) || (parser->states[0].token == XS_TOKEN_LEFT_BRACKET)) {
2353
0
      if (parser->flags & mxSuperFlag) {
2354
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_THIS, aLine);
2355
0
        parser->root->flags |= parser->flags & (mxDerivedFlag | mxSuperFlag);
2356
0
      }
2357
0
      else {
2358
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2359
0
        fxReportParserError(parser, parser->states[0].line, "invalid super");
2360
0
      }
2361
0
    }
2362
0
    else
2363
0
      fxReportParserError(parser, parser->states[0].line, "invalid super");
2364
0
    parser->flags |= mxSuperFlag;
2365
0
    break;
2366
0
  case XS_TOKEN_THIS:
2367
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, aLine);
2368
0
    parser->root->flags |= parser->flags & mxDerivedFlag;
2369
0
    fxMatchToken(parser, XS_TOKEN_THIS);
2370
0
    break;
2371
0
  case XS_TOKEN_INTEGER:
2372
0
    fxPushIntegerNode(parser, parser->states[0].integer, aLine);
2373
0
    fxGetNextToken(parser);
2374
0
    break;
2375
0
  case XS_TOKEN_NUMBER:
2376
0
    fxPushNumberNode(parser, parser->states[0].number, aLine);
2377
0
    fxGetNextToken(parser);
2378
0
    break;
2379
0
  case XS_TOKEN_BIGINT:
2380
0
    fxPushBigIntNode(parser, &parser->states[0].bigint, aLine);
2381
0
    fxGetNextToken(parser);
2382
0
    break;
2383
0
  case XS_TOKEN_DIVIDE_ASSIGN:
2384
0
    c = '=';
2385
    // continue
2386
0
    mxFallThrough;
2387
0
  case XS_TOKEN_DIVIDE:
2388
0
    fxGetNextRegExp(parser, c);
2389
0
    fxPushStringNode(parser, parser->states[0].modifierLength, parser->states[0].modifier, aLine);
2390
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2391
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_REGEXP, aLine);
2392
0
    fxGetNextToken(parser);
2393
0
    break;
2394
0
  case XS_TOKEN_STRING:
2395
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2396
0
    fxGetNextToken(parser);
2397
0
    break;
2398
0
  case XS_TOKEN_IDENTIFIER:
2399
0
    escaped = parser->states[0].escaped;
2400
0
    aSymbol = parser->states[0].symbol;
2401
0
    fxGetNextToken(parser);
2402
//    if (aSymbol == parser->undefinedSymbol) {
2403
//      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2404
//      break;
2405
//    }
2406
0
    flags = 0;
2407
0
    if ((aSymbol == parser->asyncSymbol) && (!escaped) && (!parser->states[0].crlf)) {
2408
0
      if (parser->states[0].token == XS_TOKEN_FUNCTION) {
2409
0
        fxMatchToken(parser, XS_TOKEN_FUNCTION);
2410
0
        if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2411
0
          fxGetNextToken(parser);
2412
0
          fxGeneratorExpression(parser, aLine, C_NULL, mxAsyncFlag);
2413
0
        }
2414
0
        else
2415
0
          fxFunctionExpression(parser, aLine, C_NULL, mxAsyncFlag);
2416
0
        break;
2417
0
      }
2418
0
      if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2419
0
        fxGroupExpression(parser, mxAsyncFlag);
2420
0
        break;
2421
0
      }
2422
0
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2423
//        if (!(parser->flags & mxForFlag) || !fxIsKeyword(parser, parser->ofSymbol)) {
2424
0
          aSymbol = parser->states[0].symbol;
2425
0
          fxGetNextToken(parser);
2426
0
          flags = mxAsyncFlag;
2427
//        }
2428
0
      }
2429
0
    }
2430
0
    if (aSymbol == parser->awaitSymbol)
2431
0
      parser->flags |= mxAwaitingFlag;
2432
0
    if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
2433
0
      fxCheckStrictSymbol(parser, aSymbol);
2434
0
      if (flags && (aSymbol == parser->awaitSymbol))
2435
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
2436
0
      fxPushSymbol(parser, aSymbol);
2437
0
      fxPushNULL(parser);
2438
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2439
0
      fxPushNodeList(parser, 1);
2440
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2441
0
      fxArrowExpression(parser, flags);
2442
0
      break;
2443
0
    }
2444
0
    if (aSymbol == parser->argumentsSymbol)
2445
0
      parser->flags |= mxArgumentsFlag;
2446
0
    fxPushSymbol(parser, aSymbol);
2447
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2448
0
    break;
2449
0
  case XS_TOKEN_CLASS:
2450
0
    flags = parser->flags & mxForFlag;
2451
0
    parser->flags &= ~mxForFlag;
2452
0
    fxClassExpression(parser, aLine, C_NULL);
2453
0
    parser->flags |= flags;
2454
0
    break;
2455
0
  case XS_TOKEN_FUNCTION:
2456
0
    fxMatchToken(parser, XS_TOKEN_FUNCTION);
2457
0
    if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
2458
0
      fxGetNextToken(parser);
2459
0
      fxGeneratorExpression(parser, aLine, C_NULL, 0);
2460
0
    }
2461
0
    else
2462
0
      fxFunctionExpression(parser, aLine, C_NULL, 0);
2463
0
    break;
2464
0
  case XS_TOKEN_NEW:
2465
0
    fxNewExpression(parser);
2466
0
    break;
2467
0
  case XS_TOKEN_LEFT_BRACE:
2468
0
    flags = parser->flags & mxForFlag;
2469
0
    parser->flags &= ~mxForFlag;
2470
0
    fxObjectExpression(parser);
2471
0
    parser->flags |= flags;
2472
0
    break;
2473
0
  case XS_TOKEN_LEFT_BRACKET:
2474
0
    flags = parser->flags & mxForFlag;
2475
0
    parser->flags &= ~mxForFlag;
2476
0
    fxArrayExpression(parser);
2477
0
    parser->flags |= flags;
2478
0
    break;
2479
0
  case XS_TOKEN_LEFT_PARENTHESIS:
2480
0
    fxGroupExpression(parser, 0);
2481
0
    break;
2482
0
  case XS_TOKEN_TEMPLATE:
2483
0
    fxPushNULL(parser);
2484
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2485
0
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
2486
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
2487
0
    fxGetNextToken(parser);
2488
0
    fxPushNodeList(parser, 1);
2489
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2490
0
    break;
2491
0
  case XS_TOKEN_TEMPLATE_HEAD:
2492
0
    fxPushNULL(parser);
2493
0
    fxTemplateExpression(parser);
2494
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
2495
0
    break;
2496
0
  case XS_TOKEN_HOST:
2497
0
    fxGetNextToken(parser);
2498
0
    fxPushNULL(parser);
2499
0
    fxPushNULL(parser);
2500
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2501
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2502
0
      fxGetNextToken(parser);
2503
0
    }
2504
0
    else {
2505
0
      fxReportParserError(parser, parser->states[0].line, "invalid host object");
2506
0
      fxPushNULL(parser);
2507
0
    }
2508
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2509
0
    break;
2510
0
  case XS_TOKEN_LESS:
2511
0
    fxGetNextToken(parser);
2512
0
    fxJSXElement(parser);
2513
0
    fxGetNextToken(parser);
2514
0
    break;
2515
0
  default:
2516
0
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2517
0
    fxReportParserError(parser, parser->states[0].line, "missing expression");
2518
0
    break;
2519
0
  }
2520
0
}
2521
2522
void fxArrayExpression(txParser* parser)
2523
0
{
2524
0
  txInteger aCount = 0;
2525
0
  int elision = 1;
2526
0
  txInteger aLine = parser->states[0].line;
2527
0
  txBoolean aSpreadFlag = 0;
2528
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
2529
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)) {
2530
0
    txInteger anItemLine = parser->states[0].line;
2531
0
    if (parser->states[0].token == XS_TOKEN_COMMA) {
2532
0
      fxGetNextToken(parser);
2533
0
      if (elision) {
2534
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_ELISION, anItemLine);
2535
0
        aCount++;
2536
0
      }
2537
0
      else
2538
0
        elision = 1;
2539
0
    }
2540
0
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
2541
0
      fxGetNextToken(parser);
2542
0
      if (!elision)
2543
0
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2544
0
      fxAssignmentExpression(parser);
2545
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, anItemLine);
2546
0
      aCount++;
2547
0
      elision = 0;
2548
0
      aSpreadFlag = 1;
2549
0
    }
2550
0
    else {
2551
0
      if (!elision)
2552
0
        fxReportParserError(parser, parser->states[0].line, "missing ,");
2553
0
      fxAssignmentExpression(parser);
2554
0
      aCount++;
2555
0
      elision = 0;
2556
0
    }
2557
0
  }
2558
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
2559
0
  fxPushNodeList(parser, aCount);
2560
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
2561
0
  if (aCount && elision)
2562
0
    parser->root->flags |= mxElisionFlag;
2563
0
  if (aSpreadFlag)
2564
0
    parser->root->flags |= mxSpreadFlag;
2565
0
}
2566
2567
void fxArrowExpression(txParser* parser, txUnsigned flag)
2568
0
{
2569
0
  txInteger aLine = parser->states[0].line;
2570
0
  txUnsigned flags = parser->flags;
2571
0
  parser->flags &= ~(mxAsyncFlag | mxGeneratorFlag);
2572
0
  parser->flags |= mxArrowFlag | flag;
2573
0
  fxMatchToken(parser, XS_TOKEN_ARROW);
2574
0
  fxPushNULL(parser);
2575
0
  fxSwapNodes(parser);  
2576
0
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2577
0
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2578
0
    fxBody(parser);
2579
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2580
0
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2581
0
  }
2582
0
  else {
2583
0
    fxAssignmentExpression(parser);
2584
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_RETURN, aLine);
2585
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2586
0
    if (!(flags & mxAsyncFlag) && (flag & mxAsyncFlag)) {
2587
0
      if (parser->states[0].token == XS_TOKEN_AWAIT) {
2588
0
        parser->states[0].token = XS_TOKEN_IDENTIFIER;
2589
0
      }
2590
0
    }
2591
0
  }
2592
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2593
0
  parser->root->flags = parser->flags & (mxStrictFlag | mxFieldFlag | mxNotSimpleParametersFlag | mxArrowFlag | mxSuperFlag | flag);
2594
0
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2595
0
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2596
0
  parser->flags = flags | (parser->flags & (mxArgumentsFlag | mxEvalFlag));
2597
0
}
2598
2599
void fxClassExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol)
2600
0
{
2601
0
  txBoolean heritageFlag = 0;
2602
//  txBoolean hostFlag = 0;
2603
0
  txNode* constructor = NULL;
2604
0
  txInteger aCount = 0;
2605
0
  txInteger aLine = parser->states[0].line;
2606
0
  txUnsigned flags = parser->flags;
2607
0
  txUnsigned constructorFlags = mxSuperFlag;
2608
0
  txInteger constructorInitCount = 0;
2609
0
  txInteger instanceInitCount = 0;
2610
0
  parser->flags |= mxStrictFlag;
2611
0
  fxMatchToken(parser, XS_TOKEN_CLASS);
2612
0
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
2613
0
    fxPushSymbol(parser, parser->states[0].symbol);
2614
0
    if (theSymbol)
2615
0
      *theSymbol = parser->states[0].symbol;
2616
0
    fxGetNextToken(parser);
2617
0
  }
2618
0
  else
2619
0
    fxPushNULL(parser);
2620
0
  if (parser->states[0].token == XS_TOKEN_EXTENDS) {
2621
0
    fxMatchToken(parser, XS_TOKEN_EXTENDS);
2622
0
    fxCallExpression(parser);
2623
0
    fxCheckArrowFunction(parser, 1);
2624
0
    fxCheckNativeConstructor(parser);
2625
0
    flags |= parser->flags & mxAwaitingFlag;
2626
0
    constructorFlags |= mxDerivedFlag;
2627
0
    if (parser->root->description->token == XS_TOKEN_HOST)
2628
0
      constructorFlags |= mxHostFlag;
2629
0
    heritageFlag = 1;
2630
0
  }
2631
0
  else if (parser->states[0].token == XS_TOKEN_HOST) {
2632
0
    fxGetNextToken(parser);
2633
0
    fxPushNULL(parser);
2634
0
    fxPushNULL(parser);
2635
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2636
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
2637
0
      fxGetNextToken(parser);
2638
0
    }
2639
0
    else {
2640
0
      fxReportParserError(parser, parser->states[0].line, "invalid host class");
2641
0
      fxPushNULL(parser);
2642
0
    }
2643
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, aLine);
2644
0
    constructorFlags |= mxBaseFlag | mxHostFlag;
2645
//    hostFlag = 1;
2646
0
  }
2647
0
  else {
2648
0
    fxPushNULL(parser);
2649
0
    constructorFlags |= mxBaseFlag;
2650
0
  }
2651
0
  if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2652
0
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2653
0
    for (;;) {
2654
0
      txBoolean aStaticFlag;
2655
0
      txInteger aPropertyLine = parser->states[0].line;
2656
0
      txSymbol* aSymbol;
2657
0
      txToken aToken0;
2658
0
      txToken aToken1;
2659
0
      txToken aToken2;
2660
0
      txUnsigned flag;
2661
0
      while (parser->states[0].token == XS_TOKEN_SEMICOLON)
2662
0
        fxGetNextToken(parser);
2663
0
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
2664
0
        break;
2665
0
      aStaticFlag = 0;
2666
0
      if ((parser->states[0].token == XS_TOKEN_STATIC) && (!parser->states[0].escaped)) {
2667
0
        fxGetNextToken(parser);
2668
0
        if ((parser->states[0].token == XS_TOKEN_ASSIGN) || parser->states[0].token == XS_TOKEN_SEMICOLON) {
2669
0
          fxPushSymbol(parser, parser->staticSymbol);
2670
0
          aToken1 = XS_TOKEN_PROPERTY;
2671
0
          goto field;
2672
0
        }
2673
0
        if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
2674
0
          txUnsigned flags = parser->flags;
2675
0
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag | mxAsyncFlag;
2676
0
          fxCheckParserStack(parser, aPropertyLine);
2677
0
          fxGetNextToken(parser);
2678
0
          fxStatements(parser);
2679
0
          fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2680
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aPropertyLine);
2681
0
          if (parser->flags & mxArgumentsFlag)
2682
0
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2683
0
          if (parser->flags & mxAwaitingFlag)
2684
0
            fxReportParserError(parser, parser->states[0].line, "invalid await");
2685
0
          parser->flags = flags;
2686
0
          parser->root->flags |= mxStaticFlag;
2687
0
          constructorInitCount++;
2688
0
          aCount++;
2689
0
          continue;
2690
0
        }
2691
0
        aStaticFlag = 1;
2692
0
      }
2693
0
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flag);
2694
0
      if ((aStaticFlag == 0) && (aSymbol == parser->constructorSymbol)) {
2695
0
        fxPopNode(parser); // symbol
2696
0
        if (constructor || (aToken2 == XS_TOKEN_GENERATOR) || (aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER) || (flag & mxAsyncFlag)) 
2697
0
          fxReportParserError(parser, parser->states[0].line, "invalid constructor");
2698
0
        fxFunctionExpression(parser, aPropertyLine, C_NULL, constructorFlags);
2699
0
        constructor = fxPopNode(parser);
2700
0
      }
2701
0
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
2702
0
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2703
0
          fxReportParserError(parser, parser->states[0].line, "invalid method: #constructor");
2704
0
        if (aStaticFlag && (aSymbol == parser->prototypeSymbol))
2705
0
          fxReportParserError(parser, parser->states[0].line, "invalid static method: prototype");
2706
0
        if (aStaticFlag)
2707
0
          flag |= mxStaticFlag;
2708
0
        if (aToken2 == XS_TOKEN_GETTER) 
2709
0
          flag |= mxGetterFlag;
2710
0
        else if (aToken2 == XS_TOKEN_SETTER) 
2711
0
          flag |= mxSetterFlag;
2712
0
        else
2713
0
          flag |= mxMethodFlag;
2714
0
        if (aToken2 == XS_TOKEN_GENERATOR)
2715
0
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2716
0
        else
2717
0
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flag);
2718
0
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2719
0
        parser->root->flags |= flag & (mxStaticFlag | mxGetterFlag | mxSetterFlag | mxMethodFlag);
2720
0
        if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
2721
0
          if (aStaticFlag)
2722
0
            constructorInitCount++;
2723
0
          else
2724
0
            instanceInitCount++;
2725
0
        }
2726
0
        aCount++;
2727
0
      }
2728
0
      else {
2729
0
        if ((aToken1 == XS_TOKEN_PRIVATE_PROPERTY) && (aSymbol == parser->privateConstructorSymbol))
2730
0
          fxReportParserError(parser, parser->states[0].line, "invalid field: #constructor");
2731
0
        if (aSymbol == parser->constructorSymbol)
2732
0
          fxReportParserError(parser, parser->states[0].line, "invalid field: constructor");
2733
0
        if (aSymbol == parser->prototypeSymbol)
2734
0
          fxReportParserError(parser, parser->states[0].line, "invalid field: prototype");
2735
0
      field:
2736
0
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
2737
0
          txUnsigned flags = parser->flags;
2738
0
          parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxSuperFlag | mxTargetFlag | mxFieldFlag;
2739
0
          fxGetNextToken(parser);
2740
0
          fxAssignmentExpression(parser);
2741
0
          if (parser->flags & mxArgumentsFlag)
2742
0
            fxReportParserError(parser, parser->states[0].line, "invalid arguments");
2743
0
          parser->flags = flags;
2744
0
        }
2745
0
        else {
2746
0
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2747
0
        }
2748
0
        fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
2749
0
        if (aStaticFlag) {
2750
0
          parser->root->flags |= mxStaticFlag;
2751
0
          constructorInitCount++;
2752
0
        }
2753
0
        else
2754
0
          instanceInitCount++;
2755
0
        fxSemicolon(parser);
2756
0
        aCount++;
2757
0
      }
2758
0
    }
2759
0
  }
2760
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2761
0
  fxPushNodeList(parser, aCount);
2762
  
2763
0
  if (constructorInitCount || instanceInitCount) {
2764
0
    txNodeList* itemsList = (txNodeList*)(parser->root);
2765
0
    txNodeList* constructorInitList = C_NULL;
2766
0
    txNode** constructorInitAddress = C_NULL;
2767
0
    txNodeList* instanceInitList = C_NULL;
2768
0
    txNode** instanceInitAddress = C_NULL;
2769
0
    txNode** address;
2770
0
    txNode* item;
2771
0
    if (constructorInitCount) {
2772
0
      fxPushNULL(parser);
2773
0
      fxPushNodeList(parser, 0);
2774
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2775
0
      fxPushNodeList(parser, 0);
2776
0
      constructorInitList = (txNodeList*)(parser->root);
2777
0
      constructorInitList->length = constructorInitCount;
2778
0
      constructorInitAddress = &(((txNodeList*)(parser->root))->first);
2779
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2780
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2781
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2782
0
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2783
0
    }
2784
0
    else 
2785
0
      fxPushNULL(parser);
2786
0
    if (instanceInitCount) {
2787
0
      fxPushNULL(parser);
2788
0
      fxPushNodeList(parser, 0);
2789
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2790
0
      fxPushNodeList(parser, 0);
2791
0
      instanceInitList = (txNodeList*)(parser->root);
2792
0
      instanceInitList->length = instanceInitCount;
2793
0
      instanceInitAddress = &(((txNodeList*)(parser->root))->first);
2794
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, aLine);
2795
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2796
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2797
0
      parser->root->flags = mxStrictFlag | mxSuperFlag | mxFieldFlag;
2798
0
    }
2799
0
    else 
2800
0
      fxPushNULL(parser);
2801
0
    address = &(itemsList->first);
2802
0
    while ((item = *address)) {
2803
0
      if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2804
0
        if (item->description->token == XS_TOKEN_PRIVATE_PROPERTY) {
2805
0
          txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2806
0
          field->item = item;
2807
0
          if (item->flags & mxStaticFlag) {
2808
0
            *constructorInitAddress = (txNode*)field;
2809
0
            constructorInitAddress = &field->next;
2810
0
          }
2811
0
          else {
2812
0
            *instanceInitAddress = (txNode*)field;
2813
0
            instanceInitAddress = &field->next;
2814
0
          }
2815
0
        }
2816
0
      }
2817
0
      address = &(item->next);
2818
0
    }
2819
0
    address = &(itemsList->first);
2820
0
    while ((item = *address)) {
2821
0
      if (item->description->token == XS_TOKEN_BODY) {
2822
0
        *address = item->next;
2823
0
        item->next = C_NULL;
2824
0
        itemsList->length--;
2825
0
        *constructorInitAddress = (txNode*)item;
2826
0
        constructorInitAddress = &item->next;
2827
0
      }
2828
0
      else if (item->flags & (mxMethodFlag | mxGetterFlag | mxSetterFlag)) {
2829
0
        address = &(item->next);
2830
0
      }
2831
0
      else {
2832
0
        txFieldNode* field = fxFieldNodeNew(parser, XS_TOKEN_FIELD);
2833
0
        field->item = item;
2834
0
        if (item->description->token == XS_TOKEN_PROPERTY) {
2835
0
          field->value = ((txPropertyNode*)item)->value;
2836
0
          ((txPropertyNode*)item)->value = C_NULL;
2837
0
        }
2838
0
        else if (item->description->token == XS_TOKEN_PROPERTY_AT) {
2839
0
          field->value = ((txPropertyAtNode*)item)->value;
2840
0
          ((txPropertyAtNode*)item)->value = C_NULL;
2841
0
        }
2842
0
        else {
2843
0
          field->value = ((txPrivatePropertyNode*)item)->value;
2844
0
          ((txPrivatePropertyNode*)item)->value = C_NULL;
2845
0
        }
2846
0
        if (item->flags & mxStaticFlag) {
2847
0
          *constructorInitAddress = (txNode*)field;
2848
0
          constructorInitAddress = &field->next;
2849
0
        }
2850
0
        else {
2851
0
          *instanceInitAddress = (txNode*)field;
2852
0
          instanceInitAddress = &field->next;
2853
0
        }
2854
0
        address = &(item->next);
2855
0
      }
2856
0
    }
2857
0
  }
2858
0
  else {
2859
0
    fxPushNULL(parser);
2860
0
    fxPushNULL(parser);
2861
0
  }
2862
0
  if (constructor) {
2863
0
    fxPushNode(parser, constructor);
2864
0
  }
2865
0
  else {
2866
0
    if (heritageFlag) {
2867
0
      fxPushNULL(parser);
2868
    
2869
0
      fxPushSymbol(parser, parser->argsSymbol);
2870
0
      fxPushNULL(parser);
2871
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_ARG, aLine);
2872
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
2873
0
      fxPushNodeList(parser, 1);
2874
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2875
      
2876
0
      fxPushSymbol(parser, parser->argsSymbol);
2877
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
2878
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
2879
0
      fxPushNodeList(parser, 1);
2880
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
2881
0
      parser->root->flags |= mxSpreadFlag;
2882
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SUPER, aLine);
2883
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2884
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2885
      
2886
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2887
0
      parser->root->flags = mxStrictFlag | mxDerivedFlag | mxMethodFlag | mxTargetFlag | mxSuperFlag;
2888
0
    }
2889
0
    else {
2890
0
      fxPushNULL(parser);
2891
    
2892
0
      fxPushNodeList(parser, 0);
2893
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
2894
      
2895
0
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
2896
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, aLine);
2897
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, aLine);
2898
      
2899
0
      fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, aLine);
2900
0
      parser->root->flags = mxStrictFlag | mxBaseFlag | mxMethodFlag | mxTargetFlag;
2901
0
    }
2902
0
  }
2903
0
  fxPushNodeStruct(parser, 6, XS_TOKEN_CLASS, aLine);
2904
0
  parser->flags = flags | (parser->flags & (mxArgumentsFlag));
2905
0
}
2906
2907
void fxFunctionExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2908
0
{
2909
0
  txUnsigned flags = parser->flags;
2910
0
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxFunctionFlag | mxTargetFlag | flag;
2911
0
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2912
0
      || ((flags & mxGeneratorFlag) && !(flags & mxStrictFlag) && (parser->states[0].token == XS_TOKEN_YIELD))
2913
0
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2914
0
    fxPushSymbol(parser, parser->states[0].symbol);
2915
0
    if (theSymbol)
2916
0
      *theSymbol = parser->states[0].symbol;
2917
0
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2918
0
    fxGetNextToken(parser);
2919
0
  }
2920
0
  else
2921
0
    fxPushNULL(parser);
2922
0
  fxParametersBinding(parser);
2923
0
  if (parser->states[0].token == XS_TOKEN_HOST) {
2924
0
    fxGetNextToken(parser);
2925
0
    if (parser->states[0].token == XS_TOKEN_STRING) {
2926
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, theLine);
2927
0
      fxGetNextToken(parser);
2928
0
    }
2929
0
    else {
2930
0
      fxReportParserError(parser, parser->states[0].line, "invalid host function");
2931
0
      fxPushNULL(parser);
2932
0
    }
2933
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_HOST, theLine);
2934
0
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2935
0
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2936
0
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2937
0
        parser->flags = flags;
2938
0
  }
2939
0
  else {
2940
0
    fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2941
0
    fxBody(parser);
2942
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2943
0
    fxPushNodeStruct(parser, 3, XS_TOKEN_FUNCTION, theLine);
2944
0
        parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxTargetFlag | mxArgumentsFlag | mxEvalFlag | flag);
2945
0
        if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2946
0
            fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2947
0
        if (parser->flags & mxNativeFlag) {
2948
0
          fxCheckNativeFunction(parser);
2949
0
        }     
2950
0
        parser->flags = flags;
2951
0
        fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2952
0
  }
2953
0
}
2954
2955
void fxGeneratorExpression(txParser* parser, txInteger theLine, txSymbol** theSymbol, txUnsigned flag)
2956
0
{
2957
0
  txUnsigned flags = parser->flags;
2958
0
  parser->flags = (flags & (mxParserFlags | mxStrictFlag)) | mxGeneratorFlag | mxTargetFlag | flag;
2959
0
  if ((parser->states[0].token == XS_TOKEN_IDENTIFIER)
2960
0
      || ((theSymbol == C_NULL) && (parser->states[0].token == XS_TOKEN_AWAIT))) {
2961
0
    fxPushSymbol(parser, parser->states[0].symbol);
2962
0
    if (theSymbol)
2963
0
      *theSymbol = parser->states[0].symbol;
2964
0
    else if (parser->states[0].symbol == parser->yieldSymbol)
2965
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
2966
0
    else if ((parser->flags & mxAsyncFlag) && (parser->states[0].symbol == parser->awaitSymbol))
2967
0
      fxReportParserError(parser, parser->states[0].line, "invalid await");
2968
0
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
2969
0
    fxGetNextToken(parser);
2970
0
  }
2971
0
  else
2972
0
    fxPushNULL(parser);
2973
0
  fxParametersBinding(parser);
2974
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
2975
0
  parser->flags |= mxYieldFlag;
2976
0
    fxBody(parser);
2977
0
  parser->flags &= ~mxYieldFlag;
2978
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_BODY, theLine);
2979
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_GENERATOR, theLine);
2980
0
  parser->root->flags = parser->flags & (mxStrictFlag | mxNotSimpleParametersFlag | mxGeneratorFlag | mxArgumentsFlag | mxEvalFlag | flag);
2981
0
  if (!(flags & mxStrictFlag) && (parser->flags & mxStrictFlag))
2982
0
    fxCheckStrictFunction(parser, (txFunctionNode*)parser->root);
2983
0
  parser->flags = flags;
2984
0
    fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
2985
0
}
2986
2987
void fxGroupExpression(txParser* parser, txUnsigned flag)
2988
0
{
2989
0
  txBoolean commaFlag = 0;
2990
0
  txBoolean spreadFlag = 0;
2991
0
  txInteger aCount = 0;
2992
0
  txInteger aLine;
2993
0
  txUnsigned formerAwaitingYieldingFlags = parser->flags & (mxAwaitingFlag | mxYieldingFlag);
2994
0
  parser->flags &= ~(mxAwaitingFlag | mxYieldingFlag);
2995
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
2996
0
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
2997
0
    aLine = parser->states[0].line;
2998
0
    commaFlag = 0;
2999
0
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3000
0
      fxGetNextToken(parser);
3001
0
      fxAssignmentExpression(parser);
3002
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aLine);
3003
0
      spreadFlag = 1;
3004
0
    }
3005
0
    else
3006
0
      fxAssignmentExpression(parser);
3007
0
    aCount++;
3008
0
    if (parser->states[0].token != XS_TOKEN_COMMA) 
3009
0
      break;
3010
0
    fxGetNextToken(parser);
3011
0
    commaFlag = 1;
3012
0
  }
3013
0
  aLine = parser->states[0].line;
3014
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3015
0
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_ARROW)) {
3016
0
    fxPushNodeList(parser, aCount);
3017
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3018
0
    if (commaFlag && spreadFlag)
3019
0
      fxReportParserError(parser, parser->states[0].line, "invalid parameters");
3020
0
    if (!fxParametersBindingFromExpressions(parser, parser->root))
3021
0
      fxReportParserError(parser, parser->states[0].line, "no parameters");
3022
0
    fxCheckStrictBinding(parser, parser->root);
3023
0
    parser->root->flags |= flag;
3024
0
    if (parser->flags & mxAwaitingFlag) {
3025
0
      if (flag || (parser->flags & mxAsyncFlag))
3026
0
        fxReportParserError(parser, parser->states[0].line, "invalid await");
3027
0
      else
3028
0
        formerAwaitingYieldingFlags |= mxAwaitingFlag;
3029
0
    }
3030
0
    if (parser->flags & mxYieldingFlag)
3031
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
3032
0
    fxArrowExpression(parser, flag);
3033
0
  }
3034
0
  else if (flag) {
3035
0
    fxPushNodeList(parser, aCount);
3036
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3037
0
    if (spreadFlag)
3038
0
      parser->root->flags |= mxSpreadFlag;
3039
    
3040
0
    fxPushSymbol(parser, parser->asyncSymbol);
3041
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aLine);
3042
0
    fxSwapNodes(parser);
3043
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, aLine);
3044
0
  }
3045
0
  else {
3046
0
        if ((aCount == 0) || commaFlag) {
3047
0
            fxPushNULL(parser);
3048
0
      fxReportParserError(parser, parser->states[0].line, "missing expression");
3049
0
        }
3050
0
    else /*if (aCount > 1)*/ {
3051
0
      fxPushNodeList(parser, aCount);
3052
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_EXPRESSIONS, aLine);
3053
0
    }
3054
0
  }
3055
0
  parser->flags |= formerAwaitingYieldingFlags;
3056
0
}
3057
3058
void fxNewExpression(txParser* parser)
3059
0
{
3060
0
  txInteger aLine = parser->states[0].line;
3061
0
  fxMatchToken(parser, XS_TOKEN_NEW);
3062
0
  if (parser->states[0].token == XS_TOKEN_DOT) {
3063
0
    fxGetNextToken(parser);
3064
0
    if (fxIsKeyword(parser, parser->targetSymbol)) {
3065
0
      if (!(parser->flags & mxTargetFlag))
3066
0
        fxReportParserError(parser, parser->states[0].line, "invalid new.target");
3067
0
      fxGetNextToken(parser);
3068
0
      fxPushNodeStruct(parser, 0, XS_TOKEN_TARGET, aLine);
3069
0
    }
3070
0
    else
3071
0
      fxReportParserError(parser, parser->states[0].line, "missing target");
3072
0
    return;
3073
0
  }
3074
0
  fxLiteralExpression(parser, 1);
3075
0
  fxCheckArrowFunction(parser, 1);
3076
0
  for (;;) {
3077
0
    txInteger aMemberLine = parser->states[0].line;
3078
0
    if (parser->states[0].token == XS_TOKEN_DOT) {
3079
0
      fxGetNextToken(parser);
3080
0
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3081
0
        fxPushSymbol(parser, parser->states[0].symbol);
3082
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, aMemberLine);
3083
0
        fxGetNextToken(parser);
3084
0
      }
3085
0
      else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3086
0
        fxPushSymbol(parser, parser->states[0].symbol);
3087
0
        fxSwapNodes(parser);
3088
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_PRIVATE_MEMBER, aMemberLine);
3089
0
        fxGetNextToken(parser);
3090
0
      }
3091
0
      else
3092
0
        fxReportParserError(parser, parser->states[0].line, "missing property");
3093
0
    }
3094
0
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3095
0
      fxGetNextToken(parser);
3096
0
      fxCommaExpression(parser);
3097
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER_AT, aMemberLine);
3098
0
      fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3099
0
    }
3100
0
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE) {
3101
0
      fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3102
0
      fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3103
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3104
0
      fxGetNextToken(parser);
3105
0
      fxPushNodeList(parser, 1);
3106
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3107
0
    }
3108
0
    else if (parser->states[0].token == XS_TOKEN_TEMPLATE_HEAD) {
3109
0
      fxTemplateExpression(parser);
3110
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE, aLine);
3111
0
    }
3112
0
    else
3113
0
      break;
3114
0
  } 
3115
0
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3116
0
    fxParameters(parser);
3117
0
  else {
3118
0
    fxPushNodeList(parser, 0);
3119
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3120
0
  }
3121
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_NEW, aLine);
3122
0
}
3123
3124
void fxObjectExpression(txParser* parser)
3125
0
{
3126
0
  txInteger aCount = 0;
3127
0
  txSymbol* aSymbol;
3128
0
  txToken aToken0;
3129
0
  txToken aToken1;
3130
0
  txToken aToken2;
3131
0
  txInteger aLine = parser->states[0].line;
3132
0
  txNode* base = parser->root;
3133
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3134
0
  for (;;) {
3135
0
    txInteger aPropertyLine = parser->states[0].line;
3136
0
    txUnsigned flags = 0;
3137
0
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3138
0
            break;
3139
0
        if (parser->states[0].token == XS_TOKEN_SPREAD) {
3140
0
      fxGetNextToken(parser);
3141
0
      fxAssignmentExpression(parser);
3142
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aPropertyLine);
3143
0
        }
3144
0
        else {
3145
0
      fxPropertyName(parser, &aSymbol, &aToken0, &aToken1, &aToken2, &flags);
3146
0
      if (aToken1 == XS_TOKEN_PRIVATE_PROPERTY) {
3147
0
        fxReportParserError(parser, parser->states[0].line, "invalid private property");
3148
0
      }
3149
0
      else if ((aToken2 == XS_TOKEN_GETTER) || (aToken2 == XS_TOKEN_SETTER)) {
3150
0
        flags |= mxShorthandFlag;
3151
0
        if (aToken2 == XS_TOKEN_GETTER)
3152
0
          flags |= mxGetterFlag;
3153
0
        else if (aToken2 == XS_TOKEN_SETTER)
3154
0
          flags |= mxSetterFlag;
3155
0
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3156
0
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag);
3157
0
        else
3158
0
          fxReportParserError(parser, parser->states[0].line, "missing (");
3159
0
      }
3160
0
      else if (aToken2 == XS_TOKEN_GENERATOR) {
3161
0
        flags |= mxShorthandFlag | mxMethodFlag;
3162
0
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3163
0
          fxGeneratorExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3164
0
        else
3165
0
          fxReportParserError(parser, parser->states[0].line, "missing (");
3166
0
      }
3167
0
      else if (aToken2 == XS_TOKEN_FUNCTION) {
3168
0
        flags |= mxShorthandFlag | mxMethodFlag;
3169
0
        if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS)
3170
0
          fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3171
0
        else
3172
0
          fxReportParserError(parser, parser->states[0].line, "missing (");
3173
0
      }
3174
0
      else if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3175
0
        flags |= mxShorthandFlag | mxMethodFlag;
3176
0
        fxFunctionExpression(parser, aPropertyLine, C_NULL, mxSuperFlag | flags);
3177
0
      }
3178
0
      else if (parser->states[0].token == XS_TOKEN_COLON) {
3179
0
        fxGetNextToken(parser);
3180
0
        fxAssignmentExpression(parser);
3181
0
      }
3182
0
      else if (aToken1 == XS_TOKEN_PROPERTY) {
3183
0
        flags |= mxShorthandFlag;
3184
0
        fxPushSymbol(parser, aSymbol);
3185
0
        if (parser->states[0].token == XS_TOKEN_ASSIGN) {
3186
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3187
0
          fxGetNextToken(parser);
3188
0
          fxAssignmentExpression(parser);
3189
0
          fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aPropertyLine);
3190
0
        }
3191
0
        else if (aToken0 == XS_TOKEN_IDENTIFIER) {
3192
0
          fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, aPropertyLine);
3193
0
        }
3194
0
        else {
3195
0
          fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3196
0
          fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3197
0
        }
3198
0
      }
3199
0
      else {
3200
0
        fxReportParserError(parser, parser->states[0].line, "missing :");
3201
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aPropertyLine);
3202
0
      }
3203
0
      fxPushNodeStruct(parser, 2, aToken1, aPropertyLine);
3204
0
      parser->root->flags |= flags;
3205
0
      fxCheckUniqueProperty(parser, base, parser->root); 
3206
0
    }
3207
0
    aCount++;
3208
0
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3209
0
            break;
3210
0
    fxMatchToken(parser, XS_TOKEN_COMMA);
3211
0
  }
3212
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3213
0
  fxPushNodeList(parser, aCount);
3214
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
3215
0
}
3216
3217
void fxTemplateExpression(txParser* parser)
3218
0
{
3219
0
  txInteger aCount = 0;
3220
0
  txInteger aLine = parser->states[0].line;
3221
0
  fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3222
0
  fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3223
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3224
0
  aCount++;
3225
0
  for (;;) {
3226
0
    fxGetNextToken(parser);
3227
0
        if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3228
0
            fxCommaExpression(parser);
3229
0
            aCount++;
3230
0
        }
3231
0
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE) {
3232
0
      fxReportParserError(parser, parser->states[0].line, "missing }");
3233
0
    }
3234
0
    fxGetNextTokenTemplate(parser);
3235
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, aLine);
3236
0
    fxPushRawNode(parser, parser->states[0].rawLength, parser->states[0].raw, aLine);
3237
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_TEMPLATE_MIDDLE, aLine);
3238
0
    aCount++;
3239
0
    if (parser->states[0].token == XS_TOKEN_TEMPLATE_TAIL) {
3240
0
      fxGetNextToken(parser);
3241
0
      break;
3242
0
    }
3243
0
  }
3244
0
  fxPushNodeList(parser, aCount);
3245
0
}
3246
3247
void fxYieldExpression(txParser* parser)
3248
0
{
3249
0
  txInteger aLine = parser->states[0].line;
3250
0
  if (!(parser->flags & mxYieldFlag))
3251
0
    fxReportParserError(parser, parser->states[0].line, "invalid yield");
3252
0
  else
3253
0
    parser->flags |= mxYieldingFlag;
3254
0
  fxMatchToken(parser, XS_TOKEN_YIELD);
3255
0
  if ((!parser->states[0].crlf) && (parser->states[0].token == XS_TOKEN_MULTIPLY)) {
3256
0
    fxGetNextToken(parser);
3257
0
    fxAssignmentExpression(parser);
3258
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_DELEGATE, aLine);
3259
0
    return;
3260
0
  }
3261
0
  if ((!parser->states[0].crlf) && (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3262
0
    fxAssignmentExpression(parser);
3263
0
  }
3264
0
  else {
3265
0
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, aLine);
3266
0
  }
3267
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_YIELD, aLine);
3268
0
}
3269
3270
void fxParameters(txParser* parser)
3271
0
{
3272
0
  txInteger aCount = 0;
3273
0
  txInteger aLine = parser->states[0].line;
3274
0
  txBoolean aSpreadFlag = 0;
3275
0
  fxMatchToken(parser, XS_TOKEN_LEFT_PARENTHESIS);
3276
0
  while ((parser->states[0].token == XS_TOKEN_SPREAD) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_EXPRESSION)) {
3277
0
    txInteger aParamLine = parser->states[0].line;
3278
0
    if (parser->states[0].token == XS_TOKEN_SPREAD) {
3279
0
      fxGetNextToken(parser);
3280
0
      fxAssignmentExpression(parser);
3281
0
      fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, aParamLine);
3282
0
      aSpreadFlag = 1;
3283
0
    }
3284
0
    else
3285
0
      fxAssignmentExpression(parser);
3286
0
    aCount++;
3287
0
    if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3288
0
      fxMatchToken(parser, XS_TOKEN_COMMA);
3289
0
  }
3290
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3291
0
  fxPushNodeList(parser, aCount);
3292
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, aLine);
3293
0
  if (aSpreadFlag)
3294
0
    parser->root->flags |= mxSpreadFlag;
3295
0
}
3296
3297
void fxPropertyName(txParser* parser, txSymbol** theSymbol, txToken* theToken0, txToken* theToken1, txToken* theToken2, txUnsigned* flag)
3298
0
{
3299
0
  txSymbol* aSymbol = C_NULL;
3300
0
  txToken aToken0 = XS_NO_TOKEN;
3301
0
  txToken aToken1 = XS_NO_TOKEN;
3302
0
  txToken aToken2 = XS_NO_TOKEN;
3303
0
  txInteger aLine = parser->states[0].line;
3304
0
  txIndex index;
3305
0
  *flag = 0;
3306
0
  fxLookAheadOnce(parser);
3307
0
  aToken0 = parser->states[0].token;
3308
0
  if ((gxTokenFlags[aToken0] & XS_TOKEN_IDENTIFIER_NAME)) {
3309
0
    aSymbol = parser->states[0].symbol;
3310
0
    if (parser->states[1].token == XS_TOKEN_COLON) {
3311
0
      fxPushSymbol(parser, aSymbol);
3312
0
      aToken1 = XS_TOKEN_PROPERTY;
3313
0
    }
3314
0
    else if (fxIsKeyword(parser, parser->asyncSymbol) && (!parser->states[1].crlf)) {
3315
0
      *flag = mxAsyncFlag;
3316
0
      fxGetNextToken(parser);
3317
0
      if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3318
0
        aToken2 = XS_TOKEN_GENERATOR;
3319
0
        fxGetNextToken(parser);
3320
0
      }
3321
0
      else
3322
0
        aToken2 = XS_TOKEN_FUNCTION;
3323
0
    }
3324
0
    else if (fxIsKeyword(parser, parser->getSymbol)) {
3325
0
      aToken2 = XS_TOKEN_GETTER;
3326
0
      fxGetNextToken(parser);
3327
0
    }
3328
0
    else if (fxIsKeyword(parser, parser->setSymbol)) {
3329
0
      aToken2 = XS_TOKEN_SETTER;
3330
0
      fxGetNextToken(parser);
3331
0
    }
3332
0
    else {
3333
0
      fxPushSymbol(parser, aSymbol);
3334
0
      aToken1 = XS_TOKEN_PROPERTY;
3335
0
    }
3336
0
  }
3337
0
  else if (parser->states[0].token == XS_TOKEN_MULTIPLY) {
3338
0
    aToken2 = XS_TOKEN_GENERATOR;
3339
0
    fxGetNextToken(parser);
3340
0
  }
3341
0
  else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3342
0
    aSymbol = parser->states[0].symbol;
3343
0
    fxPushSymbol(parser, aSymbol);
3344
0
    aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3345
0
  }
3346
0
  else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3347
0
    if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3348
0
      fxPushIndexNode(parser, index, aLine);
3349
0
      aToken1 = XS_TOKEN_PROPERTY_AT;
3350
0
    }
3351
0
    else {
3352
0
      aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3353
0
      fxPushSymbol(parser, aSymbol);
3354
0
      aToken1 = XS_TOKEN_PROPERTY;
3355
0
    }
3356
0
  }
3357
0
  else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3358
0
    if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3359
0
      fxPushIndexNode(parser, index, aLine);
3360
0
      aToken1 = XS_TOKEN_PROPERTY_AT;
3361
0
    }
3362
0
    else {
3363
0
      aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3364
0
      fxPushSymbol(parser, aSymbol);
3365
0
      aToken1 = XS_TOKEN_PROPERTY;
3366
0
    }
3367
0
  }
3368
0
  else if (parser->states[0].token == XS_TOKEN_STRING) {
3369
0
    if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3370
0
      fxPushIndexNode(parser, index, aLine);
3371
0
      aToken1 = XS_TOKEN_PROPERTY_AT;
3372
0
    }
3373
0
    else {
3374
0
      aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3375
0
      fxPushSymbol(parser, aSymbol);
3376
0
      aToken1 = XS_TOKEN_PROPERTY;
3377
0
    }
3378
0
  }
3379
0
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3380
0
    fxGetNextToken(parser);
3381
0
    fxCommaExpression(parser);
3382
0
    if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3383
0
      fxReportParserError(parser, parser->states[0].line, "missing ]");
3384
0
    }
3385
0
    aToken1 = XS_TOKEN_PROPERTY_AT;
3386
0
  }
3387
0
  else {
3388
0
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3389
0
    fxPushNULL(parser);
3390
0
  }
3391
0
  if (aToken2 != XS_NO_TOKEN) {
3392
0
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3393
0
      aSymbol = parser->states[0].symbol;
3394
0
      fxPushSymbol(parser, aSymbol);
3395
0
      aToken1 = XS_TOKEN_PROPERTY;
3396
0
      fxGetNextToken(parser);
3397
0
    }
3398
0
    else if (parser->states[0].token == XS_TOKEN_PRIVATE_IDENTIFIER) {
3399
0
      aSymbol = parser->states[0].symbol;
3400
0
      fxPushSymbol(parser, aSymbol);
3401
0
      aToken1 = XS_TOKEN_PRIVATE_PROPERTY;
3402
0
      fxGetNextToken(parser);
3403
0
    }
3404
0
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3405
0
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3406
0
        fxPushIndexNode(parser, index, aLine);
3407
0
        aToken1 = XS_TOKEN_PROPERTY_AT;
3408
0
      }
3409
0
      else {
3410
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3411
0
        fxPushSymbol(parser, aSymbol);
3412
0
        aToken1 = XS_TOKEN_PROPERTY;
3413
0
      }
3414
0
      fxGetNextToken(parser);
3415
0
    }
3416
0
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3417
0
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3418
0
        fxPushIndexNode(parser, index, aLine);
3419
0
        aToken1 = XS_TOKEN_PROPERTY_AT;
3420
0
      }
3421
0
      else {
3422
0
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3423
0
        fxPushSymbol(parser, aSymbol);
3424
0
        aToken1 = XS_TOKEN_PROPERTY;
3425
0
      }
3426
0
      fxGetNextToken(parser);
3427
0
    }
3428
0
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3429
0
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3430
0
        fxPushIndexNode(parser, index, aLine);
3431
0
        aToken1 = XS_TOKEN_PROPERTY_AT;
3432
0
      }
3433
0
      else {
3434
0
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3435
0
        fxPushSymbol(parser, aSymbol);
3436
0
        aToken1 = XS_TOKEN_PROPERTY;
3437
0
      }
3438
0
      fxGetNextToken(parser);
3439
0
    }
3440
0
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3441
0
      fxGetNextToken(parser);
3442
0
      fxCommaExpression(parser);
3443
0
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3444
0
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3445
0
      }
3446
0
      aToken1 = XS_TOKEN_PROPERTY_AT;
3447
0
      fxGetNextToken(parser);
3448
0
    }
3449
0
    else if (aToken2 == XS_TOKEN_GETTER) {
3450
0
      fxPushSymbol(parser, aSymbol);
3451
0
      aToken1 = XS_TOKEN_PROPERTY;
3452
0
      aToken2 = XS_NO_TOKEN;
3453
0
    }
3454
0
    else if (aToken2 == XS_TOKEN_SETTER) {
3455
0
      fxPushSymbol(parser, aSymbol);
3456
0
      aToken1 = XS_TOKEN_PROPERTY;
3457
0
      aToken2 = XS_NO_TOKEN;
3458
0
    }
3459
0
    else {
3460
0
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3461
0
      fxPushNULL(parser);
3462
0
    }
3463
0
  }
3464
0
  else
3465
0
    fxGetNextToken(parser);
3466
0
  *theSymbol = aSymbol;
3467
0
  *theToken0 = aToken0;
3468
0
  *theToken1 = aToken1;
3469
0
  *theToken2 = aToken2;
3470
0
}
3471
3472
void fxBinding(txParser* parser, txToken theToken, txUnsigned flags)
3473
0
{
3474
0
  txInteger aLine = parser->states[0].line;
3475
0
  fxCheckParserStack(parser, aLine);
3476
0
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
3477
0
    fxCheckStrictSymbol(parser, parser->states[0].symbol);
3478
0
    if (((theToken == XS_TOKEN_CONST) || (theToken == XS_TOKEN_LET) || (theToken == XS_TOKEN_USING)) && (parser->states[0].symbol == parser->letSymbol))
3479
0
      fxReportParserError(parser, parser->states[0].line, "invalid identifier");
3480
0
    fxPushSymbol(parser, parser->states[0].symbol);
3481
0
    fxPushNodeStruct(parser, 1, theToken, aLine);
3482
0
    if (flags & mxAwaitingFlag)
3483
0
      parser->root->flags |= mxAwaitingFlag;
3484
0
    fxGetNextToken(parser);
3485
0
  }
3486
0
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
3487
0
    if (theToken == XS_TOKEN_USING)
3488
0
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3489
0
    fxObjectBinding(parser, theToken);
3490
0
  }
3491
0
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3492
0
    if (theToken == XS_TOKEN_USING)
3493
0
      fxReportParserError(parser, parser->states[0].line, "invalid using");
3494
0
    fxArrayBinding(parser, theToken);
3495
0
  }
3496
0
  else {
3497
0
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
3498
0
    fxPushNULL(parser);
3499
0
  }
3500
0
  if ((flags & 1) && (parser->states[0].token == XS_TOKEN_ASSIGN)) {
3501
0
    parser->flags &= ~mxForFlag;
3502
0
    fxGetNextToken(parser);
3503
0
    fxAssignmentExpression(parser);
3504
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_BINDING, aLine);
3505
0
  }
3506
0
}
3507
3508
txNode* fxBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3509
0
{
3510
0
  txToken aToken = (theNode && theNode->description) ? theNode->description->token : XS_NO_TOKEN;
3511
0
  txNode* binding;
3512
0
again:
3513
0
  if (aToken == XS_TOKEN_EXPRESSIONS) {
3514
0
    txNode* item = ((txExpressionsNode*)theNode)->items->first;
3515
0
    if (item && !item->next) {
3516
0
      aToken = item->description->token;
3517
0
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3518
0
        item->next = theNode->next;
3519
0
        theNode = item;
3520
0
      }
3521
0
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
3522
0
        item->next = theNode->next;
3523
0
        theNode = item;
3524
0
        goto again;
3525
0
      }
3526
0
      else
3527
0
        return NULL;
3528
0
    }
3529
0
  }
3530
0
  if (aToken == XS_TOKEN_BINDING) {
3531
0
    binding = fxBindingFromExpression(parser, ((txBindingNode*)theNode)->target, theToken);
3532
0
    ((txBindingNode*)theNode)->target = binding;
3533
//    fxCheckStrictBinding(parser, theNode);
3534
//    fxCheckStrictSymbol(parser, ((txBindingNode*)theNode)->symbol);
3535
//    theNode->description = &gxTokenDescriptions[theToken];
3536
0
    return theNode;
3537
0
  }
3538
0
  if (aToken == XS_TOKEN_ARRAY_BINDING) {
3539
0
    txNodeList* list = ((txArrayBindingNode*)theNode)->items;
3540
0
    txNode** address = &(list->first);
3541
0
    txNode* item;
3542
0
    while ((item = *address)) {
3543
0
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3544
0
      binding->next = item->next;
3545
0
      address = &(binding->next);
3546
0
    }
3547
0
    return theNode;
3548
0
  }
3549
0
  if (aToken == XS_TOKEN_OBJECT_BINDING) {
3550
0
    txNodeList* list = ((txObjectBindingNode*)theNode)->items;
3551
0
    txNode** address = &(list->first);
3552
0
    txNode* item;
3553
0
    while ((item = *address)) {
3554
0
      txNode* binding = *address = fxBindingFromExpression(parser, item, theToken);
3555
0
      binding->next = item->next;
3556
0
      address = &(binding->next);
3557
0
    }
3558
0
    return theNode;
3559
0
  }
3560
0
  if (aToken == XS_TOKEN_PROPERTY_BINDING) {
3561
0
    ((txPropertyBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingNode*)theNode)->binding, theToken);
3562
0
    return theNode;
3563
0
  }
3564
0
  if (aToken == XS_TOKEN_PROPERTY_BINDING_AT) {
3565
0
    ((txPropertyBindingAtNode*)theNode)->binding = fxBindingFromExpression(parser, ((txPropertyBindingAtNode*)theNode)->binding, theToken);
3566
0
    return theNode;
3567
0
  }
3568
0
  if (aToken == XS_TOKEN_REST_BINDING) {
3569
0
    ((txRestBindingNode*)theNode)->binding = fxBindingFromExpression(parser, ((txRestBindingNode*)theNode)->binding, theToken);
3570
0
    return theNode;
3571
0
  }
3572
0
  if (aToken == XS_TOKEN_SKIP_BINDING)
3573
0
    return theNode;
3574
  
3575
0
  if (aToken == XS_TOKEN_ACCESS) {
3576
0
    fxCheckStrictSymbol(parser, ((txAccessNode*)theNode)->symbol);
3577
0
    if (theToken == XS_TOKEN_ACCESS)
3578
0
      return theNode;
3579
0
    fxPushSymbol(parser, ((txAccessNode*)theNode)->symbol);
3580
0
    fxPushNodeStruct(parser, 1, theToken, ((txAccessNode*)theNode)->line);
3581
0
    return fxPopNode(parser);
3582
0
  }
3583
0
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
3584
0
    return theNode;
3585
0
  }
3586
0
  if (aToken == XS_TOKEN_ASSIGN) {
3587
0
    binding = fxBindingFromExpression(parser, ((txAssignNode*)theNode)->reference, theToken);
3588
0
    if (!binding)
3589
0
      return NULL;
3590
0
    ((txBindingNode*)theNode)->description = &gxTokenDescriptions[XS_TOKEN_BINDING];
3591
0
    ((txBindingNode*)theNode)->target = binding;
3592
0
    ((txBindingNode*)theNode)->initializer = ((txAssignNode*)theNode)->value;
3593
0
    return theNode;
3594
0
  }
3595
  
3596
0
  if (aToken == XS_TOKEN_ARRAY)
3597
0
    return fxArrayBindingFromExpression(parser, theNode, theToken);
3598
0
  if (aToken == XS_TOKEN_OBJECT)
3599
0
    return fxObjectBindingFromExpression(parser, theNode, theToken);
3600
0
  return NULL;
3601
0
}
3602
3603
void fxArrayBinding(txParser* parser, txToken theToken)
3604
0
{
3605
0
  txInteger aCount = 0;
3606
0
  txInteger aLine = parser->states[0].line;
3607
0
  int elision = 1;
3608
0
  fxCheckParserStack(parser, aLine);
3609
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACKET);
3610
0
  while ((parser->states[0].token == XS_TOKEN_COMMA) || (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING)) {
3611
0
    txInteger anItemLine = parser->states[0].line;
3612
0
    if (parser->states[0].token == XS_TOKEN_COMMA) {
3613
0
      fxGetNextToken(parser);
3614
0
      if (elision) {
3615
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_SKIP_BINDING, anItemLine);
3616
0
        aCount++;
3617
0
      }
3618
0
      else
3619
0
        elision = 1;
3620
0
    }
3621
0
    else {
3622
0
      if (!elision)
3623
0
        fxReportParserError(parser, parser->states[0].line, "missing ,");
3624
0
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3625
0
        fxRestBinding(parser, theToken, 0);
3626
0
        aCount++;
3627
0
        break;
3628
0
      }
3629
0
      fxBinding(parser, theToken, 1);
3630
0
      aCount++;
3631
0
      elision = 0;
3632
0
    }
3633
0
  }
3634
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACKET);
3635
0
  fxPushNodeList(parser, aCount);
3636
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, aLine);
3637
0
}
3638
3639
txNode* fxArrayBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3640
0
{
3641
0
  txNodeList* list = ((txArrayNode*)theNode)->items;
3642
0
  txNode** address = &(list->first);
3643
0
  txNode* item;
3644
0
  txNode* binding;
3645
0
  while ((item = *address)) {
3646
0
        if (!item->description) {
3647
0
            parser->errorSymbol = parser->SyntaxErrorSymbol;
3648
0
            return NULL;
3649
0
        }
3650
0
    if (item->description->token == XS_TOKEN_SPREAD) {
3651
0
      if (theNode->flags & mxElisionFlag) {
3652
0
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3653
0
        return NULL;
3654
0
      }
3655
0
      binding = fxRestBindingFromExpression(parser, item, theToken, 0);
3656
0
      if (!binding) {
3657
0
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3658
0
        return NULL;
3659
0
      }
3660
0
      break;
3661
0
    }
3662
0
    if (item->description->token == XS_TOKEN_ELISION) {
3663
0
      item->description = &gxTokenDescriptions[XS_TOKEN_SKIP_BINDING];
3664
0
    }
3665
0
    else {
3666
//      if ((theToken == XS_TOKEN_BINDING) && ((item->description->token== XS_TOKEN_MEMBER) || (item->description->token == XS_TOKEN_MEMBER_AT)))
3667
//        binding = item;
3668
//      else {      
3669
0
        binding = fxBindingFromExpression(parser, item, theToken);
3670
0
        if (!binding) {
3671
0
          parser->errorSymbol = parser->SyntaxErrorSymbol;
3672
0
          return NULL;
3673
0
        }
3674
0
        binding->next = item->next;
3675
0
        item = *address = binding;
3676
//      }
3677
0
    }
3678
0
    address = &(item->next);
3679
0
  }
3680
0
  fxPushNode(parser, (txNode*)list);
3681
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY_BINDING, theNode->line);
3682
0
  return fxPopNode(parser);
3683
0
}
3684
3685
txUnsigned fxObjectBinding(txParser* parser, txToken theToken)
3686
0
{
3687
0
  txUnsigned flags = 0;
3688
0
  txInteger aCount = 0;
3689
0
  txInteger aLine = parser->states[0].line;
3690
0
  txSymbol* aSymbol;
3691
0
  txToken aToken;
3692
0
  txIndex index;
3693
0
  fxMatchToken(parser, XS_TOKEN_LEFT_BRACE);
3694
0
  for (;;) {
3695
0
    txInteger aPropertyLine = parser->states[0].line;
3696
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3697
0
      break;
3698
0
    aSymbol = NULL;
3699
0
    aToken = XS_TOKEN_PROPERTY_BINDING;
3700
0
    if ((gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)) {
3701
0
      aSymbol = parser->states[0].symbol;
3702
0
      fxPushSymbol(parser, aSymbol);
3703
0
      aToken = XS_TOKEN_PROPERTY_BINDING;
3704
0
    }
3705
0
    else if (parser->states[0].token == XS_TOKEN_INTEGER) {
3706
0
      if (fxIntegerToIndex(parser->console, parser->states[0].integer, &index)) {
3707
0
        fxPushIndexNode(parser, index, aPropertyLine);
3708
0
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3709
0
      }
3710
0
      else {
3711
0
        aSymbol = fxNewParserSymbol(parser, fxIntegerToString(parser->console, parser->states[0].integer, parser->buffer, parser->bufferSize));
3712
0
        fxPushSymbol(parser, aSymbol);
3713
0
        aToken = XS_TOKEN_PROPERTY_BINDING;
3714
0
      }
3715
0
    }
3716
0
    else if (parser->states[0].token == XS_TOKEN_NUMBER) {
3717
0
      if (fxNumberToIndex(parser->console, parser->states[0].number, &index)) {
3718
0
        fxPushIndexNode(parser, index, aPropertyLine);
3719
0
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3720
0
      }
3721
0
      else {
3722
0
        aSymbol = fxNewParserSymbol(parser, fxNumberToString(parser->console, parser->states[0].number, parser->buffer, parser->bufferSize, 0, 0));
3723
0
        fxPushSymbol(parser, aSymbol);
3724
0
        aToken = XS_TOKEN_PROPERTY_BINDING;
3725
0
      }
3726
0
    }
3727
0
    else if (parser->states[0].token == XS_TOKEN_STRING) {
3728
0
      if (fxStringToIndex(parser->console, parser->states[0].string, &index)) {
3729
0
        fxPushIndexNode(parser, index, aPropertyLine);
3730
0
        aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3731
0
      }
3732
0
      else {
3733
0
        aSymbol = fxNewParserSymbol(parser, parser->states[0].string);
3734
0
        fxPushSymbol(parser, aSymbol);
3735
0
        aToken = XS_TOKEN_PROPERTY_BINDING;
3736
0
      }
3737
0
    }
3738
0
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACKET) {
3739
0
      fxGetNextToken(parser);
3740
0
      fxCommaExpression(parser);
3741
0
      if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET) {
3742
0
        fxReportParserError(parser, parser->states[0].line, "missing ]");
3743
0
      }
3744
0
      aToken = XS_TOKEN_PROPERTY_BINDING_AT;
3745
0
    }
3746
0
    else if (parser->states[0].token == XS_TOKEN_SPREAD) {
3747
0
      flags |= mxSpreadFlag;
3748
0
      fxRestBinding(parser, theToken, 1);
3749
0
      aCount++;
3750
0
            break;
3751
0
    }
3752
0
    else {
3753
0
      fxReportParserError(parser, parser->states[0].line, "missing identifier");
3754
0
      fxPushNULL(parser);
3755
0
    }
3756
0
    fxLookAheadOnce(parser);
3757
0
    if (parser->states[1].token == XS_TOKEN_COLON) {
3758
0
      fxGetNextToken(parser);
3759
0
      fxGetNextToken(parser);
3760
0
      fxBinding(parser, theToken, 1);
3761
0
    }
3762
0
    else if (aSymbol) {
3763
0
      fxBinding(parser, theToken, 1);
3764
0
    }
3765
0
    else {
3766
0
      fxReportParserError(parser, parser->states[0].line, "missing :");
3767
0
      fxPushNULL(parser);
3768
0
    }
3769
0
    fxPushNodeStruct(parser, 2, aToken, aPropertyLine);
3770
0
    aCount++;
3771
0
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
3772
0
            break;
3773
0
    if (parser->states[0].token == XS_TOKEN_COMMA)
3774
0
      fxGetNextToken(parser);
3775
0
    else
3776
0
            break;
3777
0
  }
3778
0
  fxMatchToken(parser, XS_TOKEN_RIGHT_BRACE);
3779
0
  fxPushNodeList(parser, aCount);
3780
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, aLine);
3781
0
  parser->root->flags |= flags;
3782
0
  return flags;
3783
0
}
3784
3785
txNode* fxObjectBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken)
3786
0
{
3787
0
  txNodeList* list = ((txObjectNode*)theNode)->items;
3788
0
  txNode* property = list->first;
3789
0
  txNode* binding;
3790
0
  txUnsigned flags = 0;
3791
0
  while (property) {
3792
0
    if (!property->description) {
3793
0
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3794
0
      return NULL;
3795
0
    }
3796
0
    if (property->description->token == XS_TOKEN_PROPERTY) {
3797
0
      binding = fxBindingFromExpression(parser, ((txPropertyNode*)property)->value, theToken);
3798
0
      if (!binding) {
3799
0
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3800
0
        return NULL;
3801
0
      }
3802
0
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING];
3803
0
      ((txPropertyBindingNode*)property)->binding = binding;
3804
0
    }
3805
0
    else if (property->description->token == XS_TOKEN_PROPERTY_AT) {
3806
0
      binding = fxBindingFromExpression(parser, ((txPropertyAtNode*)property)->value, theToken);
3807
0
      if (!binding) {
3808
0
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3809
0
        return NULL;
3810
0
      }
3811
0
      property->description = &gxTokenDescriptions[XS_TOKEN_PROPERTY_BINDING_AT];
3812
0
      ((txPropertyBindingAtNode*)property)->binding = binding;
3813
0
    }
3814
0
    else if (property->description->token == XS_TOKEN_SPREAD) {
3815
0
      binding = fxRestBindingFromExpression(parser, property, theToken, 1);
3816
0
      if (!binding) {
3817
0
        parser->errorSymbol = parser->SyntaxErrorSymbol;
3818
0
        return NULL;
3819
0
      }
3820
0
      flags |= mxSpreadFlag;
3821
0
      break;
3822
0
    }
3823
0
    property = property->next;
3824
0
  }
3825
0
  fxPushNode(parser, (txNode*)list);
3826
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT_BINDING, theNode->line);
3827
0
  parser->root->flags |= flags;
3828
0
  return fxPopNode(parser);
3829
0
}
3830
3831
void fxParametersBinding(txParser* parser)
3832
0
{
3833
0
  txInteger aCount = 0;
3834
0
  txInteger aLine = parser->states[0].line;
3835
0
  txBindingNode* binding;
3836
0
  if (parser->states[0].token == XS_TOKEN_LEFT_PARENTHESIS) {
3837
0
    fxGetNextToken(parser);
3838
0
    while (gxTokenFlags[parser->states[0].token] & XS_TOKEN_BEGIN_BINDING) {
3839
0
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
3840
0
        parser->flags |= mxNotSimpleParametersFlag;
3841
0
        fxRestBinding(parser, XS_TOKEN_ARG, 0);
3842
0
        aCount++;
3843
0
        break;
3844
0
      }
3845
0
      fxBinding(parser, XS_TOKEN_ARG, 1);
3846
0
      binding = (txBindingNode*)parser->root;
3847
0
      if (binding->description->token != XS_TOKEN_ARG)
3848
0
        parser->flags |= mxNotSimpleParametersFlag;
3849
0
      aCount++;
3850
0
      if (parser->states[0].token != XS_TOKEN_RIGHT_PARENTHESIS)
3851
0
        fxMatchToken(parser, XS_TOKEN_COMMA);
3852
0
    }
3853
0
    fxMatchToken(parser, XS_TOKEN_RIGHT_PARENTHESIS);
3854
0
  }
3855
0
  else
3856
0
    fxReportParserError(parser, parser->states[0].line, "missing (");
3857
0
  fxPushNodeList(parser, aCount);
3858
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS_BINDING, aLine);
3859
0
}
3860
3861
txNode* fxParametersBindingFromExpressions(txParser* parser, txNode* theNode)
3862
0
{
3863
0
  txNodeList* list = ((txParamsNode*)theNode)->items;
3864
0
  txNode** address = &(list->first);
3865
0
  txNode* item;
3866
0
  txBindingNode* binding;
3867
0
  while ((item = *address)) {
3868
0
    txToken aToken = (item && item->description) ? item->description->token : XS_NO_TOKEN;
3869
0
    if (aToken == XS_TOKEN_SPREAD) {
3870
0
      binding = (txBindingNode*)fxRestBindingFromExpression(parser, item, XS_TOKEN_ARG, 0);
3871
0
      if (!binding)
3872
0
        return NULL;
3873
0
      parser->flags |= mxNotSimpleParametersFlag;
3874
0
      break;
3875
0
    }
3876
0
    binding = (txBindingNode*)fxBindingFromExpression(parser, item, XS_TOKEN_ARG);
3877
0
    if (!binding)
3878
0
      return NULL;
3879
0
    if (binding->description->token != XS_TOKEN_ARG)
3880
0
      parser->flags |= mxNotSimpleParametersFlag;
3881
0
    binding->next = item->next;
3882
0
    item = *address = (txNode*)binding;
3883
0
    address = &(item->next);
3884
0
  }
3885
0
  theNode->description = &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING];
3886
0
  return theNode;
3887
0
}
3888
3889
void fxRestBinding(txParser* parser, txToken theToken, txUnsigned flag)
3890
0
{
3891
0
  txInteger aLine = parser->states[0].line;
3892
0
  fxMatchToken(parser, XS_TOKEN_SPREAD);
3893
0
  fxBinding(parser, theToken, 0);
3894
0
  if (flag && ((parser->root->description->token == XS_TOKEN_ARRAY_BINDING) || (parser->root->description->token == XS_TOKEN_OBJECT_BINDING))) {
3895
0
    fxReportParserError(parser, parser->states[0].line, "invalid rest");
3896
0
  }
3897
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_REST_BINDING, aLine);
3898
0
}
3899
3900
txNode* fxRestBindingFromExpression(txParser* parser, txNode* theNode, txToken theToken, txUnsigned flag)
3901
0
{
3902
0
  txNode* expression = ((txSpreadNode*)theNode)->expression;
3903
0
  txNode* binding;
3904
0
  if (theNode->next) {
3905
0
    parser->errorSymbol = parser->SyntaxErrorSymbol;
3906
0
    return NULL;
3907
0
  }
3908
0
  if (!expression)
3909
0
    return NULL;
3910
/*  if ((theToken == XS_TOKEN_BINDING) && ((expression->description->token == XS_TOKEN_MEMBER) || (expression->description->token == XS_TOKEN_MEMBER_AT)))
3911
    binding = expression;
3912
  else */
3913
0
  {
3914
0
    binding = fxBindingFromExpression(parser, expression, theToken);
3915
0
    if (!binding) {
3916
0
      parser->errorSymbol = parser->SyntaxErrorSymbol;
3917
0
      return NULL;
3918
0
    }
3919
0
    if (binding->description->token == XS_TOKEN_BINDING) {
3920
0
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3921
0
      return NULL;
3922
0
    }
3923
0
    if (flag && ((binding->description->token == XS_TOKEN_ARRAY_BINDING) || (binding->description->token == XS_TOKEN_OBJECT_BINDING))) {
3924
0
      fxReportParserError(parser, parser->states[0].line, "invalid rest");
3925
0
      return NULL;
3926
0
    }
3927
0
  }
3928
0
  theNode->description = &gxTokenDescriptions[XS_TOKEN_REST_BINDING];
3929
0
  ((txRestBindingNode*)theNode)->binding = binding;
3930
0
  return theNode;
3931
0
}
3932
3933
void fxCheckArrowFunction(txParser* parser, txInteger count)
3934
0
{
3935
0
  txNode* node = parser->root;
3936
0
  while (count) {
3937
0
    if (node->flags & mxArrowFlag)
3938
0
      fxReportParserError(parser, parser->states[0].line, "invalid arrow function");
3939
0
    count--;
3940
0
    node = node->next;
3941
0
  }
3942
0
}
3943
3944
static void fxReportWarning(txParser* parser, txInteger line, txString theFormat, ...)
3945
0
{
3946
0
  c_va_list arguments;
3947
0
  c_va_start(arguments, theFormat);
3948
0
    (*parser->reportWarning)(parser->console, parser->path ? parser->path->string : C_NULL, line, theFormat, arguments);
3949
0
  c_va_end(arguments);
3950
0
}
3951
3952
void fxCheckNativeConstructor(txParser* parser)
3953
0
{
3954
0
  txClassNode* root = (txClassNode*)(parser->root);
3955
0
  if (root->description != &gxTokenDescriptions[XS_TOKEN_CLASS])
3956
0
    return;
3957
0
  if (root->symbol != C_NULL)
3958
0
    return;
3959
0
  txHostNode* host = (txHostNode*)(root->heritage);
3960
0
  if (host == C_NULL)
3961
0
    return;
3962
0
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
3963
0
    return;
3964
0
  if (root->constructorInit != C_NULL)
3965
0
    return;
3966
0
  if (root->instanceInit != C_NULL)
3967
0
    return;
3968
0
  txFunctionNode* constructor = (txFunctionNode*)(root->constructor);
3969
0
  if (constructor->description != &gxTokenDescriptions[XS_TOKEN_FUNCTION])
3970
0
    return;
3971
0
  txParamsBindingNode* args = (txParamsBindingNode*)(constructor->params);
3972
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
3973
0
    return;
3974
0
  if (args->items->length != 0)
3975
0
    return;
3976
0
  txBodyNode* body = (txBodyNode*)(constructor->body);
3977
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3978
0
    return;
3979
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3980
0
  if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
3981
0
    return;
3982
0
  txNode* undefined = (txNode*)(statement->expression);
3983
0
  if (undefined->description != &gxTokenDescriptions[XS_TOKEN_UNDEFINED])
3984
0
    return;
3985
0
  fxPopNode(parser);
3986
0
  fxPushNode(parser, (txNode*)host);
3987
0
}
3988
3989
void fxCheckNativeFunction(txParser* parser)
3990
0
{
3991
0
  txFunctionNode* function = (txFunctionNode*)(parser->root);
3992
0
  txBodyNode* body = (txBodyNode*)(function->body);
3993
0
  if (body->description != &gxTokenDescriptions[XS_TOKEN_BODY])
3994
0
    goto bail;
3995
0
  txStatementNode* statement = (txStatementNode*)(body->statement);
3996
0
  if ((function->flags & mxDerivedFlag) && (function->flags & mxHostFlag)) {
3997
0
    txStatementsNode* statements = (txStatementsNode*)(statement);
3998
0
    if (statements->description != &gxTokenDescriptions[XS_TOKEN_STATEMENTS])
3999
0
      goto bail;
4000
0
    if (statements->items->length != 2)
4001
0
      goto bail;
4002
0
    statement = (txStatementNode*)(statements->items->first);
4003
0
    if (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT])
4004
0
      goto bail;
4005
0
    txSuperNode* super = (txSuperNode*)(statement->expression);
4006
0
    if (super->description != &gxTokenDescriptions[XS_TOKEN_SUPER])
4007
0
      goto bail;
4008
0
    txParamsNode* params = (txParamsNode*)(super->params);
4009
0
    if (params->items->length != 0)
4010
0
      goto bail;
4011
0
    statement = (txStatementNode*)(statement->next);
4012
0
  }
4013
0
  if ((statement->description != &gxTokenDescriptions[XS_TOKEN_RETURN]) && (statement->description != &gxTokenDescriptions[XS_TOKEN_STATEMENT]))
4014
0
    goto bail;
4015
0
  txCallNewNode* call = (txCallNewNode*)(statement->expression);
4016
0
  if (call->description != &gxTokenDescriptions[XS_TOKEN_CALL])
4017
0
    goto bail;
4018
0
  txMemberNode* member = (txMemberNode*)(call->reference);
4019
0
  if (member->description != &gxTokenDescriptions[XS_TOKEN_MEMBER])
4020
0
    goto bail;
4021
0
  if (member->symbol != parser->callSymbol)
4022
0
    goto bail;
4023
0
  txHostNode* host = (txHostNode*)(member->reference);
4024
0
  if (host->description != &gxTokenDescriptions[XS_TOKEN_HOST])
4025
0
    goto bail;
4026
0
  txParamsNode* params = (txParamsNode*)(call->params);
4027
0
  if (params->description != &gxTokenDescriptions[XS_TOKEN_PARAMS])
4028
0
    goto bail;
4029
0
  txParamsBindingNode* args = (txParamsBindingNode*)(function->params);
4030
0
  if (args->description != &gxTokenDescriptions[XS_TOKEN_PARAMS_BINDING])
4031
0
    goto bail;
4032
0
  if (params->items->length != args->items->length + 1)
4033
0
    goto bail;
4034
0
  txNode* arg = args->items->first;
4035
0
  txNode* param = params->items->first;
4036
0
  if (param->description != &gxTokenDescriptions[XS_TOKEN_THIS])
4037
0
    goto bail;
4038
0
  param = param->next;
4039
0
  while (arg) {
4040
0
    txDeclareNode* binding;
4041
0
    txAccessNode* access;
4042
0
    if (arg->description == &gxTokenDescriptions[XS_TOKEN_REST_BINDING]) {
4043
0
      if (param->description != &gxTokenDescriptions[XS_TOKEN_SPREAD])
4044
0
        goto bail;
4045
0
      binding = (txDeclareNode*)(((txRestBindingNode*)arg)->binding);
4046
0
      access = (txAccessNode*)(((txSpreadNode*)param)->expression);
4047
0
    }
4048
0
    else {
4049
0
      binding = (txDeclareNode*)arg;
4050
0
      access = (txAccessNode*)param;
4051
0
    }
4052
0
    if (binding->description != &gxTokenDescriptions[XS_TOKEN_ARG])
4053
0
      goto bail;
4054
0
    if (access->description != &gxTokenDescriptions[XS_TOKEN_ACCESS])
4055
0
      goto bail;
4056
0
    if (binding->symbol != access->symbol)
4057
0
      goto bail;
4058
0
    arg = arg->next;
4059
0
    param = param->next;
4060
0
  }
4061
0
  host->flags |= function->flags;
4062
0
  host->params = (txNode*)args;
4063
0
  fxPopNode(parser);
4064
0
  fxPushNode(parser, (txNode*)host);
4065
0
  return;
4066
0
bail:
4067
0
    fxReportWarning(parser, function->line, "cannot optimize native");
4068
0
}
4069
4070
txBoolean fxCheckReference(txParser* parser, txToken theToken)
4071
0
{
4072
0
  txNode* node = parser->root;
4073
0
  txToken aToken = (node && node->description) ? node->description->token : XS_NO_TOKEN;
4074
0
  if (aToken == XS_TOKEN_EXPRESSIONS) {
4075
0
    txNode* item;
4076
0
  again:
4077
0
    item = ((txExpressionsNode*)node)->items->first;
4078
0
    if (item && !item->next) {
4079
0
      aToken = (item->description) ? item->description->token : XS_NO_TOKEN;
4080
0
      if ((aToken == XS_TOKEN_ACCESS) || (aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED)) {
4081
0
        item->next = node->next;
4082
0
        node = parser->root = item;
4083
0
      }
4084
0
      else if (aToken == XS_TOKEN_EXPRESSIONS) {
4085
0
        item->next = node->next;
4086
0
        node = item;
4087
0
        goto again;
4088
0
      }
4089
0
      else
4090
0
        aToken = XS_TOKEN_EXPRESSIONS;
4091
0
    }
4092
0
  }
4093
0
  if (aToken == XS_TOKEN_ACCESS) {
4094
0
    fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4095
0
    return 1;
4096
0
  }
4097
0
  if ((aToken == XS_TOKEN_MEMBER) || (aToken == XS_TOKEN_MEMBER_AT) || (aToken == XS_TOKEN_PRIVATE_MEMBER) || (aToken == XS_TOKEN_UNDEFINED))
4098
0
    return 1;
4099
    
4100
0
  if (theToken == XS_TOKEN_ASSIGN) {
4101
0
    if (aToken == XS_TOKEN_ARRAY) {
4102
0
      txNode* binding = fxArrayBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4103
0
            if (binding) {
4104
0
                binding->next = node->next;
4105
0
                parser->root = binding;
4106
0
        return 1;
4107
0
           }
4108
0
        }
4109
0
    else if (aToken == XS_TOKEN_OBJECT) {
4110
0
      txNode* binding = fxObjectBindingFromExpression(parser, node, XS_TOKEN_ACCESS);
4111
0
            if (binding) {
4112
0
                binding->next = node->next;
4113
0
                parser->root = binding;
4114
0
        return 1;
4115
0
            }
4116
0
        }
4117
0
  }
4118
0
  else if (theToken == XS_TOKEN_DELETE)
4119
0
    return 1;
4120
0
  return 0;
4121
0
}
4122
4123
void fxCheckStrictBinding(txParser* parser, txNode* node)
4124
0
{
4125
0
  if (node && node->description) {
4126
0
    if (node->description->token == XS_TOKEN_ACCESS) {
4127
0
      fxCheckStrictSymbol(parser, ((txAccessNode*)node)->symbol);
4128
0
    }
4129
0
    else if (node->description->token == XS_TOKEN_ARG) {
4130
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4131
0
    }
4132
0
    else if (node->description->token == XS_TOKEN_CONST) {
4133
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4134
0
    }
4135
0
    else if (node->description->token == XS_TOKEN_LET) {
4136
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4137
0
    }
4138
0
    else if (node->description->token == XS_TOKEN_USING) {
4139
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4140
0
    }
4141
0
    else if (node->description->token == XS_TOKEN_VAR) {
4142
0
      fxCheckStrictSymbol(parser, ((txDeclareNode*)node)->symbol);
4143
0
    }
4144
0
    else if (node->description->token == XS_TOKEN_BINDING) {
4145
0
      fxCheckStrictBinding(parser, ((txBindingNode*)node)->target);
4146
0
    }
4147
0
    else if (node->description->token == XS_TOKEN_ARRAY_BINDING) {
4148
0
      node = ((txArrayBindingNode*)node)->items->first;
4149
0
      while (node) {
4150
0
        fxCheckStrictBinding(parser, node);
4151
0
        node = node->next;
4152
0
      }
4153
0
    }
4154
0
    else if (node->description->token == XS_TOKEN_OBJECT_BINDING) {
4155
0
      node = ((txObjectBindingNode*)node)->items->first;
4156
0
      while (node) {
4157
0
        fxCheckStrictBinding(parser, node);
4158
0
        node = node->next;
4159
0
      }
4160
0
    }
4161
0
    else if (node->description->token == XS_TOKEN_PARAMS_BINDING) {
4162
0
      node = ((txParamsBindingNode*)node)->items->first;
4163
0
      while (node) {
4164
0
        fxCheckStrictBinding(parser, node);
4165
0
        node = node->next;
4166
0
      }
4167
0
    }
4168
0
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING)
4169
0
      fxCheckStrictBinding(parser, ((txPropertyBindingNode*)node)->binding);
4170
0
    else if (node->description->token == XS_TOKEN_PROPERTY_BINDING_AT)
4171
0
      fxCheckStrictBinding(parser, ((txPropertyBindingAtNode*)node)->binding);
4172
0
    else if (node->description->token == XS_TOKEN_REST_BINDING)
4173
0
      fxCheckStrictBinding(parser, ((txRestBindingNode*)node)->binding);
4174
0
  }
4175
0
}
4176
4177
void fxCheckStrictFunction(txParser* parser, txFunctionNode* function)
4178
0
{
4179
0
  parser->states[0].line = function->line;
4180
0
  fxCheckStrictSymbol(parser, function->symbol);
4181
0
  fxCheckStrictBinding(parser, function->params);
4182
0
}
4183
4184
void fxCheckStrictSymbol(txParser* parser, txSymbol* symbol)
4185
0
{
4186
0
  if (parser->flags & mxStrictFlag) {
4187
0
    if (symbol == parser->argumentsSymbol)
4188
0
      fxReportParserError(parser, parser->states[0].line, "invalid arguments (strict mode)");
4189
0
    else if (symbol == parser->evalSymbol)
4190
0
      fxReportParserError(parser, parser->states[0].line, "invalid eval (strict mode)");
4191
0
    else if (symbol == parser->yieldSymbol)
4192
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield (strict mode)");
4193
0
  }
4194
0
  else if (parser->flags & mxYieldFlag) {
4195
0
    if (symbol == parser->yieldSymbol)
4196
0
      fxReportParserError(parser, parser->states[0].line, "invalid yield");
4197
0
  }
4198
0
}
4199
4200
void fxCheckUniqueProperty(txParser* parser, txNode* base, txNode* current)
4201
0
{
4202
0
  return; // no more!
4203
0
  if (current->description->token == XS_TOKEN_PROPERTY) {
4204
0
    txPropertyNode* currentNode = (txPropertyNode*)current;
4205
0
    while (base != current) {
4206
0
      txPropertyNode* baseNode = (txPropertyNode*)base;
4207
0
      if (baseNode->description->token == XS_TOKEN_PROPERTY) {
4208
0
        if (baseNode->symbol == currentNode->symbol) {
4209
0
          fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4210
0
        }
4211
0
      }
4212
0
      base = base->next;
4213
0
    }
4214
0
  }
4215
0
  else {
4216
0
    txPropertyAtNode* currentNode = (txPropertyAtNode*)current;
4217
0
    txIntegerNode* currentAt = (txIntegerNode*)(currentNode->at);
4218
0
    if (currentAt->description->token == XS_TOKEN_INTEGER) {
4219
0
      while (base != current) {
4220
0
        txPropertyAtNode* baseNode = (txPropertyAtNode*)base;
4221
0
        if (baseNode->description->token == XS_TOKEN_PROPERTY_AT) {
4222
0
          txIntegerNode* baseAt = (txIntegerNode*)(baseNode->at);
4223
0
          if (baseAt->description->token == XS_TOKEN_INTEGER) {
4224
0
            if (baseAt->value == currentAt->value) {
4225
0
              fxCheckUniquePropertyAux(parser, (txNode*)baseNode, (txNode*)currentNode);      
4226
0
            }
4227
0
          }
4228
0
        }
4229
0
        base = base->next;
4230
0
      }
4231
0
    }
4232
0
  }
4233
0
}
4234
4235
void fxCheckUniquePropertyAux(txParser* parser, txNode* baseNode, txNode* currentNode)
4236
0
{
4237
0
  if (currentNode->flags & mxGetterFlag) {
4238
0
    if (baseNode->flags & mxGetterFlag)
4239
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4240
0
    else if (!(baseNode->flags & mxSetterFlag))
4241
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4242
0
  }
4243
0
  else if (currentNode->flags & mxSetterFlag) {
4244
0
    if (baseNode->flags & mxSetterFlag)
4245
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4246
0
    else if (!(baseNode->flags & mxGetterFlag))
4247
0
      fxReportParserError(parser, parser->states[0].line, "property already defined");
4248
0
  }
4249
0
  else {
4250
0
    if (baseNode->flags & mxGetterFlag)
4251
0
      fxReportParserError(parser, parser->states[0].line, "getter already defined");
4252
0
    else if (baseNode->flags & mxSetterFlag)
4253
0
      fxReportParserError(parser, parser->states[0].line, "setter already defined");
4254
0
    else if (parser->flags & mxStrictFlag)
4255
0
      fxReportParserError(parser, parser->states[0].line, "property already defined (strict mode)");
4256
0
  }
4257
0
}
4258
4259
4260
void fxJSONValue(txParser* parser)
4261
0
{
4262
0
  switch (parser->states[0].token) {
4263
0
  case XS_TOKEN_FALSE:
4264
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4265
0
    fxGetNextTokenJSON(parser);
4266
0
    break;
4267
0
  case XS_TOKEN_TRUE:
4268
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4269
0
    fxGetNextTokenJSON(parser);
4270
0
    break;
4271
0
  case XS_TOKEN_NULL:
4272
0
    fxPushNodeStruct(parser, 0, parser->states[0].token, parser->states[0].line);
4273
0
    fxGetNextTokenJSON(parser);
4274
0
    break;
4275
0
  case XS_TOKEN_INTEGER:
4276
0
    fxPushIntegerNode(parser, parser->states[0].integer, parser->states[0].line);
4277
0
    fxGetNextTokenJSON(parser);
4278
0
    break;
4279
0
  case XS_TOKEN_NUMBER:
4280
0
    fxPushNumberNode(parser, parser->states[0].number, parser->states[0].line);
4281
0
    fxGetNextTokenJSON(parser);
4282
0
    break;
4283
0
  case XS_TOKEN_STRING:
4284
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4285
0
    fxGetNextTokenJSON(parser);
4286
0
    break;
4287
0
  case XS_TOKEN_LEFT_BRACE:
4288
0
    fxJSONObject(parser);
4289
0
    break;
4290
0
  case XS_TOKEN_LEFT_BRACKET:
4291
0
    fxJSONArray(parser);
4292
0
    break;
4293
0
  default:
4294
0
    fxPushNULL(parser);
4295
0
    fxReportParserError(parser, parser->states[0].line, "invalid value");
4296
0
    break;
4297
0
  }
4298
0
}
4299
4300
void fxJSONObject(txParser* parser)
4301
0
{
4302
0
  txIndex aLength = 0;
4303
0
  txInteger aLine = parser->states[0].line;
4304
0
  fxGetNextTokenJSON(parser);
4305
0
  for (;;) {
4306
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4307
0
      break;
4308
0
    if (parser->states[0].token != XS_TOKEN_STRING) {
4309
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4310
0
      break;
4311
0
    }
4312
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4313
0
    fxGetNextTokenJSON(parser);
4314
0
    if (parser->states[0].token != XS_TOKEN_COLON) {
4315
0
      fxReportParserError(parser, parser->states[0].line, "missing :");
4316
0
      break;
4317
0
    }
4318
0
    fxGetNextTokenJSON(parser);
4319
0
    fxJSONValue(parser);
4320
0
    fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY_AT, parser->states[0].line);
4321
0
    aLength++;
4322
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4323
0
      break;
4324
0
    fxGetNextTokenJSON(parser);
4325
0
  }
4326
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4327
0
    fxReportParserError(parser, parser->states[0].line, "missing }");
4328
0
  fxGetNextTokenJSON(parser);
4329
0
  fxPushNodeList(parser, aLength);
4330
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, aLine);
4331
0
}
4332
4333
void fxJSONArray(txParser* parser)
4334
0
{
4335
0
  txIndex aLength = 0;
4336
0
  txInteger aLine = parser->states[0].line;
4337
0
  fxGetNextTokenJSON(parser);
4338
0
  for (;;) {
4339
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACKET)
4340
0
      break;
4341
0
    fxJSONValue(parser);
4342
0
    aLength++;
4343
0
    if (parser->states[0].token != XS_TOKEN_COMMA)
4344
0
      break;
4345
0
    fxGetNextTokenJSON(parser);
4346
0
  }
4347
0
  if (parser->states[0].token != XS_TOKEN_RIGHT_BRACKET)
4348
0
    fxReportParserError(parser, parser->states[0].line, "missing ]");
4349
0
  fxGetNextTokenJSON(parser);
4350
0
  fxPushNodeList(parser, aLength);
4351
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ARRAY, aLine);
4352
0
}
4353
4354
void fxJSONModule(txParser* parser)
4355
0
{
4356
0
  fxJSONValue(parser);
4357
  
4358
0
  fxPushSymbol(parser, parser->defaultSymbol);
4359
0
  fxPushNULL(parser);
4360
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_CONST, 1);
4361
0
  fxSwapNodes(parser);
4362
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_ASSIGN, 1);
4363
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENT, 1);
4364
  
4365
0
  fxPushSymbol(parser, parser->defaultSymbol);
4366
0
  fxPushNULL(parser);
4367
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_SPECIFIER, 1);
4368
0
  fxPushNodeList(parser, 1);
4369
0
  fxPushNULL(parser);
4370
0
  fxPushNULL(parser);
4371
0
  fxPushNodeStruct(parser, 3, XS_TOKEN_EXPORT, 1);
4372
  
4373
0
  fxPushNodeList(parser, 2);
4374
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_STATEMENTS, 1);
4375
  
4376
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_MODULE, 1);
4377
0
}
4378
4379
static txSymbol* fxJSXName(txParser* parser, txSymbol* before, txSymbol* after)
4380
0
{
4381
0
  txSize beforeLength = before->length;
4382
0
  txSize afterLength = after->length;
4383
0
  txSize length = beforeLength + 1 + afterLength + 1;
4384
0
  txString string = fxNewParserChunk(parser, length);
4385
0
  snprintf(string, length, "%s-%s", before->string, after->string);
4386
0
  return fxNewParserSymbol(parser, string);
4387
0
}
4388
4389
void fxJSXAttributeName(txParser* parser)
4390
0
{
4391
0
  txSymbol* symbol = parser->states[0].symbol;
4392
0
  fxGetNextToken(parser);
4393
0
  while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4394
0
    fxGetNextToken(parser);
4395
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4396
0
      symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4397
0
    else
4398
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4399
0
    fxGetNextToken(parser);
4400
0
  }
4401
0
  if (parser->states[0].token == XS_TOKEN_COLON) {
4402
0
    fxGetNextToken(parser);
4403
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4404
0
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4405
0
    else
4406
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4407
0
    fxGetNextToken(parser);
4408
0
    while (parser->states[0].token == XS_TOKEN_SUBTRACT) {
4409
0
      fxGetNextToken(parser);
4410
0
      if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME)
4411
0
        symbol = fxJSXName(parser, symbol, parser->states[0].symbol);
4412
0
      else
4413
0
        fxReportParserError(parser, parser->states[0].line, "missing name");
4414
0
      fxGetNextToken(parser);
4415
0
    } 
4416
0
  }
4417
0
  fxPushSymbol(parser, symbol);
4418
0
}
4419
4420
void fxJSXAttributeValue(txParser* parser)
4421
0
{
4422
0
  txInteger line = parser->states[0].line;
4423
0
  fxGetNextTokenJSXAttribute(parser);
4424
0
  if (parser->states[0].token == XS_TOKEN_STRING) {
4425
0
    fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, line);
4426
0
    fxGetNextToken(parser);
4427
0
  }
4428
0
  else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4429
0
    fxGetNextToken(parser);
4430
0
    if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE) {
4431
0
      fxGetNextToken(parser);
4432
0
      fxReportParserError(parser, parser->states[0].line, "missing expression");
4433
0
      fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4434
0
    }
4435
0
    else {
4436
0
      fxAssignmentExpression(parser);
4437
0
      if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4438
0
        fxGetNextToken(parser);
4439
0
      else
4440
0
        fxReportParserError(parser, parser->states[0].line, "missing }");
4441
0
    }
4442
0
  }
4443
0
  else {
4444
0
    fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4445
0
    fxPushNodeStruct(parser, 0, XS_TOKEN_UNDEFINED, line);
4446
0
  }
4447
0
}
4448
4449
void fxJSXElement(txParser* parser)
4450
0
{
4451
0
  txBoolean closed = 0;
4452
0
  txInteger line = parser->states[0].line;
4453
0
  txNode* name = NULL;
4454
0
  txInteger nodeCount = parser->nodeCount;
4455
0
  txInteger propertyCount = 0;
4456
0
  fxCheckParserStack(parser, line);
4457
0
  fxPushSymbol(parser, parser->__jsx__Symbol);
4458
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, parser->states[0].line);
4459
0
  if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4460
0
    fxJSXElementName(parser);
4461
0
    name = parser->root;
4462
0
  }
4463
0
  else {
4464
0
    fxReportParserError(parser, parser->states[0].line, "missing identifier");
4465
0
    fxPushNULL(parser);
4466
0
  }
4467
0
  for (;;) {
4468
0
    if (parser->states[0].token == XS_TOKEN_MORE)
4469
0
      break;
4470
0
    if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4471
0
      fxGetNextToken(parser);
4472
0
      if (parser->states[0].token != XS_TOKEN_MORE)
4473
0
        fxReportParserError(parser, parser->states[0].line, "missing >");
4474
0
      closed = 1;
4475
0
      break;
4476
0
    }
4477
0
    if (gxTokenFlags[parser->states[0].token] & XS_TOKEN_IDENTIFIER_NAME) {
4478
0
      fxJSXAttributeName(parser);
4479
0
      if (parser->states[0].token == XS_TOKEN_ASSIGN)
4480
0
        fxJSXAttributeValue(parser);
4481
0
      else
4482
0
        fxPushNodeStruct(parser, 0, XS_TOKEN_TRUE, parser->states[0].line);
4483
0
      fxPushNodeStruct(parser, 2, XS_TOKEN_PROPERTY, parser->states[0].line);
4484
0
      propertyCount++;
4485
0
    }
4486
0
    else if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4487
0
      fxGetNextToken(parser);
4488
0
      if (parser->states[0].token == XS_TOKEN_SPREAD) {
4489
0
        fxGetNextToken(parser);
4490
0
        fxAssignmentExpression(parser);
4491
0
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4492
0
          fxGetNextToken(parser);
4493
0
        else
4494
0
          fxReportParserError(parser, parser->states[0].line, "missing }");
4495
0
        fxPushNodeStruct(parser, 1, XS_TOKEN_SPREAD, parser->states[0].line);
4496
0
        propertyCount++;
4497
0
      }
4498
0
      else
4499
0
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4500
0
    }
4501
0
    else {
4502
0
      fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4503
0
      break;
4504
0
    }
4505
0
  }
4506
0
  if (propertyCount > 0) {
4507
0
    fxPushNodeList(parser, propertyCount);
4508
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_OBJECT, parser->states[0].line);
4509
0
  }
4510
0
  else
4511
0
    fxPushNodeStruct(parser, 0, XS_TOKEN_NULL, parser->states[0].line);
4512
0
  if (!closed) {
4513
0
    for (;;) {
4514
0
      fxGetNextTokenJSXChild(parser);
4515
0
      if (parser->states[0].stringLength)
4516
0
        fxPushStringNode(parser, parser->states[0].stringLength, parser->states[0].string, parser->states[0].line);
4517
0
      if (parser->states[0].token == XS_TOKEN_LEFT_BRACE) {
4518
0
        fxGetNextToken(parser);
4519
0
        if (parser->states[0].token == XS_TOKEN_RIGHT_BRACE)
4520
0
          fxGetNextToken(parser);
4521
0
        else {
4522
0
          fxAssignmentExpression(parser);
4523
0
          if (parser->states[0].token != XS_TOKEN_RIGHT_BRACE)
4524
0
            fxReportParserError(parser, parser->states[0].line, "missing }");
4525
0
        }
4526
0
      }
4527
0
      else if (parser->states[0].token == XS_TOKEN_LESS) {
4528
0
        fxGetNextToken(parser);
4529
0
        if (parser->states[0].token == XS_TOKEN_DIVIDE) {
4530
0
          fxGetNextToken(parser);
4531
0
          if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4532
0
            fxJSXElementName(parser);
4533
0
            if (!fxJSXMatch(parser, name, parser->root)) {
4534
0
              fxReportParserError(parser, parser->states[0].line, "invalid element");
4535
0
              fxPushNULL(parser);
4536
0
            }
4537
0
          }
4538
0
          else {
4539
0
            fxReportParserError(parser, parser->states[0].line, "missing identifier");
4540
0
            fxPushNULL(parser);
4541
0
          }
4542
0
          if (parser->states[0].token != XS_TOKEN_MORE)
4543
0
            fxReportParserError(parser, parser->states[0].line, "missing >");
4544
0
          fxPopNode(parser);
4545
0
          break;
4546
0
        }
4547
0
        else
4548
0
          fxJSXElement(parser);
4549
0
      }
4550
0
      else {
4551
0
        fxReportParserError(parser, parser->states[0].line, "invalid %s", gxTokenNames[parser->states[0].token]);
4552
0
        break;
4553
0
      }
4554
0
    }
4555
0
  }
4556
0
  fxPushNodeList(parser, parser->nodeCount - nodeCount - 1);
4557
0
  fxPushNodeStruct(parser, 1, XS_TOKEN_PARAMS, line);
4558
0
  fxPushNodeStruct(parser, 2, XS_TOKEN_CALL, line);
4559
0
}
4560
4561
void fxJSXElementName(txParser* parser)
4562
0
{
4563
0
  txInteger line = parser->states[0].line;
4564
0
  txSymbol* symbol = parser->states[0].symbol;
4565
0
  fxGetNextToken(parser);
4566
0
  if (parser->states[0].token == XS_TOKEN_COLON) {
4567
0
    fxGetNextToken(parser);
4568
0
    if (parser->states[0].token == XS_TOKEN_IDENTIFIER)
4569
0
      symbol = fxJSXNamespace(parser, symbol, parser->states[0].symbol);
4570
0
    else
4571
0
      fxReportParserError(parser, parser->states[0].line, "missing name");
4572
0
    fxPushSymbol(parser, symbol);
4573
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4574
0
    fxGetNextToken(parser);
4575
0
  }
4576
0
  else {
4577
0
    fxPushSymbol(parser, symbol);
4578
0
    fxPushNodeStruct(parser, 1, XS_TOKEN_ACCESS, line);
4579
0
    while (parser->states[0].token == XS_TOKEN_DOT) {
4580
0
      fxGetNextToken(parser);
4581
0
      if (parser->states[0].token == XS_TOKEN_IDENTIFIER) {
4582
0
        fxPushSymbol(parser, parser->states[0].symbol);
4583
0
        fxPushNodeStruct(parser, 2, XS_TOKEN_MEMBER, parser->states[0].line);
4584
0
        fxGetNextToken(parser);
4585
0
      }
4586
0
      else
4587
0
        fxReportParserError(parser, parser->states[0].line, "missing property");
4588
0
    }
4589
0
  }
4590
0
}
4591
4592
txBoolean fxJSXMatch(txParser* parser, txNode* opening, txNode* closing)
4593
0
{
4594
0
  if (opening && closing) {
4595
0
    while (opening->description->token == XS_TOKEN_MEMBER) {
4596
0
      if (closing->description->token != XS_TOKEN_MEMBER)
4597
0
        return 0;
4598
0
      if (((txMemberNode*)opening)->symbol != ((txMemberNode*)closing)->symbol)
4599
0
        return 0;
4600
0
      opening = ((txMemberNode*)opening)->reference;
4601
0
      closing = ((txMemberNode*)closing)->reference;
4602
0
    }
4603
0
    if (opening->description->token == XS_TOKEN_ACCESS) {
4604
0
      if (closing->description->token != XS_TOKEN_ACCESS)
4605
0
        return 0;
4606
0
      if (((txAccessNode*)opening)->symbol != ((txAccessNode*)closing)->symbol)
4607
0
        return 0;
4608
0
      return 1;
4609
0
    }
4610
0
  }
4611
0
  return 0;
4612
0
}
4613
4614
txSymbol* fxJSXNamespace(txParser* parser, txSymbol* namespace, txSymbol* name)
4615
0
{
4616
0
  txSize namespaceLength = namespace->length;
4617
0
  txSize nameLength = name->length;
4618
0
  txSize length = namespaceLength + 1 + nameLength + 1;
4619
0
  txString string = fxNewParserChunk(parser, length);
4620
0
  snprintf(string, length, "%s:%s", namespace->string, name->string);
4621
0
  return fxNewParserSymbol(parser, string);
4622
0
}