On 3/30/15 11:34 PM, deadalnix wrote:
On Tuesday, 31 March 2015 at 06:20:22 UTC, Andrei Alexandrescu wrote:
On 3/30/15 8:49 PM, deadalnix wrote:
On Tuesday, 31 March 2015 at 01:01:24 UTC, Andrei Alexandrescu wrote:
On 3/30/15 5:49 PM, deadalnix wrote:
Why are you doing the replacement top/down rather than bottom up ?

What would be the alternative? -- Andrei

Doing the replacement bottom up :

a = a++;

a += { auto olda = a; a = a + 1; return olda; }();

a = cast(typeof(a)) (a + { auto olda = a; a = a + 1; return olda; }());

You need another lowering here because you evaluate a twice. Consider:

import std.stdio;
int a;
ref int fun() { writeln("meh"); return a; }
void main() {
  fun() = i++;
}


Yeah, I had an int in mind. Make it

{
     aPtr = &a;
     *aPtr = cast(typeof(a)) (*aPtr + { auto olda = *aPtr; *aPtr = a +
1; return olda; }());
     return *aPtr;
}()

So you propose the following lowering for e1 += e2:

e1 += e2

-\>

{
    auto __p = &(e1);
    *__p = cast(typeof(e1)) (*__p + e2);
}()

This looks contrived and it's no surprise is inconsistent with opOpAssign as you yourself noted. I prefer the lowering that identifies += to a function calls with two parameters:

e1 += e2

-\>

(ref a, b) { a = (cast(typeof(a)) (a + b); }(e1, e2)

Other code transformation do not require a function call to take place,
so why would this require one (which force eager evaluation of
parameters) ?

Everything needs to be evaluated (and only once).

That is also inconsistent with LTR evaluation.

I don't see how.


a appear on the left of a++. a should be evaluated before a++. You
propose that it isn't.

I see, thanks.

Guess we should change the spec no matter what. My money is on the lowering I mentioned.


Andrei

Reply via email to