[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mono-devel-list
Subject:    Re: [Mono-dev] Question about LiftedBinaryOperator in mcs source
From:       Marek Safar <marek.safar () gmail ! com>
Date:       2013-01-31 18:07:40
Message-ID: CAB=RytWxZVOR3e-SwCmNXuhF4c14d1VeJ0m71sXvK0fxgxEvwQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi,

I'm working on project that uses Mono as its C# parser. It uses the AST
> that comes from calling "Resolve".
>
> I'm having trouble understanding what happens to LiftedBinaryOperator.
>
> In particular, this code seems strange:
>
>             if (left_orig is NullLiteral) {
>                 left = right;
>
> One of the effects of this assignment is that, if a user operator is
> involved, the corresponding UserOperatorCall will have "right" as both of
> its arguments.
> If I replace the assignment with, say:
>                 left = LiftedNull.Create (right.Type, left.Location);
> I get parse errors.
> It seems that at least one of the goals is to trigger a check for "left !=
> right".
>

This is kind of trick to simplify handling of comparisons which always end
up with constant result but are allowed by the language.

For example

bool b = false;
var x = null != b;

If you found a case where this breaks valid C# code, please fill a bug
report with C# example.


>
> Another mysterious thing I noticed is that, in the AST for code like:
> int i;
> int ?oi;
>
> i + oi;
>
> the AST is a LiftedBinaryOperator where "right" is an Unwrap with type int
> (this part I understand), while "left" is an EmptyCast with type "int?",
> which I find mysterious. It looks like the "EmitOperator" call casts it
> back to its original type:
>             if (left.Type.IsNullableType) {
>                 l = NullableInfo.GetUnderlyingType (left.Type);
>                 left = EmptyCast.Create (left, l);
>             }
>
>
Correct, that's just another wrap so we can use same emit operator routine.


> It would be great if you could explains how all this works.
>

All nullable handling is tricky especially cases involving user operators
mainly because C# spec is light on details about nullable handling and does
not match csc implementation quite few cases.

Sorry for late reply I somehow missed your email.

Marek

[Attachment #5 (text/html)]

<div dir="ltr">Hi,<div class="gmail_extra"><br><div class="gmail_quote"><blockquote \
class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">



I&#39;m working on project that uses Mono as its C# parser. It uses the AST that \
comes from calling &quot;Resolve&quot;.<br> <br>
I&#39;m having trouble understanding what happens to LiftedBinaryOperator.<br>
<br>
In particular, this code seems strange:<br>
<br>
            if (left_orig is NullLiteral) {<br>
                left = right;<br>
<br>
One of the effects of this assignment is that, if a user operator is involved, the \
corresponding UserOperatorCall will have &quot;right&quot; as both of its \
arguments.<br> If I replace the assignment with, say:<br>
                left = LiftedNull.Create (right.Type, left.Location);<br>
I get parse errors.<br>
It seems that at least one of the goals is to trigger a check for &quot;left != \
right&quot;.<br></blockquote><div><br></div><div>This is kind of trick to simplify \
handling of comparisons which always end up with constant result but are allowed by \
the language.</div>

<div><br></div><div>For example</div><div><br></div><div><div><span \
style="white-space:pre-wrap">		</span>bool b = false;</div><div><span \
style="white-space:pre-wrap">		</span>var x = null != b;</div> \
<div><br></div></div><div>If you found a case where this breaks valid C# code, please \
fill a bug report with C# example.</div><div> </div><blockquote class="gmail_quote" \
style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">



<br>
Another mysterious thing I noticed is that, in the AST for code like:<br>
int i;<br>
int ?oi;<br>
<br>
i + oi;<br>
<br>
the AST is a LiftedBinaryOperator where &quot;right&quot; is an Unwrap with type int \
(this part I understand), while &quot;left&quot; is an EmptyCast with type \
&quot;int?&quot;, which I find mysterious. It looks like the &quot;EmitOperator&quot; \
call casts it back to its original type:<br>


            if (left.Type.IsNullableType) {<br>
                l = NullableInfo.GetUnderlyingType (left.Type);<br>
                left = EmptyCast.Create (left, l);<br>
            }<br>
<br></blockquote><div><br></div><div style>Correct, that&#39;s just another wrap so \
we can use same emit operator routine.</div><div> </div><blockquote \
class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


It would be great if you could explains how all this \
works.<br></blockquote><div><br></div><div style>All nullable handling is tricky \
especially cases involving user operators mainly because C# spec is light on details \
about nullable handling and does not match csc implementation quite few cases.</div> \
<div style><br></div><div style>Sorry for late reply I somehow missed your \
email.</div><div style><br></div><div style>Marek</div></div></div></div>



_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic