3220 return referenceError(lhs, null, false);
3221 }
3222 verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
3223 }
3224 expression = incDecExpression(token, type, expression, true);
3225 next();
3226 break;
3227 default:
3228 break;
3229 }
3230 }
3231
3232 if (expression == null) {
3233 throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
3234 }
3235
3236 return expression;
3237 }
3238
3239 /**
3240 * MultiplicativeExpression :
3241 * UnaryExpression
3242 * MultiplicativeExpression * UnaryExpression
3243 * MultiplicativeExpression / UnaryExpression
3244 * MultiplicativeExpression % UnaryExpression
3245 *
3246 * See 11.5
3247 *
3248 * AdditiveExpression :
3249 * MultiplicativeExpression
3250 * AdditiveExpression + MultiplicativeExpression
3251 * AdditiveExpression - MultiplicativeExpression
3252 *
3253 * See 11.6
3254 *
3255 * ShiftExpression :
3256 * AdditiveExpression
3257 * ShiftExpression << AdditiveExpression
3258 * ShiftExpression >> AdditiveExpression
3259 * ShiftExpression >>> AdditiveExpression
3306 * ConditionalExpression :
3307 * LogicalORExpression
3308 * LogicalORExpression ? AssignmentExpression : AssignmentExpression
3309 *
3310 * See 11.12
3311 *
3312 * AssignmentExpression :
3313 * ConditionalExpression
3314 * LeftHandSideExpression AssignmentOperator AssignmentExpression
3315 *
3316 * AssignmentOperator :
3317 * = *= /= %= += -= <<= >>= >>>= &= ^= |=
3318 *
3319 * See 11.13
3320 *
3321 * Expression :
3322 * AssignmentExpression
3323 * Expression , AssignmentExpression
3324 *
3325 * See 11.14
3326 *
3327 * Parse expression.
3328 * @return Expression node.
3329 */
3330 private Expression expression() {
3331 // TODO - Destructuring array.
3332 // Include commas in expression parsing.
3333 return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
3334 }
3335
3336 private JoinPredecessorExpression joinPredecessorExpression() {
3337 return new JoinPredecessorExpression(expression());
3338 }
3339
3340 private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
3341 // Get the precedence of the next operator.
3342 int precedence = type.getPrecedence();
3343 Expression lhs = exprLhs;
3344
3345 // While greater precedence.
3346 while (type.isOperator(noIn) && precedence >= minPrecedence) {
3347 // Capture the operator token.
3348 final long op = token;
3349
3350 if (type == TERNARY) {
3351 // Skip operator.
3352 next();
3353
3354 // Pass expression. Middle expression of a conditional expression can be a "in"
3355 // expression - even in the contexts where "in" is not permitted.
3356 final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
3357
3358 expect(COLON);
3359
3360 // Fail expression.
3381 while (type.isOperator(noIn) &&
3382 (nextPrecedence > precedence ||
3383 nextPrecedence == precedence && !type.isLeftAssociative())) {
3384 rhs = expression(rhs, nextPrecedence, noIn);
3385 nextPrecedence = type.getPrecedence();
3386 }
3387 } finally {
3388 if(isAssign) {
3389 defaultNames.pop();
3390 }
3391 }
3392 lhs = verifyAssignment(op, lhs, rhs);
3393 }
3394
3395 precedence = type.getPrecedence();
3396 }
3397
3398 return lhs;
3399 }
3400
3401 private Expression assignmentExpression(final boolean noIn) {
3402 // TODO - Handle decompose.
3403 // Exclude commas in expression parsing.
3404 return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
3405 }
3406
3407 /**
3408 * Parse an end of line.
3409 */
3410 private void endOfLine() {
3411 switch (type) {
3412 case SEMICOLON:
3413 case EOL:
3414 next();
3415 break;
3416 case RPAREN:
3417 case RBRACKET:
3418 case RBRACE:
3419 case EOF:
3420 break;
3421 default:
|
3220 return referenceError(lhs, null, false);
3221 }
3222 verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
3223 }
3224 expression = incDecExpression(token, type, expression, true);
3225 next();
3226 break;
3227 default:
3228 break;
3229 }
3230 }
3231
3232 if (expression == null) {
3233 throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
3234 }
3235
3236 return expression;
3237 }
3238
3239 /**
3240 * {@code
3241 * MultiplicativeExpression :
3242 * UnaryExpression
3243 * MultiplicativeExpression * UnaryExpression
3244 * MultiplicativeExpression / UnaryExpression
3245 * MultiplicativeExpression % UnaryExpression
3246 *
3247 * See 11.5
3248 *
3249 * AdditiveExpression :
3250 * MultiplicativeExpression
3251 * AdditiveExpression + MultiplicativeExpression
3252 * AdditiveExpression - MultiplicativeExpression
3253 *
3254 * See 11.6
3255 *
3256 * ShiftExpression :
3257 * AdditiveExpression
3258 * ShiftExpression << AdditiveExpression
3259 * ShiftExpression >> AdditiveExpression
3260 * ShiftExpression >>> AdditiveExpression
3307 * ConditionalExpression :
3308 * LogicalORExpression
3309 * LogicalORExpression ? AssignmentExpression : AssignmentExpression
3310 *
3311 * See 11.12
3312 *
3313 * AssignmentExpression :
3314 * ConditionalExpression
3315 * LeftHandSideExpression AssignmentOperator AssignmentExpression
3316 *
3317 * AssignmentOperator :
3318 * = *= /= %= += -= <<= >>= >>>= &= ^= |=
3319 *
3320 * See 11.13
3321 *
3322 * Expression :
3323 * AssignmentExpression
3324 * Expression , AssignmentExpression
3325 *
3326 * See 11.14
3327 * }
3328 *
3329 * Parse expression.
3330 * @return Expression node.
3331 */
3332 protected Expression expression() {
3333 // This method is protected so that subclass can get details
3334 // at expression start point!
3335
3336 // TODO - Destructuring array.
3337 // Include commas in expression parsing.
3338 return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
3339 }
3340
3341 private JoinPredecessorExpression joinPredecessorExpression() {
3342 return new JoinPredecessorExpression(expression());
3343 }
3344
3345 protected Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
3346 // Get the precedence of the next operator.
3347 int precedence = type.getPrecedence();
3348 Expression lhs = exprLhs;
3349
3350 // While greater precedence.
3351 while (type.isOperator(noIn) && precedence >= minPrecedence) {
3352 // Capture the operator token.
3353 final long op = token;
3354
3355 if (type == TERNARY) {
3356 // Skip operator.
3357 next();
3358
3359 // Pass expression. Middle expression of a conditional expression can be a "in"
3360 // expression - even in the contexts where "in" is not permitted.
3361 final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
3362
3363 expect(COLON);
3364
3365 // Fail expression.
3386 while (type.isOperator(noIn) &&
3387 (nextPrecedence > precedence ||
3388 nextPrecedence == precedence && !type.isLeftAssociative())) {
3389 rhs = expression(rhs, nextPrecedence, noIn);
3390 nextPrecedence = type.getPrecedence();
3391 }
3392 } finally {
3393 if(isAssign) {
3394 defaultNames.pop();
3395 }
3396 }
3397 lhs = verifyAssignment(op, lhs, rhs);
3398 }
3399
3400 precedence = type.getPrecedence();
3401 }
3402
3403 return lhs;
3404 }
3405
3406 protected Expression assignmentExpression(final boolean noIn) {
3407 // This method is protected so that subclass can get details
3408 // at assignment expression start point!
3409
3410 // TODO - Handle decompose.
3411 // Exclude commas in expression parsing.
3412 return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
3413 }
3414
3415 /**
3416 * Parse an end of line.
3417 */
3418 private void endOfLine() {
3419 switch (type) {
3420 case SEMICOLON:
3421 case EOL:
3422 next();
3423 break;
3424 case RPAREN:
3425 case RBRACKET:
3426 case RBRACE:
3427 case EOF:
3428 break;
3429 default:
|