On Wed, 15 Jul 2015, Richard Sandiford wrote:

> Michael Matz <m...@suse.de> writes:
> >> >>  (switch
> >> >>   (A) B
> >> >>   (B) C
> >> >>   (C) D
> >> >>   E)
> >> >
> >> >The lispy way would have been
> >> >
> >> >   (switch
> >> >    (A) (B)
> >> >    (C) (D)
> >> >    (E) (F)
> >> >    G)
> >> >
> >> >i.e. parenthesize the result as well, which then would be unambiguously
> >> 
> >> That's just atoms vs. Expressions.
> >
> > But if the result is no atom, you'd want parentheses.  Similar if the 
> > condition is no expression but an atom, you'd want to leave out 
> > parentheses as well.  My point is, that both condition and result are at 
> > the same level, and hence should be subject to the same parenthesis rules, 
> > namely: surrounding parens by default, optional for atoms.
> >
> >> Like (Plus @0 @1) vs. Plain @1.  So you suggest to require ((plus @0 
> >> @1)) here to make it unambiguous?
> >
> > No :)  Just look at your example again:
> >
> >  (switch
> >   (A) B
> >  )
> >
> > Both A and B are at the same level, and are both expressions, but still 
> > you parenthesize them differently; that can't be right.  You also don't 
> > write
> >
> >  (switch
> >   ((plus @0 @1))  (@0)
> >  )
> >
> > You write
> >
> >  (switch
> >   (plus @0 @1) (@0)
> >  )
> >
> > And as syntactic sugar you are allowed to leave out the parens around @0 
> > as it's an atom:
> >
> >  (switch
> >   (plus @0 @1) @0
> >  )
> >
> > Similar, if the condition is an atom you should be able to leave the 
> > parens away:
> >
> >  (switch
> >   cond (minus @0 @1)
> >  )
> >
> > (given a predicate 'cond' defined appropriately).
> 
> Agreed FWIW.  The rtx equivalent (unfortunately called "cond",
> so the clash with "cond"==COND_EXPR prevents naming consistency)
> uses the lispy syntax without any ambiguity.

It also puts an extra pair of [] parens around the if-then cases
and leaves a single else case.  It's

 ('cond' [cond1 then1
        cond2 then2
        ...]
  else)

That's of course also possible to mimic with

 (switch
  (
   (integer_zerop (@1)) @0
   (INTEGRAL_TYPE_P (type)) (plus @1 @2)
  )
  (minus @3 @2))

not sure if that is visually easier to parse than the 'if' keyword.
One of the current switch stmts we have is

     (switch
      /* x > +Inf is always false, if with ignore sNANs.  */
      (if (code == GT_EXPR
           && ! HONOR_SNANS (@0))
       { constant_boolean_node (false, type); })
      (if (code == LE_EXPR)
       /* x <= +Inf is always true, if we don't case about NaNs.  */
       (if (! HONOR_NANS (@0))
        { constant_boolean_node (true, type); }
        /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
        (eq @0 @0)))
      /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX.  */
      (if (code == EQ_EXPR || code == GE_EXPR)
       (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
        (if (neg)
         (lt @0 { build_real (TREE_TYPE (@0), max); })
         (gt @0 { build_real (TREE_TYPE (@0), max); }))))
      /* x < +Inf is always equal to x <= DBL_MAX.  */
      (if (code == LT_EXPR)
       (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
        (if (neg)
         (ge @0 { build_real (TREE_TYPE (@0), max); })
         (le @0 { build_real (TREE_TYPE (@0), max); }))))
      /* x != +Inf is always equal to !(x > DBL_MAX).  */
      (if (code == NE_EXPR)
       (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); }
        (if (! HONOR_NANS (@0))
         (if (neg)
          (ge @0 { build_real (TREE_TYPE (@0), max); })
          (le @0 { build_real (TREE_TYPE (@0), max); }))
         (if (neg)
          (bit_xor (lt @0 { build_real (TREE_TYPE (@0), max); })
           { build_one_cst (type); })
          (bit_xor (gt @0 { build_real (TREE_TYPE (@0), max); })
           { build_one_cst (type); }))))))

(this doesn't have an else clause)

Richard.

Reply via email to