@ibyar/expressions 0.3.0 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +79 -6
  3. package/api/abstract.d.ts +5 -7
  4. package/api/abstract.js +2 -5
  5. package/api/abstract.js.map +1 -1
  6. package/api/app/class.d.ts +99 -8
  7. package/api/app/class.js +250 -29
  8. package/api/app/class.js.map +1 -1
  9. package/api/app/program.d.ts +1 -2
  10. package/api/app/program.js +1 -4
  11. package/api/app/program.js.map +1 -1
  12. package/api/computing/call.d.ts +4 -4
  13. package/api/computing/call.js +20 -22
  14. package/api/computing/call.js.map +1 -1
  15. package/api/computing/new.d.ts +1 -2
  16. package/api/computing/new.js +4 -7
  17. package/api/computing/new.js.map +1 -1
  18. package/api/computing/rest.d.ts +16 -0
  19. package/api/computing/rest.js +40 -0
  20. package/api/computing/rest.js.map +1 -0
  21. package/api/computing/return.d.ts +1 -2
  22. package/api/computing/return.js +2 -5
  23. package/api/computing/return.js.map +1 -1
  24. package/api/computing/spread.d.ts +1 -2
  25. package/api/computing/spread.js +3 -9
  26. package/api/computing/spread.js.map +1 -1
  27. package/api/computing/throw.d.ts +3 -6
  28. package/api/computing/throw.js +5 -14
  29. package/api/computing/throw.js.map +1 -1
  30. package/api/definition/array.d.ts +12 -10
  31. package/api/definition/array.js +44 -16
  32. package/api/definition/array.js.map +1 -1
  33. package/api/definition/bind.d.ts +21 -0
  34. package/api/definition/bind.js +81 -0
  35. package/api/definition/bind.js.map +1 -0
  36. package/api/definition/comment.d.ts +1 -2
  37. package/api/definition/comment.js +1 -4
  38. package/api/definition/comment.js.map +1 -1
  39. package/api/definition/function.d.ts +12 -15
  40. package/api/definition/function.js +49 -58
  41. package/api/definition/function.js.map +1 -1
  42. package/api/definition/member.d.ts +8 -5
  43. package/api/definition/member.js +40 -31
  44. package/api/definition/member.js.map +1 -1
  45. package/api/definition/object.d.ts +16 -17
  46. package/api/definition/object.js +24 -16
  47. package/api/definition/object.js.map +1 -1
  48. package/api/definition/statement.d.ts +1 -2
  49. package/api/definition/statement.js +2 -5
  50. package/api/definition/statement.js.map +1 -1
  51. package/api/definition/values.d.ts +12 -11
  52. package/api/definition/values.js +17 -12
  53. package/api/definition/values.js.map +1 -1
  54. package/api/expression.d.ts +8 -4
  55. package/api/expression.js.map +1 -1
  56. package/api/index.d.ts +7 -6
  57. package/api/index.js +7 -6
  58. package/api/index.js.map +1 -1
  59. package/api/module/export.d.ts +1 -2
  60. package/api/module/export.js +1 -4
  61. package/api/module/export.js.map +1 -1
  62. package/api/module/import.d.ts +1 -2
  63. package/api/module/import.js +1 -4
  64. package/api/module/import.js.map +1 -1
  65. package/api/module/module.d.ts +1 -2
  66. package/api/module/module.js +2 -5
  67. package/api/module/module.js.map +1 -1
  68. package/api/operators/assignment.js +2 -2
  69. package/api/operators/assignment.js.map +1 -1
  70. package/api/operators/await.d.ts +1 -2
  71. package/api/operators/await.js +2 -5
  72. package/api/operators/await.js.map +1 -1
  73. package/api/operators/binary.js +4 -4
  74. package/api/operators/binary.js.map +1 -1
  75. package/api/operators/chaining.d.ts +9 -13
  76. package/api/operators/chaining.js +14 -48
  77. package/api/operators/chaining.js.map +1 -1
  78. package/api/operators/comma.d.ts +1 -2
  79. package/api/operators/comma.js +2 -5
  80. package/api/operators/comma.js.map +1 -1
  81. package/api/operators/grouping.d.ts +1 -2
  82. package/api/operators/grouping.js +2 -5
  83. package/api/operators/grouping.js.map +1 -1
  84. package/api/operators/logical.js.map +1 -1
  85. package/api/operators/pipeline.d.ts +4 -5
  86. package/api/operators/pipeline.js +23 -25
  87. package/api/operators/pipeline.js.map +1 -1
  88. package/api/operators/ternary.d.ts +1 -2
  89. package/api/operators/ternary.js +1 -4
  90. package/api/operators/ternary.js.map +1 -1
  91. package/api/operators/unary.d.ts +1 -2
  92. package/api/operators/unary.js +2 -5
  93. package/api/operators/unary.js.map +1 -1
  94. package/api/operators/update.d.ts +1 -2
  95. package/api/operators/update.js +2 -5
  96. package/api/operators/update.js.map +1 -1
  97. package/api/statement/{controlflow → control}/block.d.ts +1 -2
  98. package/api/statement/{controlflow → control}/block.js +2 -5
  99. package/api/statement/control/block.js.map +1 -0
  100. package/api/statement/{controlflow → control}/empty.d.ts +1 -2
  101. package/api/statement/{controlflow → control}/empty.js +1 -4
  102. package/api/statement/control/empty.js.map +1 -0
  103. package/api/statement/{controlflow → control}/if.d.ts +1 -2
  104. package/api/statement/{controlflow → control}/if.js +2 -5
  105. package/api/statement/control/if.js.map +1 -0
  106. package/api/statement/{controlflow → control}/switch.d.ts +2 -4
  107. package/api/statement/{controlflow → control}/switch.js +5 -11
  108. package/api/statement/control/switch.js.map +1 -0
  109. package/api/statement/{controlflow → control}/terminate.d.ts +1 -2
  110. package/api/statement/{controlflow → control}/terminate.js +1 -4
  111. package/api/statement/control/terminate.js.map +1 -0
  112. package/api/statement/declarations/declares.d.ts +13 -14
  113. package/api/statement/declarations/declares.js +10 -9
  114. package/api/statement/declarations/declares.js.map +1 -1
  115. package/api/statement/iterations/for.d.ts +14 -14
  116. package/api/statement/iterations/for.js +12 -24
  117. package/api/statement/iterations/for.js.map +1 -1
  118. package/api/statement/iterations/while.d.ts +2 -4
  119. package/api/statement/iterations/while.js +4 -10
  120. package/api/statement/iterations/while.js.map +1 -1
  121. package/package.json +18 -4
  122. package/scope/scope.d.ts +23 -3
  123. package/scope/scope.js +67 -1
  124. package/scope/scope.js.map +1 -1
  125. package/scope/stack.d.ts +14 -3
  126. package/scope/stack.js +61 -1
  127. package/scope/stack.js.map +1 -1
  128. package/v8/app.js.map +1 -1
  129. package/v8/nodes.d.ts +1 -2
  130. package/v8/nodes.js +2 -11
  131. package/v8/nodes.js.map +1 -1
  132. package/v8/parser.d.ts +5 -4
  133. package/v8/parser.js +165 -69
  134. package/v8/parser.js.map +1 -1
  135. package/v8/stream.js +20 -6
  136. package/v8/stream.js.map +1 -1
  137. package/v8/token.d.ts +3 -0
  138. package/v8/token.js +9 -0
  139. package/v8/token.js.map +1 -1
  140. package/api/operators/destruct.d.ts +0 -19
  141. package/api/operators/destruct.js +0 -95
  142. package/api/operators/destruct.js.map +0 -1
  143. package/api/statement/controlflow/block.js.map +0 -1
  144. package/api/statement/controlflow/empty.js.map +0 -1
  145. package/api/statement/controlflow/if.js.map +0 -1
  146. package/api/statement/controlflow/switch.js.map +0 -1
  147. package/api/statement/controlflow/terminate.js.map +0 -1
