@@ -13738,6 +13738,7 @@ namespace ProviderImplementation.ProvidedTypes
13738
13738
let decimalTypeTgt = convTypeToTgt typeof<decimal>
13739
13739
let convertTypeTgt = convTypeToTgt typeof<System.Convert>
13740
13740
let stringTypeTgt = convTypeToTgt typeof<string>
13741
+ let mathTypeTgt = convTypeToTgt typeof<System.Math>
13741
13742
13742
13743
let makeTypePattern tp =
13743
13744
let tt = convTypeToTgt tp
@@ -13805,6 +13806,50 @@ namespace ProviderImplementation.ProvidedTypes
13805
13806
| _ ->
13806
13807
invalidArg "templateParameter" "The parameter is not a recognized method name"
13807
13808
13809
+ let (|MakeDecimal|_|) =
13810
+ let minfo1 = languagePrimitivesType().GetNestedType("IntrinsicFunctions").GetMethod("MakeDecimal")
13811
+ (fun tm ->
13812
+ match tm with
13813
+ | Call(None, minfo2, args)
13814
+ #if FX_NO_REFLECTION_METADATA_TOKENS
13815
+ when ( // if metadata tokens are not available we'll rely only on equality of method references
13816
+ #else
13817
+ when (minfo1.MetadataToken = minfo2.MetadataToken &&
13818
+ #endif
13819
+ minfo1 = minfo2) ->
13820
+ Some(args)
13821
+ | _ -> None)
13822
+
13823
+ let (|NaN|_|) =
13824
+ let operatorsType = convTypeToTgt (typedefof<list<_>>.Assembly.GetType("Microsoft.FSharp.Core.Operators"))
13825
+ let minfo1 = operatorsType.GetProperty("NaN").GetGetMethod()
13826
+ (fun e ->
13827
+ match e with
13828
+ | Call(None, minfo2, [])
13829
+ #if FX_NO_REFLECTION_METADATA_TOKENS
13830
+ when ( // if metadata tokens are not available we'll rely only on equality of method references
13831
+ #else
13832
+ when (minfo1.MetadataToken = minfo2.MetadataToken &&
13833
+ #endif
13834
+ minfo1 = minfo2) ->
13835
+ Some()
13836
+ | _ -> None)
13837
+
13838
+ let (|NaNSingle|_|) =
13839
+ let operatorsType = convTypeToTgt (typedefof<list<_>>.Assembly.GetType("Microsoft.FSharp.Core.Operators"))
13840
+ let minfo1 = operatorsType.GetProperty("NaNSingle").GetGetMethod()
13841
+ (fun e ->
13842
+ match e with
13843
+ | Call(None, minfo2, [])
13844
+ #if FX_NO_REFLECTION_METADATA_TOKENS
13845
+ when ( // if metadata tokens are not available we'll rely only on equality of method references
13846
+ #else
13847
+ when (minfo1.MetadataToken = minfo2.MetadataToken &&
13848
+ #endif
13849
+ minfo1 = minfo2) ->
13850
+ Some()
13851
+ | _ -> None)
13852
+
13808
13853
let (|LessThan|_|) = (|SpecificCall|_|) <@ (<) @>
13809
13854
let (|GreaterThan|_|) = (|SpecificCall|_|) <@ (>) @>
13810
13855
let (|LessThanOrEqual|_|) = (|SpecificCall|_|) <@ (<=) @>
@@ -13824,6 +13869,10 @@ namespace ProviderImplementation.ProvidedTypes
13824
13869
let (|Or|_|) = (|SpecificCall|_|) <@ (|||) @>
13825
13870
let (|Xor|_|) = (|SpecificCall|_|) <@ (^^^) @>
13826
13871
let (|Not|_|) = (|SpecificCall|_|) <@ (~~~) @>
13872
+ //let (|Compare|_|) = (|SpecificCall|_|) <@ compare @>
13873
+ let (|Max|_|) = (|SpecificCall|_|) <@ max @>
13874
+ let (|Min|_|) = (|SpecificCall|_|) <@ min @>
13875
+ //let (|Hash|_|) = (|SpecificCall|_|) <@ hash @>
13827
13876
let (|CallByte|_|) = (|SpecificCall|_|) <@ byte @>
13828
13877
let (|CallSByte|_|) = (|SpecificCall|_|) <@ sbyte @>
13829
13878
let (|CallUInt16|_|) = (|SpecificCall|_|) <@ uint16 @>
@@ -13844,7 +13893,54 @@ namespace ProviderImplementation.ProvidedTypes
13844
13893
let (|GetArray2D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray2D @>
13845
13894
let (|GetArray3D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray3D @>
13846
13895
let (|GetArray4D|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray4D @>
13847
-
13896
+
13897
+ let (|Abs|_|) = (|SpecificCall|_|) <@ abs @>
13898
+ let (|Acos|_|) = (|SpecificCall|_|) <@ acos @>
13899
+ let (|Asin|_|) = (|SpecificCall|_|) <@ asin @>
13900
+ let (|Atan|_|) = (|SpecificCall|_|) <@ atan @>
13901
+ let (|Atan2|_|) = (|SpecificCall|_|) <@ atan2 @>
13902
+ let (|Ceil|_|) = (|SpecificCall|_|) <@ ceil @>
13903
+ let (|Exp|_|) = (|SpecificCall|_|) <@ exp @>
13904
+ let (|Floor|_|) = (|SpecificCall|_|) <@ floor @>
13905
+ let (|Truncate|_|) = (|SpecificCall|_|) <@ truncate @>
13906
+ let (|Round|_|) = (|SpecificCall|_|) <@ round @>
13907
+ let (|Sign|_|) = (|SpecificCall|_|) <@ sign @>
13908
+ let (|Log|_|) = (|SpecificCall|_|) <@ log @>
13909
+ let (|Log10|_|) = (|SpecificCall|_|) <@ log10 @>
13910
+ let (|Sqrt|_|) = (|SpecificCall|_|) <@ sqrt @>
13911
+ let (|Cos|_|) = (|SpecificCall|_|) <@ cos @>
13912
+ let (|Cosh|_|) = (|SpecificCall|_|) <@ cosh @>
13913
+ let (|Sin|_|) = (|SpecificCall|_|) <@ sin @>
13914
+ let (|Sinh|_|) = (|SpecificCall|_|) <@ sinh @>
13915
+ let (|Tan|_|) = (|SpecificCall|_|) <@ tan @>
13916
+ let (|Tanh|_|) = (|SpecificCall|_|) <@ tanh @>
13917
+ //let (|Range|_|) = (|SpecificCall|_|) <@ (..) @>
13918
+ //let (|RangeStep|_|) = (|SpecificCall|_|) <@ (.. ..) @>
13919
+ let (|Pow|_|) = (|SpecificCall|_|) <@ ( ** ) @>
13920
+ //let (|Pown|_|) = (|SpecificCall|_|) <@ pown @>
13921
+
13922
+ let mathOp t1 name =
13923
+ match t1 with
13924
+ | Double ->
13925
+ let m = mathTypeTgt.GetMethod(name, [|t1|])
13926
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
13927
+ | Single ->
13928
+ ilg.Emit(I_conv DT_R8)
13929
+ let m = mathTypeTgt.GetMethod(name, [|convTypeToTgt typeof<double>|])
13930
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
13931
+ ilg.Emit(I_conv DT_R4)
13932
+ | StaticMethod name [|t1|] m ->
13933
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
13934
+ | _ -> failwithf "%s not supported for type %s" name t1.Name
13935
+
13936
+ let lessThan (a1 : Expr) (a2 : Expr) =
13937
+ match <@@ (<) @@> with
13938
+ | DerivedPatterns.Lambdas(vars,Call(None,meth,_)) ->
13939
+ let targetType = convTypeToTgt meth.DeclaringType
13940
+ let m = targetType.GetMethod(meth.Name, bindAll).MakeGenericMethod(a1.Type)
13941
+ Expr.Call(m, [a1; a2])
13942
+ | _ -> failwith "Unreachable"
13943
+
13848
13944
let isEmpty s = (s = ExpectedStackState.Empty)
13849
13945
let isAddress s = (s = ExpectedStackState.Address)
13850
13946
let rec emitLambda(callSiteIlg: ILGenerator, v: Var, body: Expr, freeVars: seq<Var>, lambdaLocals: Dictionary<_, ILLocalBuilder>, parameters) =
@@ -14009,6 +14105,13 @@ namespace ProviderImplementation.ProvidedTypes
14009
14105
14010
14106
popIfEmptyExpected expectedState
14011
14107
14108
+ | NaN -> emitExpr ExpectedStackState.Value <@@ Double.NaN @@>
14109
+
14110
+ | NaNSingle -> emitExpr ExpectedStackState.Value <@@ Single.NaN @@>
14111
+
14112
+ | MakeDecimal(args) ->
14113
+ emitExpr ExpectedStackState.Value (Expr.NewObjectUnchecked(decimalConstructor(), args))
14114
+
14012
14115
| LessThan(None, [t1], [a1; a2]) ->
14013
14116
emitExpr ExpectedStackState.Value a1
14014
14117
emitExpr ExpectedStackState.Value a2
@@ -14311,7 +14414,83 @@ namespace ProviderImplementation.ProvidedTypes
14311
14414
| StaticMethod "op_Not" [|t1; t1|] m ->
14312
14415
ilg.Emit(I_call(Normalcall, transMeth m, None))
14313
14416
| _ -> failwithf "Operator (~~~) not supported for type %s" t1.Name
14314
-
14417
+
14418
+ | Max(None, [t1], [a1; a2]) ->
14419
+ match t1 with
14420
+ | Double ->
14421
+ emitExpr ExpectedStackState.Value a1
14422
+ emitExpr ExpectedStackState.Value a2
14423
+ let m = mathTypeTgt.GetMethod("Max", [|t1; t1|])
14424
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14425
+ | Single ->
14426
+ emitExpr ExpectedStackState.Value a1
14427
+ emitExpr ExpectedStackState.Value a2
14428
+ ilg.Emit(I_conv DT_R8)
14429
+ let t = convTypeToTgt typeof<double>
14430
+ let m = mathTypeTgt.GetMethod("Max", [|t;t|])
14431
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14432
+ ilg.Emit(I_conv DT_R4)
14433
+ | _ ->
14434
+ match a1,a2 with
14435
+ | (Var _ | Value _), (Var _ | Value _) ->
14436
+ Expr.IfThenElseUnchecked(lessThan a1 a2, a2, a1)
14437
+ |> emitExpr ExpectedStackState.Value
14438
+ | (Var _ | Value _), _ ->
14439
+ let e2 = Var("e2", a2.Type)
14440
+ Expr.Let(e2, a2,
14441
+ Expr.IfThenElseUnchecked(lessThan a1 (Expr.Var e2), Expr.Var e2, a1))
14442
+ |> emitExpr ExpectedStackState.Value
14443
+ | _, (Var _ | Value _) ->
14444
+ let e1 = Var("e1", a1.Type)
14445
+ Expr.Let(e1, a1,
14446
+ Expr.IfThenElseUnchecked((lessThan (Expr.Var e1) a2, a2, (Expr.Var e1))))
14447
+ |> emitExpr ExpectedStackState.Value
14448
+ | _ ->
14449
+ let e1 = Var("e1", a1.Type)
14450
+ let e2 = Var("e2", a2.Type)
14451
+ Expr.Let(e1, a1,
14452
+ Expr.Let(e2, a2,
14453
+ Expr.IfThenElseUnchecked(lessThan (Expr.Var e1) (Expr.Var e2), Expr.Var e2, Expr.Var e1)))
14454
+ |> emitExpr ExpectedStackState.Value
14455
+
14456
+ | Min(None, [t1], [a1; a2]) ->
14457
+ match t1 with
14458
+ | Double ->
14459
+ emitExpr ExpectedStackState.Value a1
14460
+ emitExpr ExpectedStackState.Value a2
14461
+ let m = mathTypeTgt.GetMethod("Min", [|t1; t1|])
14462
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14463
+ | Single ->
14464
+ emitExpr ExpectedStackState.Value a1
14465
+ emitExpr ExpectedStackState.Value a2
14466
+ ilg.Emit(I_conv DT_R8)
14467
+ let t = convTypeToTgt typeof<double>
14468
+ let m = mathTypeTgt.GetMethod("Min", [|t;t|])
14469
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14470
+ ilg.Emit(I_conv DT_R4)
14471
+ | _ ->
14472
+ match a1,a2 with
14473
+ | (Var _ | Value _), (Var _ | Value _) ->
14474
+ Expr.IfThenElseUnchecked(lessThan a1 a2, a1, a2)
14475
+ |> emitExpr ExpectedStackState.Value
14476
+ | (Var _ | Value _), _ ->
14477
+ let e2 = Var("e2", a2.Type)
14478
+ Expr.Let(e2, a2,
14479
+ Expr.IfThenElseUnchecked(lessThan a1 (Expr.Var e2), a1, Expr.Var e2))
14480
+ |> emitExpr ExpectedStackState.Value
14481
+ | _, (Var _ | Value _) ->
14482
+ let e1 = Var("e1", a1.Type)
14483
+ Expr.Let(e1, a1,
14484
+ Expr.IfThenElseUnchecked((lessThan (Expr.Var e1) a2, Expr.Var e1, a2)))
14485
+ |> emitExpr ExpectedStackState.Value
14486
+ | _ ->
14487
+ let e1 = Var("e1", a1.Type)
14488
+ let e2 = Var("e2", a2.Type)
14489
+ Expr.Let(e1, a1,
14490
+ Expr.Let(e2, a2,
14491
+ Expr.IfThenElseUnchecked(lessThan (Expr.Var e1) (Expr.Var e2), Expr.Var e1, Expr.Var e2)))
14492
+ |> emitExpr ExpectedStackState.Value
14493
+
14315
14494
| CallByte(None, [t1], [a1]) ->
14316
14495
emitExpr ExpectedStackState.Value a1
14317
14496
match t1 with
@@ -14552,6 +14731,132 @@ namespace ProviderImplementation.ProvidedTypes
14552
14731
14553
14732
popIfEmptyExpected expectedState
14554
14733
14734
+ | Abs(None, [t1], [a1]) ->
14735
+ emitExpr ExpectedStackState.Value a1
14736
+ match t1 with
14737
+ | Int32 | Double | Single | Int64 | Int16 | SByte | Decimal ->
14738
+ let m = mathTypeTgt.GetMethod("Abs", [|t1|])
14739
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14740
+ | StaticMethod "Abs" [|t1|] m ->
14741
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14742
+ | _ -> failwithf "Abs not supported for type %s" t1.Name
14743
+
14744
+ | Acos(None, [t1], [a1]) ->
14745
+ emitExpr ExpectedStackState.Value a1
14746
+ mathOp t1 "Acos"
14747
+
14748
+ | Asin(None, [t1], [a1]) ->
14749
+ emitExpr ExpectedStackState.Value a1
14750
+ mathOp t1 "Asin"
14751
+
14752
+ | Atan(None, [t1], [a1]) ->
14753
+ emitExpr ExpectedStackState.Value a1
14754
+ mathOp t1 "Atan"
14755
+
14756
+ | Atan2(None, [t1;t2], [a1; a2]) ->
14757
+ emitExpr ExpectedStackState.Value a1
14758
+ emitExpr ExpectedStackState.Value a2
14759
+ match t1 with
14760
+ | Double ->
14761
+ let m = mathTypeTgt.GetMethod("Atan2", [|t1; t1|])
14762
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14763
+ | Single ->
14764
+ ilg.Emit(I_conv DT_R8)
14765
+ let t = convTypeToTgt typeof<double>
14766
+ let m = mathTypeTgt.GetMethod("Atan2", [|t;t|])
14767
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14768
+ ilg.Emit(I_conv DT_R4)
14769
+ | StaticMethod "Atan2" [|t1; t1|] m ->
14770
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14771
+ | _ -> failwithf "Atan2 not supported for type %s" t1.Name
14772
+
14773
+ | Ceil(None, [t1], [a1]) ->
14774
+ emitExpr ExpectedStackState.Value a1
14775
+ mathOp t1 "Ceiling"
14776
+
14777
+ | Exp(None, [t1], [a1]) ->
14778
+ emitExpr ExpectedStackState.Value a1
14779
+ mathOp t1 "Exp"
14780
+
14781
+ | Floor(None, [t1], [a1]) ->
14782
+ emitExpr ExpectedStackState.Value a1
14783
+ mathOp t1 "Floor"
14784
+
14785
+ | Truncate(None, [t1], [a1]) ->
14786
+ emitExpr ExpectedStackState.Value a1
14787
+ mathOp t1 "Truncate"
14788
+
14789
+ | Round(None, [t1], [a1]) ->
14790
+ emitExpr ExpectedStackState.Value a1
14791
+ mathOp t1 "Round"
14792
+
14793
+ | Sign(None, [t1], [a1]) ->
14794
+ emitExpr ExpectedStackState.Value a1
14795
+ match t1 with
14796
+ | Int32 | Double | Single | Int64 | Int16 | SByte | Decimal ->
14797
+ let m = mathTypeTgt.GetMethod("Sign", [|t1|])
14798
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14799
+ | Single ->
14800
+ ilg.Emit(I_conv DT_R8)
14801
+ let m = mathTypeTgt.GetMethod("Sign", [|convTypeToTgt typeof<double>|])
14802
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14803
+ ilg.Emit(I_conv DT_R4)
14804
+ | StaticMethod "Sign" [|t1|] m ->
14805
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14806
+ | _ -> failwithf "Sign not supported for type %s" t1.Name
14807
+
14808
+ | Log(None, [t1], [a1]) ->
14809
+ emitExpr ExpectedStackState.Value a1
14810
+ mathOp t1 "Log"
14811
+
14812
+ | Log10(None, [t1], [a1]) ->
14813
+ emitExpr ExpectedStackState.Value a1
14814
+ mathOp t1 "Log10"
14815
+
14816
+ | Sqrt(None, [t1; t2], [a1]) ->
14817
+ emitExpr ExpectedStackState.Value a1
14818
+ mathOp t1 "Sqrt"
14819
+
14820
+ | Cos(None, [t1], [a1]) ->
14821
+ emitExpr ExpectedStackState.Value a1
14822
+ mathOp t1 "Cos"
14823
+
14824
+ | Cosh(None, [t1], [a1]) ->
14825
+ emitExpr ExpectedStackState.Value a1
14826
+ mathOp t1 "Cosh"
14827
+
14828
+ | Sin(None, [t1], [a1]) ->
14829
+ emitExpr ExpectedStackState.Value a1
14830
+ mathOp t1 "Sin"
14831
+
14832
+ | Sinh(None, [t1], [a1]) ->
14833
+ emitExpr ExpectedStackState.Value a1
14834
+ mathOp t1 "Sinh"
14835
+
14836
+ | Tan(None, [t1], [a1]) ->
14837
+ emitExpr ExpectedStackState.Value a1
14838
+ mathOp t1 "Tan"
14839
+
14840
+ | Tanh(None, [t1], [a1]) ->
14841
+ emitExpr ExpectedStackState.Value a1
14842
+ mathOp t1 "Tanh"
14843
+
14844
+ | Pow(None, [t1; t2], [a1; a2]) ->
14845
+ emitExpr ExpectedStackState.Value a1
14846
+ emitExpr ExpectedStackState.Value a2
14847
+ match t1 with
14848
+ | Double ->
14849
+ let m = mathTypeTgt.GetMethod("Pow", [|t1; t1|])
14850
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14851
+ | Single ->
14852
+ ilg.Emit(I_conv DT_R8)
14853
+ let t = convTypeToTgt typeof<double>
14854
+ let m = mathTypeTgt.GetMethod("Pow", [|t;t|])
14855
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14856
+ ilg.Emit(I_conv DT_R4)
14857
+ | StaticMethod "Pow" [|t1; t2|] m ->
14858
+ ilg.Emit(I_call(Normalcall, transMeth m, None))
14859
+ | _ -> failwithf "Pow not supported for type %s" t1.Name
14555
14860
14556
14861
| FieldGet (None,field) when field.DeclaringType.IsEnum ->
14557
14862
if expectedState <> ExpectedStackState.Empty then
0 commit comments