Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-16 Thread Richard Biener
On Wed, 15 Jul 2015, Michael Matz wrote:

 Hi,
 
 On Wed, 15 Jul 2015, Richard Biener wrote:
 
(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).

Yes.  Though techincally the condition cannot be an atom because
it has to be a c-expr and that has no notion of atom vs. no-atom.

But the issue is to unambiguously parse the else clause, thus

 (switch
  (integer_zerop (@0)) (plus @1 @2)   --- if - then
  (integer_onep (@0)) (minus @2 @1)   --- if - then
  (minus @3 @2))  --- else

whether or not the then or else clauses are atoms.  The parser
currently cannot backtrack and optimistically parse the next
expression or atom as 'else' and fall back to 'if' (a condition)
if that fails.  The parser has to know upfront by peeking at N
tokens whether the next entry of the switch is a if - then or
the else.

Thus the extra redundant keyword.

Richard.


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-16 Thread Richard Biener
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.


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-16 Thread Michael Matz
Hi,

On Thu, 16 Jul 2015, Richard Biener wrote:

  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).
 
 Yes.  Though techincally the condition cannot be an atom because
 it has to be a c-expr and that has no notion of atom vs. no-atom.

1 is a valid c-expr, and quite atomy :)  (Or true)

 But the issue is to unambiguously parse the else clause, thus

Ah, yes, I remember, the c-expr vs expr case; the parser is too limited :)  
In that case I find the extra keyword without parens even better:

(switch
 when (bla) (foo)
 when (bar) (boo)
 (blob))

I.e. following 'when' it's an c-expr (when single token, parens optional), 
when not following 'when' its a result expr (atomic or not).  Think of it 
as an infix multi-part keyword (like smalltalk has multi-part method 
names), the keyword(s) being switch(when)*.

I'm undecided if I'd allow function calls as atoms as well (because they 
contain parens), like so:

(switch
 when integer_zero(@0) @1
 when integer_zero(@1) @0
 (plus @0 @1))

This would mean that there would be no single-token conditions without 
parens where one could leave out outer parens, as otherwise you have a 
ambiguity between:

(switch
 when true (@0)// (@0) is the result
 ...)

and

(switch
 when token(@0) @1// (@0) belongs to the when-expr
 ...)

One has to chose between one or the other, and I think the latter (i.e. 
function calls as lone when-expr) occur more often.

(Limiting the number of parens is worthwhile IMHO, but you probably 
guessed that much already :))


Ciao,
Michael.


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-15 Thread Richard Sandiford
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.

Thanks,
Richard


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-15 Thread Michael Matz
Hi,

On Tue, 14 Jul 2015, Richard Biener wrote:

 I know Micha detests the extra 'if' as much as the extra braces thus
 would have prefered
 
  (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 
parsable.  But hey, it's your language ;)


Ciao,
Michael.


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-15 Thread Michael Matz
Hi,

On Wed, 15 Jul 2015, Richard Biener wrote:

   (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).


Ciao,
Michael.


Re: [PATCH] Add 'switch' statement to match.pd language

2015-07-15 Thread Richard Biener
On July 15, 2015 4:21:03 PM GMT+02:00, Michael Matz m...@suse.de wrote:
Hi,

On Tue, 14 Jul 2015, Richard Biener wrote:

 I know Micha detests the extra 'if' as much as the extra braces thus
 would have prefered
 
  (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.  Like
(Plus @0 @1) vs. Plain @1.  So you suggest to require ((plus @0 @1)) here to 
make it unambiguous?

parsable.  But hey, it's your language ;)


Ciao,
Michael.