diff --git a/extensions/src/libadalang-expr_eval.adb b/extensions/src/libadalang-expr_eval.adb index 51bda0e02..817c9f07e 100644 --- a/extensions/src/libadalang-expr_eval.adb +++ b/extensions/src/libadalang-expr_eval.adb @@ -493,6 +493,48 @@ package body Libadalang.Expr_Eval is return Eval_Range_Attr (D.As_Ordinary_Fixed_Point_Def.F_Range.F_Range.As_Ada_Node, A); + when Ada_Floating_Point_Def => + declare + Def : constant LAL.Floating_Point_Def := + D.As_Floating_Point_Def; + + Rng : constant LAL.Range_Spec := Def.F_Range; + begin + -- If a range has been specified we simply recurse on it, + -- otherwise we need to manually compute its bounds using + -- the `digits` value specified for that type definition. + if Rng.Is_Null then + declare + Digits_Res : constant Eval_Result := + Expr_Eval (Def.F_Num_Digits); + + Digits_Val : constant Integer := + (if Digits_Res.Kind in Int + then To_Integer (Digits_Res.Int_Result) + else raise Property_Error with + "digits must be an integer"); + + Bound : constant Double := + (if Digits_Val > 0 + then (10.0 ** (4 * Digits_Val)) + else raise Property_Error with + "digits must be positive"); + begin + return Result : Eval_Result := + (Kind => Real, + Expr_Type => D.Parent.As_Base_Type_Decl, + Real_Result => <>) + do + Result.Real_Result.Set + (case A is + when Range_First => -Bound, + when Range_Last => Bound); + end return; + end; + else + return Eval_Range_Attr (Rng.F_Range.As_Ada_Node, A); + end if; + end; when others => raise Property_Error with diff --git a/testsuite/tests/ada_api/static_expr_eval/test.adb b/testsuite/tests/ada_api/static_expr_eval/test.adb index 86ab6a371..af454b1d9 100644 --- a/testsuite/tests/ada_api/static_expr_eval/test.adb +++ b/testsuite/tests/ada_api/static_expr_eval/test.adb @@ -203,6 +203,23 @@ begin null; end; + -- Floating point ranges + declare + type T is digits 8 range 0.0 .. 1.0; + type U is digits 2; + + T_First : T := T'First; + T_Last : T := T'Last; + + U_First : U := U'First; + U_Last : U := U'Last; + + Float_First : Float := Float'First; + Float_Last : Float := Float'Last; + begin + null; + end; + -- Invalid decimal fixed point defs declare type T is delta 1 digits 2; diff --git a/testsuite/tests/ada_api/static_expr_eval/test.out b/testsuite/tests/ada_api/static_expr_eval/test.out index cb3934c34..16ed8339a 100644 --- a/testsuite/tests/ada_api/static_expr_eval/test.out +++ b/testsuite/tests/ada_api/static_expr_eval/test.out @@ -242,6 +242,18 @@ Expr evaluated to Real -3/2 Expr evaluated to Real 3/2 +Expr evaluated to Real 0 + +Expr evaluated to Real 1 + +Expr evaluated to Real -100000000 + +Expr evaluated to Real 100000000 + +Expr evaluated to Real -340282346638528859811704183484516925440 + +Expr evaluated to Real 340282346638528859811704183484516925440 + Property_Error: delta must be real Property_Error: digits must be an integer @@ -258,14 +270,14 @@ Property_Error: Unsupported type discrepancy Property_Error: Unsupported type discrepancy -Expr evaluated to Real 7 +Expr evaluated to Real 7 -Expr evaluated to Real 15/2 +Expr evaluated to Real 15/2 -Expr evaluated to Real 7/4 +Expr evaluated to Real 7/4 Property_Error: Unsupported type discrepancy -Expr evaluated to Real 625/16 +Expr evaluated to Real 625/16 Done.