This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Implement conditional expressions


This patch adds a significant new feature to the language, conditional
expressions. This is currently under control of -gnatX (extensions
permitted), but is expected to become an official part of the language.

The form of a conditional expression is

 (if expression then expresion
   {elsif expression then expression}
   [else expression])

The enclosing parens can be omitted in the following contexts:

  Attribute arguments
  Pragma positional arguments
  Subprogram positional argumeents
  Argument of type conversion
  Indexing expressions
  Argument of type qualification

If the ELSE expression is omitted, the type of the expression must
be or be derived from Standard.Boolean, and the default value of the
ELSE expression is True (this allows (if A then B) as a convenient
form equivalent to (A implies B) in standard logic.

For now the type resolution works by resolving using the THEN
expression, and the ELSE expresion is forced to be of the same
type, but we expect later to do a full intersection of the
THEN and ELSE types allowing more complex cases to be resolved.

The following test shows successful use of the feature:

with Text_IO; use Text_IO;
procedure Condif is
   procedure p (A : string) is
   begin Put_Line (A); end;

   function F (A : String; B : String) return Boolean is
   begin
      Put_Line (A & "..." & B);
      return True;
   end F;

   B : Boolean;

begin
   for J in 1 .. 3 loop
      Put_Line ((if J = 1 then "one"
                 elsif J = 2 then "two"
                 else "three"));
   end loop;

   for J in Boolean loop
      if (if J then False else True) then
         Put_Line ("One");
      else
         Put_Line ("Two");
      end if;
   end loop;

   for J in Boolean loop
      if (if J then False) then
         Put_Line ("One");
      else
         Put_Line ("Two");
      end if;
   end loop;

   for J in Boolean loop
      B := F (if J then "A" else "B", if not J then "A" else "B");
   end loop;

   for J in Boolean loop
      P (if J then "happy" else "sad");
   end loop;

end Condif;

The output from this test program compiled with -gnatX is:

one
two
three
One
Two
One
Two
B...A
A...B
sad
happy

The following test shows error handling for incorrect usage,
this is compiled with -gnatX

Compiling: condife.adb

     1. procedure Condife (B : Boolean) is
     2.    A : Integer;
     3.    B : Integer := if B then 2 else 3;
                          |
        >>> conditional expression must be parenthesized

     4.    C : Integer :=
                         |
        >>> missing operand

     5.    if B then C := 3; else C := 4; end if;
           |
        >>> statement not allowed in declarative part

     6. begin
     7.    A := if B then 2 else 3;
                |
        >>> conditional expression must be parenthesized

     8.    A :=
               |
        >>> missing operand

     9.    if B then
    10.       C := 2;
    11.    else
    12.       C := 3;
    13.    end if;
    14.    A := (if B then 2 else 3 end if);
                                    |
        >>> "end if" not allowed at end of conditional expression

    15. end Condife;

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

2009-07-07  Robert Dewar  <dewar@adacore.com>

	* scng.adb: Minor reformattting

	* par-ch2.adb (Scan_Pragma_Argument_Association): Pragma argument
	association allows conditional expression without parens.

	* par-ch4.adb (P_Name): Attribute arguments can be conditional
	expressions without enclosing parentheses, and also as parameters,
	indexing expressions etc.
	(P_Conditional_Expression): New procedure
	(P_Expression_If_OK): New procedure

	* par.adb (P_Conditional_Expression): New procedure
	(P_Expression_If_OK): New procedure

	* sem_ch4.adb (Analyze_Conditional_Expression): Allow for two argument
	form of conditional expression.

	* sem_res.adb (Resolve_Conditional_Expression): Deal with supplying
	missing True argument if ELSE argument missing.

	* sinfo.adb (Is_Elsif): New flag

	* sinfo.ads (N_Conditional_Expression): This node is now a syntactic
	part of the language, and the documentation is modified accordingly.
	(Is_Elsif): New flag

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]