package/v8/parser.js CHANGED
@@ -1,22 +1,24 @@
1
1
  import { Token } from './token.js';
2
2
  import { TokenStream } from './stream.js';
3
3
  import { OfNode, Identifier, ThisNode, GetIdentifier, SetIdentifier, AsyncIdentifier, NullNode, StringLiteral, AwaitIdentifier, ConstructorIdentifier, NameIdentifier, EvalIdentifier, ArgumentsIdentifier, TaggedTemplateExpression, TemplateLiteral } from '../api/definition/values.js';
4
- import { EmptyStatement } from '../api/statement/controlflow/empty.js';
5
- import { BlockStatement } from '../api/statement/controlflow/block.js';
6
- import { ArrowFunctionExpression, ArrowFunctionType, FunctionKind, Paramter, FunctionExpression } from '../api/definition/function.js';
7
- import { IfStatement } from '../api/statement/controlflow/if.js';
4
+ import { EmptyStatement } from '../api/statement/control/empty.js';
5
+ import { BlockStatement } from '../api/statement/control/block.js';
6
+ import { ArrowFunctionExpression, ArrowFunctionType, FunctionKind, Param, FunctionExpression, FunctionDeclaration } from '../api/definition/function.js';
7
+ import { IfStatement } from '../api/statement/control/if.js';
8
8
  import { NewExpression } from '../api/computing/new.js';
