On 01.02.2016 21:14, Sven Barth wrote:
> Hello together!
> 
> Time for the next flame. I've attached a patch which implements an "if
> Condition then ThenExpr else ElseExpr"-expression for those that want to
> play around with it. It follows the same principles as the
> yet-to-be-renamed IfThen() (namely that the type is determined by the
> ThenExpr) as it's just a different syntax with the same (copy & pasted)
> code behind it...
> 
> Note: this patch *might* also work with 3.0.0 or even 2.6.4...

And I just noticed that I sent this to fpc-devel instead of
fpc-pascal... *sigh*

So here it is again for fpc-pascal as well.

Regards,
Sven

Index: compiler/pexpr.pas
===================================================================
--- compiler/pexpr.pas	(Revision 33036)
+++ compiler/pexpr.pas	(Arbeitskopie)
@@ -3242,6 +3242,77 @@
            result:=not current_procinfo.get_normal_proc.procdef.no_self_node;
          end;
 
+
+         function factor_read_inline_if:tnode;
+           var
+             stat : tstatementnode;
+             tempnode : ttempcreatenode;
+             ifnode,
+             condexpr,
+             thenexpr,
+             elseexpr : tnode;
+             resdef : tdef;
+           begin
+             consume(_IF);
+             condexpr:=comp_expr([ef_accept_equal]);
+             consume(_THEN);
+             thenexpr:=comp_expr([ef_accept_equal]);
+             consume(_ELSE);
+             elseexpr:=comp_expr([ef_accept_equal]);
+
+             typecheckpass(condexpr);
+             typecheckpass(thenexpr);
+             typecheckpass(elseexpr);
+
+             if (condexpr.nodetype=errorn) or
+                 (thenexpr.nodetype=errorn) or
+                 (elseexpr.nodetype=errorn) then
+               result:=cerrornode.create;
+
+             { The result type of the expression is that of the then-expression; the
+               else-expression is converted to that if possible (otherwise error)
+               There are a few special cases however:
+               - constant strings need to be converted to strings
+               - chars need to be checked with strings
+             }
+
+             if is_conststringnode(thenexpr) then
+               begin
+                 if is_constwidestringnode(elseexpr) or is_constwidecharnode(elseexpr) then
+                   resdef:=cwidestringtype
+                 else
+                   resdef:=cansistringtype;
+               end
+             else if is_constcharnode(thenexpr) then
+               begin
+                 if is_constcharnode(elseexpr) then
+                   resdef:=cansichartype
+                 else if is_constwidecharnode(elseexpr) then
+                   resdef:=cwidechartype
+                 else if is_string(elseexpr.resultdef) then
+                   resdef:=elseexpr.resultdef
+                 else
+                   resdef:=thenexpr.resultdef;
+               end
+             else
+               resdef:=thenexpr.resultdef;
+
+             result:=internalstatements(stat);
+
+             { create the tempnode that will hold our result }
+             tempnode:=ctempcreatenode.create(resdef,resdef.size,tt_persistent,true);
+             addstatement(stat,tempnode);
+
+             ifnode:=cifnode.create(condexpr,
+                                cassignmentnode.create(ctemprefnode.create(tempnode),thenexpr),
+                                cassignmentnode.create(ctemprefnode.create(tempnode),elseexpr)
+                              );
+             addstatement(stat,ifnode);
+
+             addstatement(stat,ctempdeletenode.create_normal_temp(tempnode));
+             addstatement(stat,ctemprefnode.create(tempnode));
+           end;
+
       {---------------------------------------------
                       Factor (Main)
       ---------------------------------------------}
@@ -3779,6 +3850,10 @@
                consume(_RKLAMMER);
                p1:=cinlinenode.create(in_objc_protocol_x,false,p1);
              end;
+           _IF:
+             begin
+               p1:=factor_read_inline_if;
+             end;
 
              else
                begin
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to