public JsValue EvaluateBinaryExpression(BinaryExpression expression) { JsValue left = _engine.GetValue(EvaluateExpression(expression.Left)); JsValue right = _engine.GetValue(EvaluateExpression(expression.Right)); JsValue value; switch (expression.Operator) { case BinaryOperator.Plus: var lprim = TypeConverter.ToPrimitive(left); var rprim = TypeConverter.ToPrimitive(right); if (lprim.IsString() || rprim.IsString()) { value = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim); } else { value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim); } break; case BinaryOperator.Minus: value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right); break; case BinaryOperator.Times: if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right); } break; case BinaryOperator.Divide: value = Divide(left, right); break; case BinaryOperator.Modulo: if (left == Undefined.Instance || right == Undefined.Instance) { value = Undefined.Instance; } else { value = TypeConverter.ToNumber(left) % TypeConverter.ToNumber(right); } break; case BinaryOperator.Equal: value = Equal(left, right); break; case BinaryOperator.NotEqual: value = !Equal(left, right); break; case BinaryOperator.Greater: value = Compare(right, left, false); if (value == Undefined.Instance) { value = false; } break; case BinaryOperator.GreaterOrEqual: value = Compare(left, right); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case BinaryOperator.Less: value = Compare(left, right); if (value == Undefined.Instance) { value = false; } break; case BinaryOperator.LessOrEqual: value = Compare(right, left, false); if (value == Undefined.Instance || value.AsBoolean()) { value = false; } else { value = true; } break; case BinaryOperator.StrictlyEqual: return StrictlyEqual(left, right); case BinaryOperator.StricltyNotEqual: return !StrictlyEqual(left, right); case BinaryOperator.BitwiseAnd: return TypeConverter.ToInt32(left) & TypeConverter.ToInt32(right); case BinaryOperator.BitwiseOr: return TypeConverter.ToInt32(left) | TypeConverter.ToInt32(right); case BinaryOperator.BitwiseXOr: return TypeConverter.ToInt32(left) ^ TypeConverter.ToInt32(right); case BinaryOperator.LeftShift: return TypeConverter.ToInt32(left) << (int)(TypeConverter.ToUint32(right) & 0x1F); case BinaryOperator.RightShift: return TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F); case BinaryOperator.UnsignedRightShift: return (uint)TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F); case BinaryOperator.InstanceOf: var f = right.TryCast<FunctionInstance>(); if (f == null) { throw new JavaScriptException(_engine.TypeError, "instanceof can only be used with a function object"); } value = f.HasInstance(left); break; case BinaryOperator.In: if (!right.IsObject()) { throw new JavaScriptException(_engine.TypeError, "in can only be used with an object"); } value = right.AsObject().HasProperty(TypeConverter.ToString(left)); break; default: throw new NotImplementedException(); } return value; }
public ExpressionContext(JScriptBuilder builder, BinaryExpression e) : this(builder) { _op = OperatorInfo.GetBinary(e.Operator); Enter(); }
private void EmitBinaryExpression(BinaryExpression e) { using (var ec = new ExpressionContext(this, e)) { Emit(e.Left); Write(" " + ec.Token + " "); Emit(e.Right); } }