9
9
  import { SpreadElement } from '../api/computing/spread.js';
10
+ import { RestElement } from '../api/computing/rest.js';
10
11
  import { AssignmentExpression } from '../api/operators/assignment.js';
11
12
  import { GroupingExpression } from '../api/operators/grouping.js';
12
13
  import { MemberExpression } from '../api/definition/member.js';
14
+ import { BindExpression } from '../api/definition/bind.js';
13
15
  import { ObjectExpression, Property, ObjectPattern } from '../api/definition/object.js';
14
16
  import { ArrayExpression, ArrayPattern } from '../api/definition/array.js';
15
17
  import { CallExpression } from '../api/computing/call.js';
16
18
  import { DoWhileNode, WhileNode } from '../api/statement/iterations/while.js';
17
19
  import { CatchClauseNode, ThrowStatement, TryCatchNode } from '../api/computing/throw.js';
18
- import { SwitchCase, DefaultExpression, SwitchStatement } from '../api/statement/controlflow/switch.js';
19
- import { BreakStatement, ContinueStatement } from '../api/statement/controlflow/terminate.js';
20
+ import { SwitchCase, DefaultExpression, SwitchStatement } from '../api/statement/control/switch.js';
21
+ import { BreakStatement, ContinueStatement } from '../api/statement/control/terminate.js';
20
22
  import { ReturnStatement } from '../api/computing/return.js';
21
23
  import { VariableNode, VariableDeclarationNode } from '../api/statement/declarations/declares.js';
22
24
  import { ForNode, ForOfNode, ForInNode, ForAwaitOfNode } from '../api/statement/iterations/for.js';
@@ -27,7 +29,7 @@ import { SequenceExpression } from '../api/operators/comma.js';
27
29
  import { ChainExpression } from '../api/operators/chaining.js';
28
30
  import { ExpressionStatement } from '../api/definition/statement.js';
29
31
  import { buildPostfixExpression, buildUnaryExpression, expressionFromLiteral, shortcutNumericLiteralBinaryExpression } from './nodes.js';
30
- import { BinaryExpression } from '../api/index.js';
32
+ import { BinaryExpression } from '../api/operators/binary.js';
31
33
  export var ParsingArrowHeadFlag;
