internal override void Bind(Binder binder) { binder.Bookmark(); foreach (Variable variable in TemporaryVariables) { binder.BindVariable(variable); } Left.Bind(binder); Right.Bind(binder); binder.Checkout(); RedwoodType leftType = Left.GetKnownType(); RedwoodType rightType = Right.GetKnownType(); if (SpecialHandling(Operator) || leftType == null || rightType == null) { return; } else if (leftType.CSharpType != null && rightType.CSharpType != null) { // Resolve the static method MemberResolver.TryResolveOperator( null, null, Left.GetKnownType(), Right.GetKnownType(), Operator, out Lambda binaryOperationLambda); if (binaryOperationLambda == null) { throw new NotImplementedException(); } ResolvedOperator = binaryOperationLambda; LambdaType = RedwoodType.GetForLambdaArgsTypes( typeof(ExternalLambda), binaryOperationLambda.ReturnType, binaryOperationLambda.ExpectedArgs.ToArray() ); } else { RedwoodType[] lambdaTypes = new RedwoodType[2]; Lambda[] lambdas = new Lambda[2]; int?[] slots = new int?[2]; int?[] indexes = new int?[2]; // Search both the left and the right types for // static lambdas lambdaTypes[0] = ResolveBinaryOperator( Operator, leftType, rightType, leftType, out lambdas[0], out slots[0], out indexes[0] ); lambdaTypes[1] = ResolveBinaryOperator( Operator, leftType, rightType, rightType, out lambdas[1], out slots[1], out indexes[1] ); if (lambdaTypes[0] == null && lambdaTypes[1] == null) { // There's no compatible operator between the two throw new NotImplementedException(); } else if (lambdaTypes[0] == null) { LambdaType = lambdaTypes[1]; ResolvedOperator = lambdas[1]; ResolvedStaticSlot = slots[1]; ResolvedOverloadIndex = indexes[1]; UsingLeftOperator = false; } else if (lambdaTypes[1] == null) { LambdaType = lambdaTypes[0]; ResolvedOperator = lambdas[0]; ResolvedStaticSlot = slots[0]; ResolvedOverloadIndex = indexes[0]; UsingLeftOperator = true; } else { // TODO: This couldn't return null, could it? RuntimeUtil.TrySelectOverload( new RedwoodType[] { leftType, rightType }, lambdaTypes .Select(lambdaType => lambdaType .GenericArguments .SkipLast(1) .ToArray() ) .ToArray(), out int res ); LambdaType = lambdaTypes[res]; ResolvedOperator = lambdas[res]; ResolvedStaticSlot = slots[res]; ResolvedOverloadIndex = indexes[res]; UsingLeftOperator = res == 0; } } }