Patchwork [Ada] Improvements to sprint for conditional expressions

login
register
mail settings
Submitter Arnaud Charlet
Date Jan. 2, 2013, 10:38 a.m.
Message ID <20130102103839.GA20009@adacore.com>
Download mbox | patch
Permalink /patch/208988/
State New
Headers show

Comments

Arnaud Charlet - Jan. 2, 2013, 10:38 a.m.
This change improves the circuitry that produces a source-like rendition
for an Ada tree by omitting the generation of extraneous parentheses around
conditional expressions, and removing an extraneous ELSE keyword.

The following compilation must produce the indicated output:
$ gcc -c -gnat12 -gnatG condexpr_sprint.adb
Source recreated from tree for Condexpr_Sprint (body)


procedure condexpr_sprint (b : boolean; i : integer) is
   type r is record
      bb : boolean := (if b then b);
      ii : integer := (case i is when 1 => 1, when others => 2);
   end record;
begin
   null;
end condexpr_sprint;

condexpr_sprint.adb:2:04: declaration expected

procedure Condexpr_Sprint (B : Boolean; I : Integer) is
   zz --  Purposely introduce a serious error here to prevent further analysis

   type R is record
      BB : Boolean := (if B then B);
      II : Integer := (case I is when 1 => 1, when others => 2);
   end record;
begin
   null;
end Condexpr_Sprint;

Tested on x86_64-pc-linux-gnu, committed on trunk

2013-01-02  Thomas Quinot  <quinot@adacore.com>

	* sprint.adb (Sprint_Node_Actual): Do not add extra parens for
	a conditional expression (CASE or IF expression) that already
	has parens. Also omit ELSE keyword for an IF expression without
	an ELSE part.

Patch

Index: sprint.adb
===================================================================
--- sprint.adb	(revision 194776)
+++ sprint.adb	(working copy)
@@ -1159,14 +1159,19 @@ 
 
          when N_Case_Expression =>
             declare
-               Alt : Node_Id;
+               Has_Parens : constant Boolean := Paren_Count (Node) > 0;
+               Alt        : Node_Id;
 
             begin
                --  The syntax for case_expression does not include parentheses,
                --  but sometimes parentheses are required, so unconditionally
-               --  generate them here.
+               --  generate them here unless already present.
 
-               Write_Str_With_Col_Check_Sloc ("(case ");
+               if not Has_Parens then
+                  Write_Char ('(');
+               end if;
+
+               Write_Str_With_Col_Check_Sloc ("case ");
                Sprint_Node (Expression (Node));
                Write_Str_With_Col_Check (" is");
 
@@ -1178,7 +1183,9 @@ 
                   Write_Char (',');
                end loop;
 
-               Write_Char (')');
+               if not Has_Parens then
+                  Write_Char (')');
+               end if;
             end;
 
          when N_Case_Expression_Alternative =>
@@ -1963,15 +1970,19 @@ 
 
          when N_If_Expression =>
             declare
-               Condition : constant Node_Id := First (Expressions (Node));
-               Then_Expr : constant Node_Id := Next (Condition);
+               Has_Parens : constant Boolean := Paren_Count (Node) > 0;
+               Condition  : constant Node_Id := First (Expressions (Node));
+               Then_Expr  : constant Node_Id := Next (Condition);
 
             begin
                --  The syntax for if_expression does not include parentheses,
                --  but sometimes parentheses are required, so unconditionally
-               --  generate them here.
+               --  generate them here unless already present.
 
-               Write_Str_With_Col_Check_Sloc ("(if ");
+               if not Has_Parens then
+                  Write_Char ('(');
+               end if;
+               Write_Str_With_Col_Check_Sloc ("if ");
                Sprint_Node (Condition);
                Write_Str_With_Col_Check (" then ");
 
@@ -1979,11 +1990,16 @@ 
 
                if Present (Then_Expr) then
                   Sprint_Node (Then_Expr);
-                  Write_Str_With_Col_Check (" else ");
-                  Sprint_Node (Next (Then_Expr));
+
+                  if Present (Next (Then_Expr)) then
+                     Write_Str_With_Col_Check (" else ");
+                     Sprint_Node (Next (Then_Expr));
+                  end if;
                end if;
 
-               Write_Char (')');
+               if not Has_Parens then
+                  Write_Char (')');
+               end if;
             end;
 
          when N_If_Statement =>