protected internal static JintExpression Build(Engine engine, Expression expression) { switch (expression.Type) { case Nodes.AssignmentExpression: return(JintAssignmentExpression.Build(engine, (AssignmentExpression)expression)); case Nodes.ArrayExpression: return(new JintArrayExpression(engine, (ArrayExpression)expression)); case Nodes.ArrowFunctionExpression: return(new JintArrowFunctionExpression(engine, (IFunction)expression)); case Nodes.BinaryExpression: return(JintBinaryExpression.Build(engine, (BinaryExpression)expression)); case Nodes.CallExpression: return(new JintCallExpression(engine, (CallExpression)expression)); case Nodes.ConditionalExpression: return(new JintConditionalExpression(engine, (ConditionalExpression)expression)); case Nodes.FunctionExpression: return(new JintFunctionExpression(engine, (IFunction)expression)); case Nodes.Identifier: return(new JintIdentifierExpression(engine, (Identifier)expression)); case Nodes.Literal: return(JintLiteralExpression.Build(engine, (Literal)expression)); case Nodes.LogicalExpression: switch (((BinaryExpression)expression).Operator) { case BinaryOperator.LogicalAnd: return(new JintLogicalAndExpression(engine, (BinaryExpression)expression)); case BinaryOperator.LogicalOr: return(new JintLogicalOrExpression(engine, (BinaryExpression)expression)); default: return(ExceptionHelper.ThrowArgumentOutOfRangeException <JintExpression>()); } case Nodes.MemberExpression: return(new JintMemberExpression(engine, (MemberExpression)expression)); case Nodes.NewExpression: return(new JintNewExpression(engine, (NewExpression)expression)); case Nodes.ObjectExpression: return(new JintObjectExpression(engine, (ObjectExpression)expression)); case Nodes.SequenceExpression: return(new JintSequenceExpression(engine, (SequenceExpression)expression)); case Nodes.ThisExpression: return(new JintThisExpression(engine, (ThisExpression)expression)); case Nodes.UpdateExpression: return(new JintUpdateExpression(engine, (UpdateExpression)expression)); case Nodes.UnaryExpression: return(JintUnaryExpression.Build(engine, (UnaryExpression)expression)); case Nodes.SpreadElement: return(new JintSpreadExpression(engine, (SpreadElement)expression)); case Nodes.TemplateLiteral: return(new JintTemplateLiteralExpression(engine, (TemplateLiteral)expression)); case Nodes.TaggedTemplateExpression: return(new JintTaggedTemplateExpression(engine, (TaggedTemplateExpression)expression)); default: return(ExceptionHelper.ThrowArgumentOutOfRangeException <JintExpression>(nameof(expression), $"unsupported expression type '{expression.Type}'")); } }
private JsValue UpdateNonIdentifier(EvaluationContext context) { var engine = context.Engine; var reference = _argument.Evaluate(context).Value as Reference; if (reference is null) { ExceptionHelper.ThrowTypeError(engine.Realm, "Invalid left-hand side expression"); } reference.AssertValid(engine.Realm); var value = engine.GetValue(reference, false); var isInteger = value._type == InternalTypes.Integer; JsValue newValue = null; var operatorOverloaded = false; if (context.OperatorOverloadingAllowed) { if (JintUnaryExpression.TryOperatorOverloading(context, _argument.GetValue(context).Value, _change > 0 ? "op_Increment" : "op_Decrement", out var result)) { operatorOverloaded = true; newValue = result; } } if (!operatorOverloaded) { if (isInteger) { newValue = JsNumber.Create(value.AsInteger() + _change); } else if (!value.IsBigInt()) { newValue = JsNumber.Create(TypeConverter.ToNumber(value) + _change); } else { newValue = JsBigInt.Create(TypeConverter.ToBigInt(value) + _change); } } engine.PutValue(reference, newValue); engine._referencePool.Return(reference); if (_prefix) { return(newValue); } else { if (isInteger || operatorOverloaded) { return(value); } if (!value.IsBigInt()) { return(JsNumber.Create(TypeConverter.ToNumber(value))); } return(JsBigInt.Create(value)); } }
private JsValue UpdateIdentifier(EvaluationContext context) { var strict = StrictModeScope.IsStrictModeCode; var name = _leftIdentifier._expressionName; var engine = context.Engine; var env = engine.ExecutionContext.LexicalEnvironment; if (JintEnvironment.TryGetIdentifierEnvironmentWithBindingValue( env, name, strict, out var environmentRecord, out var value)) { if (strict && _evalOrArguments) { ExceptionHelper.ThrowSyntaxError(engine.Realm); } var isInteger = value._type == InternalTypes.Integer; JsValue newValue = null; var operatorOverloaded = false; if (context.OperatorOverloadingAllowed) { if (JintUnaryExpression.TryOperatorOverloading(context, _argument.GetValue(context).Value, _change > 0 ? "op_Increment" : "op_Decrement", out var result)) { operatorOverloaded = true; newValue = result; } } if (!operatorOverloaded) { if (isInteger) { newValue = JsNumber.Create(value.AsInteger() + _change); } else if (value._type != InternalTypes.BigInt) { newValue = JsNumber.Create(TypeConverter.ToNumber(value) + _change); } else { newValue = JsBigInt.Create(TypeConverter.ToBigInt(value) + _change); } } environmentRecord.SetMutableBinding(name.Key.Name, newValue, strict); if (_prefix) { return(newValue); } if (!value.IsBigInt() && !value.IsNumber() && !operatorOverloaded) { return(JsNumber.Create(TypeConverter.ToNumber(value))); } return(value); } return(null); }