32
34
  (function (ParsingArrowHeadFlag) {
33
35
  ParsingArrowHeadFlag[ParsingArrowHeadFlag["CertainlyNotArrowHead"] = 0] = "CertainlyNotArrowHead";
@@ -750,6 +752,9 @@ export class JavaScriptParser extends AbstractParser {
750
752
  const formals = this.parseFormalParameterList(functionInfo);
751
753
  this.expect(Token.R_PARENTHESES);
752
754
  const body = this.parseFunctionBody();
755
+ if (name) {
756
+ return new FunctionDeclaration(formals, body, flag, name, functionInfo.rest);
757
+ }
753
758
  return new FunctionExpression(formals, body, flag, name, functionInfo.rest);
754
759
  }
755
760
  parseFunctionBody() {
@@ -809,10 +814,10 @@ export class JavaScriptParser extends AbstractParser {
809
814
  throw new Error(this.errorMessage(`Rest Default Initializer`));
810
815
  }
811
816
  const value = this.parseAssignmentExpression();
812
- initializer = new Paramter(pattern, value);
817
+ initializer = new Param(pattern, value);
813
818
  }
814
819
  else {
815
- initializer = new Paramter(pattern);
820
+ initializer = new Param(pattern);
816
821
  }
817
822
  return initializer;
818
823
  }
@@ -864,14 +869,14 @@ export class JavaScriptParser extends AbstractParser {
864
869
  const result = this.parsePrimaryExpression();
865
870
  return this.parseMemberExpressionContinuation(result);
866
871
  }
867
- toParamterNode(expression) {
872
+ toParamNode(expression) {
868
873
  if (expression instanceof AssignmentExpression) {
869
- return new Paramter(expression.getLeft(), expression.getRight());
874
+ return new Param(expression.getLeft(), expression.getRight());
870
875
  }
871
876
  if (expression instanceof GroupingExpression) {
872
- return new Paramter(expression.getNode());
877
+ return new Param(expression.getNode());
873
878
  }
874
- return new Paramter(expression);
879
+ return new Param(expression);
875
880
  }
876
881
  parsePrimaryExpression() {
877
882
  let token = this.peek();
@@ -892,10 +897,10 @@ export class JavaScriptParser extends AbstractParser {
892
897
  const name = this.parseAndClassifyIdentifier(token);
893
898
  const params = [];
894
899
  if (name instanceof SequenceExpression) {
895
- params.push(...name.getExpressions().map(this.toParamterNode));
900
+ params.push(...name.getExpressions().map(this.toParamNode));
896
901
  }
897
902
  else {
898
- params.push(this.toParamterNode(name));
903
+ params.push(this.toParamNode(name));
899
904
  }
900
905
  return this.parseArrowFunctionLiteral(params, kind);
901
906
  }
@@ -954,7 +959,12 @@ export class JavaScriptParser extends AbstractParser {
954
959
  }
955
960
  this.expect(Token.R_PARENTHESES);
956
961
  if (this.peek().isType(Token.ARROW)) {
957
- expression = this.parseArrowFunctionLiteral([expression], ArrowFunctionType.NORMAL, info.rest);
962
+ if (expression instanceof SequenceExpression) {
963
+ expression = this.parseArrowFunctionLiteral(expression.getExpressions(), ArrowFunctionType.NORMAL, info.rest);
964
+ }
965
+ else {
966
+ expression = this.parseArrowFunctionLiteral([expression], ArrowFunctionType.NORMAL, info.rest);
967
+ }
958
968
  }
959
969
  return expression;
960
970
  }
@@ -1052,13 +1062,13 @@ export class JavaScriptParser extends AbstractParser {
1052
1062
  throw new Error(this.errorMessage(`Malformed Arrow Fun Param List`));
1053
1063
  }
1054
1064
  if (expression instanceof SequenceExpression) {
1055
- const params = expression.getExpressions().map(expr => new Paramter(expr));
1065
+ const params = expression.getExpressions().map(expr => new Param(expr));
1056
1066
  return this.parseArrowFunctionLiteral(params, ArrowFunctionType.NORMAL);
1057
1067
  }
1058
1068
  if (expression instanceof GroupingExpression) {
1059
- return this.parseArrowFunctionLiteral([new Paramter(expression.getNode())], ArrowFunctionType.NORMAL);
1069
+ return this.parseArrowFunctionLiteral([new Param(expression.getNode())], ArrowFunctionType.NORMAL);
1060
1070
  }
1061
- return this.parseArrowFunctionLiteral([new Paramter(expression)], ArrowFunctionType.NORMAL);
1071
+ return this.parseArrowFunctionLiteral([new Param(expression)], ArrowFunctionType.NORMAL);
1062
1072
  }
1063
1073
  if (this.isAssignableIdentifier(expression)) {
1064
1074
  if (this.isParenthesized(expression)) {
@@ -1112,7 +1122,9 @@ export class JavaScriptParser extends AbstractParser {
1112
1122
  }
1113
1123
  else if (this.check(Token.ELLIPSIS)) {
1114
1124
  const argument = this.parsePossibleDestructuringSubPattern();
1115
- elem = new SpreadElement(argument);
1125
+ elem = isPattern
1126
+ ? new RestElement(argument)
1127
+ : new SpreadElement(argument);
1116
1128
  if (firstSpreadIndex < 0) {
1117
1129
  firstSpreadIndex = values.length;
1118
1130
  }
@@ -1137,7 +1149,7 @@ export class JavaScriptParser extends AbstractParser {
1137
1149
  this.consume(Token.L_CURLY);
1138
1150
  const properties = [];
1139
1151
  while (!this.check(Token.R_CURLY)) {
1140
- const property = this.parseObjectPropertyDefinition();
1152
+ const property = this.parseObjectPropertyDefinition(isPattern);
1141
1153
  properties.push(property);
1142
1154
  if (this.peek().isNotType(Token.R_CURLY)) {
1143
1155
  this.expect(Token.COMMA);
@@ -1148,13 +1160,16 @@ export class JavaScriptParser extends AbstractParser {
1148
1160
  }
1149
1161
  return new ObjectExpression(properties);
1150
1162
  }
1151
- parseObjectPropertyDefinition() {
1163
+ parseObjectPropertyDefinition(isPattern) {
1152
1164
  const propInfo = { kind: PropertyKind.NotSet };
1153
1165
  const nameExpression = this.parseProperty(propInfo);
1154
1166
  switch (propInfo.kind) {
1155
1167
  case PropertyKind.Spread:
1156
- const spared = nameExpression;
1157
- return new Property(spared.getArgument(), spared, 'init');
1168
+ let value = nameExpression;
1169
+ if (isPattern) {
1170
+ value = new RestElement(value.getArgument());
1171
+ }
1172
+ return new Property(value.getArgument(), value, 'init');
1158
1173
  case PropertyKind.Value: {
1159
1174
  this.consume(Token.COLON);
1160
1175
  const value = this.parsePossibleDestructuringSubPattern();
@@ -1235,8 +1250,8 @@ export class JavaScriptParser extends AbstractParser {
1235
1250
  case Token.NUMBER:
1236
1251
  case Token.BIGINT:
1237
1252
  this.consume(nextToken.token);
1238
- propInfo.name = nextToken.getValue().toString();
1239
- propertyName = new StringLiteral(propInfo.name);
1253
+ propertyName = nextToken.getValue();
1254
+ propInfo.name = propertyName.getValue();
1240
1255
  break;
1241
1256
  case Token.L_BRACKETS:
1242
1257
  this.consume(Token.L_BRACKETS);
@@ -1316,54 +1331,112 @@ export class JavaScriptParser extends AbstractParser {
1316
1331
  throw new Error(this.errorMessage(`Parsing property expression: Unexpected Token`));
1317
1332
  }
1318
1333
  parsePipelineExpression(expression) {
1319
- while (this.peek().isType(Token.PIPELINE)) {
1320
- this.consume(Token.PIPELINE);
1321
- const func = this.parseMemberExpression();
1322
- let args = [];
1323
- switch (this.peek().token) {
1324
- case Token.COLON:
1325
- do {
1326
- this.consume(Token.COLON);
1327
- const isSpread = this.check(Token.ELLIPSIS);
1328
- if (this.peek().isType(Token.CONDITIONAL)) {
1329
- this.consume(Token.CONDITIONAL);
1330
- if (isSpread) {
1331
- args.push('...?');
1332
- }
1333
- else {
1334
- args.push('?');
1335
- }
1334
+ let token;
1335
+ while (Token.isPipelineOperator(token = this.peek().token)) {
1336
+ this.consume(token);
1337
+ expression = this.parsePipelineBody(expression);
1338
+ }
1339
+ return expression;
1340
+ }
1341
+ parsePipelineBody(lhs) {
1342
+ let body;
1343
+ let token = this.peek();
1344
+ switch (token.token) {
1345
+ case Token.FUNCTION:
1346
+ this.consume(Token.FUNCTION);
1347
+ if (this.peek().isType(Token.MUL)) {
1348
+ this.consume(Token.MUL);
1349
+ body = this.parseFunctionExpression(FunctionKind.GENERATOR);
1350
+ break;
1351
+ }
1352
+ body = this.parseFunctionExpression(FunctionKind.NORMAL);
1353
+ break;
1354
+ case Token.ASYNC:
1355
+ if (this.peekAhead().isType(Token.FUNCTION)) {
1356
+ this.consume(Token.ASYNC);
1357
+ this.consume(Token.FUNCTION);
1358
+ if (this.peek().isType(Token.MUL)) {
1359
+ this.consume(Token.MUL);
1360
+ body = this.parseFunctionExpression(FunctionKind.ASYNC_GENERATOR);
1361
+ break;
1362
+ }
1363
+ body = this.parseFunctionExpression(FunctionKind.ASYNC);
1364
+ break;
1365
+ }
1366
+ break;
1367
+ default:
1368
+ break;
1369
+ }
1370
+ if (body) {
1371
+ return new PipelineExpression(lhs, body);
1372
+ }
1373
+ if (token.isType(Token.L_PARENTHESES)) {
1374
+ body = this.parsePrimaryExpression();
1375
+ return new PipelineExpression(lhs, body);
1376
+ }
1377
+ const func = this.parseMemberExpression();
1378
+ let args = [];
1379
+ switch (this.peek().token) {
1380
+ case Token.COLON:
1381
+ do {
1382
+ this.consume(Token.COLON);
1383
+ const isSpread = this.check(Token.ELLIPSIS);
1384
+ if (this.peek().isType(Token.CONDITIONAL)) {
1385
+ this.consume(Token.CONDITIONAL);
1386
+ if (isSpread) {
1387
+ args.push('...?');
1336
1388
  }
1337
1389
  else {
1338
- const arg = this.parseLogicalExpression();
1339
- if (isSpread) {
1340
- args.push(new SpreadElement(arg));
1341
- }
1342
- else {
1343
- args.push(arg);
1344
- }
1390
+ args.push('?');
1345
1391
  }
1346
- } while (this.peek().isType(Token.COLON));
1347
- break;
1348
- case Token.L_PARENTHESES:
1349
- this.consume(Token.L_PARENTHESES);
1350
- while (this.peek().isNotType(Token.R_PARENTHESES)) {
1351
- if (this.peek().isType(Token.CONDITIONAL)) {
1352
- this.consume(Token.CONDITIONAL);
1392
+ }
1393
+ else {
1394
+ const arg = this.parseAssignmentExpressionCoverGrammar();
1395
+ if (isSpread) {
1396
+ args.push(new SpreadElement(arg));
1397
+ }
1398
+ else {
1399
+ args.push(arg);
1400
+ }
1401
+ }
1402
+ } while (this.peek().isType(Token.COLON));
1403
+ break;
1404
+ case Token.L_PARENTHESES:
1405
+ this.consume(Token.L_PARENTHESES);
1406
+ let indexed = false;
1407
+ while (this.peek().isNotType(Token.R_PARENTHESES)) {
1408
+ const isSpread = this.check(Token.ELLIPSIS);
1409
+ if (this.peek().isType(Token.CONDITIONAL)) {
1410
+ this.consume(Token.CONDITIONAL);
1411
+ indexed = true;
1412
+ if (isSpread) {
1413
+ args.push('...?');
1414
+ }
1415
+ else {
1353
1416
  args.push('?');
1354
1417
  }
1418
+ }
1419
+ else {
1420
+ const arg = this.parseAssignmentExpressionCoverGrammar();
1421
+ if (isSpread) {
1422
+ args.push(new SpreadElement(arg));
1423
+ }
1355
1424
  else {
1356
- args.push(this.parseLogicalExpression());
1425
+ args.push(arg);
1357
1426
  }
1358
1427
  }
1359
- this.expect(Token.R_PARENTHESES);
1360
- break;
1361
- default:
1362
- break;
1363
- }
1364
- expression = new PipelineExpression(expression, func, args);
1428
+ this.check(Token.COMMA);
1429
+ }
1430
+ this.expect(Token.R_PARENTHESES);
1431
+ if (!indexed) {
1432
+ body = new CallExpression(func, args);
1433
+ return new PipelineExpression(lhs, body);
1434
+ }
1435
+ break;
1436
+ default:
1437
+ break;
1365
1438
  }
1366
- return expression;
1439
+ return new PipelineExpression(lhs, func, args);
1367
1440
  }
1368
1441
  parseConditionalExpression() {
1369
1442
  let expression = this.parseLogicalExpression();
@@ -1502,13 +1575,13 @@ export class JavaScriptParser extends AbstractParser {
1502
1575
  if (Token.isPropertyOrCall(this.peek().token))
1503
1576
  continue;
1504
1577
  const key = this.parsePropertyName();
1505
- result = new ChainExpression(result, key, 'property');
1578
+ result = new MemberExpression(result, key, false, isOptional);
1506
1579
  break;
1507
1580
  }
1508
1581
  case Token.L_BRACKETS: {
1509
1582
  this.consume(Token.L_BRACKETS);
1510
1583
  const index = this.parseExpressionCoverGrammar();
1511
- result = new MemberExpression(result, index, true);
1584
+ result = new MemberExpression(result, index, true, isOptional);
1512
1585
  this.expect(Token.R_BRACKETS);
1513
1586
  break;
1514
1587
  }
@@ -1518,7 +1591,7 @@ export class JavaScriptParser extends AbstractParser {
1518
1591
  }
1519
1592
  this.consume(Token.PERIOD);
1520
1593
  const key = this.parsePropertyName();
1521
- result = new MemberExpression(result, key, false);
1594
+ result = new MemberExpression(result, key, false, isOptional);
1522
1595
  break;
1523
1596
  }
1524
1597
  case Token.L_PARENTHESES: {
@@ -1526,7 +1599,27 @@ export class JavaScriptParser extends AbstractParser {
1526
1599
  if (result.toString() === 'eval') {
1527
1600
  throw new Error(this.errorMessage(`'eval(...)' is not supported.`));
1528
1601
  }
1529
- result = new CallExpression(result, args);
1602
+ result = new CallExpression(result, args, isOptional);
1603
+ break;
1604
+ }
1605
+ case Token.BIND: {
1606
+ if (isOptional) {
1607
+ throw new Error(this.errorMessage(`Unexpected Token:${this.position()}`));
1608
+ }
1609
+ this.consume(Token.BIND);
1610
+ const key = this.parsePropertyName();
1611
+ result = new BindExpression(result, key, false, isOptional);
1612
+ break;
1613
+ }
1614
+ case Token.QUESTION_BIND: {
1615
+ if (isOptional) {
1616
+ throw new Error(this.errorMessage(`Failure Expression`));
1617
+ }
1618
+ this.consume(Token.QUESTION_BIND);
1619
+ isOptional = true;
1620
+ optionalChaining = true;
1621
+ const key = this.parsePropertyName();
1622
+ result = new BindExpression(result, key, true, isOptional);
1530
1623
  break;
1531
1624
  }
1532
1625
  default:
@@ -1540,6 +1633,9 @@ export class JavaScriptParser extends AbstractParser {
1540
1633
  isOptional = false;
1541
1634
  }
1542
1635
  } while (Token.isPropertyOrCall(this.peek().token));
1636
+ if (optionalChaining) {
1637
+ result = new ChainExpression(result);
1638
+ }
1543
1639
  return result;
1544
1640
  }
1545
1641
  parseAwaitExpression() {