[fpc-devel] Fwd: While - Otherwise Statement
MohsenTi
mohsen.timar at gmail.com
Sun Oct 11 18:55:55 CEST 2015
I create 2 test files depends on testsuite readme file and make testsuite
with make full command and set TEST_FPC variable to fpc ppcx64 compiler.
for-otherwise and while-otherwise diff file and test files attached to
email.
test result :
Total = 6906 (75:6831)
Total number of compilations = 4264 (60:4204)
Successfully compiled = 3147
Successfully failed = 1057
Compilation failures = 55
Compilation that did not fail while they should = 5
Total number of runs = 2642 (15:2627)
Successful runs = 2627
Failed runs = 15
Number units compiled = 135
Number program that should not be run = 367
Number of skipped tests = 404
Number of skipped graph tests = 10
Number of skipped interactive tests = 31
Number of skipped known bug tests = 6
Number of skipped tests for other versions = 4
Number of skipped tests for other cpus = 190
Number of skipped tests for other targets = 163
I checked failed ones but it seems they are not related to my changes.
What you think?
thanks a lot
On Sun, Oct 11, 2015 at 6:44 PM, Sven Barth <pascaldragon at googlemail.com>
wrote:
> Am 11.10.2015 15:56 schrieb "MohsenTi" <mohsen.timar at gmail.com>:
> >
> > Hi everybody
> >
> > I add new feature to FPC compiler to simplify programming.
> > this is While - Otherwise working like While - Else in python and has
> backwards compatibility.
>
> Nice idea with the otherwise. I first thought that this would break
> case-statements that use otherwise instead of else, but then I remembered
> that the case-label-blocks can and IMHO should be terminated by ; anyway.
> At least problems can be easily circumvented.
>
> I don't know whether we'll add it to trunk, but I'll at least take a look
> at your code to give you feedback.
>
> Oh, and please provide simple tests for your feature that could be added
> to our testsuite (in tests/test or tests/tbs) in case we decide to
> incorporate it.
> Speaking of which: did you run the testsuite and compared the results to a
> run without modifications?
> (If you need help with running the testsuite or interpreting the results,
> please ask, I have yet to write a wiki page for that...)
>
> Regards,
> Sven
>
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20151011/40c11fae/attachment.html>
-------------- next part --------------
Index: ncgflw.pas
===================================================================
--- ncgflw.pas (revision 32016)
+++ ncgflw.pas (working copy)
@@ -132,7 +132,7 @@
procedure tcgwhilerepeatnode.pass_generate_code;
var
- lcont,lbreak,lloop,
+ lcont,lbreak,lloop,lotherwise,
oldclabel,oldblabel : tasmlabel;
truelabel,falselabel : tasmlabel;
oldflowcontrol : tflowcontrol;
@@ -143,6 +143,7 @@
current_asmdata.getjumplabel(lloop);
current_asmdata.getjumplabel(lcont);
current_asmdata.getjumplabel(lbreak);
+ current_asmdata.getjumplabel(lotherwise);
{ arrange continue and breaklabels: }
oldflowcontrol:=flowcontrol;
oldclabel:=current_procinfo.CurrContinueLabel;
@@ -184,17 +185,21 @@
hlcg.a_label(current_asmdata.CurrAsmList,lcont);
if lnf_checknegate in loopflags then
begin
- truelabel:=lbreak;
+ truelabel:=lotherwise;
falselabel:=lloop;
end
else
begin
truelabel:=lloop;
- falselabel:=lbreak;
+ falselabel:=lotherwise;
end;
secondpass(left);
+ hlcg.maketojumpboollabels(current_asmdata.CurrAsmList,left,truelabel,falselabel);
+ hlcg.a_label(current_asmdata.CurrAsmList,lotherwise);
+ if (Assigned(t1)) then begin
+ secondpass(t1);
+ end;
- hlcg.maketojumpboollabels(current_asmdata.CurrAsmList,left,truelabel,falselabel);
hlcg.a_label(current_asmdata.CurrAsmList,lbreak);
sync_regvars(false);
@@ -413,7 +418,7 @@
procedure tcgfornode.pass_generate_code;
var
- l3,oldclabel,oldblabel : tasmlabel;
+ l3,lotherwise,oldclabel,oldblabel : tasmlabel;
temptovalue : boolean;
hop : topcg;
hcond : topcmp;
@@ -430,7 +435,7 @@
current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
current_asmdata.getjumplabel(current_procinfo.CurrBreakLabel);
current_asmdata.getjumplabel(l3);
-
+ current_asmdata.getjumplabel(lotherwise);
{ only calculate reference }
opsize := def_cgsize(left.resultdef);
count_var_is_signed:=is_signed(left.resultdef);
@@ -794,6 +799,16 @@
tcgint(cmp_const.svalue),left.location,l3);
end;
+ hlcg.a_label(current_asmdata.CurrAsmList,lotherwise);
+
+ if (Assigned(e)) then
+ begin
+ oldexecutionweight:=cg.executionweight;
+ cg.executionweight:=cg.executionweight*8;
+ secondpass(e);
+ cg.executionweight:=oldexecutionweight;
+ end;
+
{ this is the break label: }
hlcg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel);
Index: nflw.pas
===================================================================
--- nflw.pas (revision 32016)
+++ nflw.pas (working copy)
@@ -71,8 +71,11 @@
function docompare(p: tnode): boolean; override;
end;
+ { twhilerepeatnode }
+
twhilerepeatnode = class(tloopnode)
constructor create(l,r:Tnode;tab,cn:boolean);virtual;reintroduce;
+ constructor create(l,r,e:Tnode;tab,cn:boolean);virtual;reintroduce;
function pass_typecheck:tnode;override;
function pass_1 : tnode;override;
{$ifdef state_tracking}
@@ -92,6 +95,8 @@
end;
tifnodeclass = class of tifnode;
+ { tfornode }
+
tfornode = class(tloopnode)
{ if count isn divisable by unrolls then
the for loop must jump to this label to get the correct
@@ -99,8 +104,10 @@
entrylabel,
{ this is a dummy node used by the dfa to store life information for the loop iteration }
loopiteration : tnode;
+ e:TNode;
loopvar_notid:cardinal;
- constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
+ //constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
+ constructor create(l,r,_t1,_t2,_e : tnode;back : boolean);virtual;reintroduce;
function wrap_to_value:tnode;
function pass_typecheck:tnode;override;
function pass_1 : tnode;override;
@@ -258,10 +265,11 @@
function create_type_for_in_loop(hloopvar, hloopbody, expr: tnode): tnode;
begin
+ //Todo: Checking otherwise for for-in
result:=cfornode.create(hloopvar,
cinlinenode.create(in_low_x,false,expr.getcopy),
cinlinenode.create(in_high_x,false,expr.getcopy),
- hloopbody,
+ hloopbody,nil,
false);
end;
@@ -528,10 +536,11 @@
{ add the actual statement to the loop }
addstatement(loopbodystatement,hloopbody);
+ //Todo: Checking otherwise for for-in string
forloopnode:=cfornode.create(ctemprefnode.create(loopvar),
genintconstnode(1),
cinlinenode.create(in_length_x,false,ctemprefnode.create(stringvar)),
- loopbody,
+ loopbody,nil,
false);
addstatement(loopstatement,forloopnode);
@@ -641,11 +650,11 @@
{ add the actual statement to the loop }
addstatement(loopbodystatement,hloopbody);
-
+ //Todo: Checking otherwise for for-in array
forloopnode:=cfornode.create(ctemprefnode.create(loopvar),
lowbound,
highbound,
- loopbody,
+ loopbody,nil,
false);
addstatement(loopstatement,forloopnode);
@@ -706,11 +715,11 @@
addstatement(loopbodystatement,cassignmentnode.create(hloopvar,ctemprefnode.create(loopvar)));
{ add the actual statement to the loop }
addstatement(loopbodystatement,hloopbody);
-
+ //Todo: Checking otherwise for for-in set
forloopnode:=cfornode.create(ctemprefnode.create(loopvar),
cinlinenode.create(in_low_x,false,ctemprefnode.create(setvar)),
cinlinenode.create(in_high_x,false,ctemprefnode.create(setvar)),
- loopbody,
+ loopbody,nil,
false);
addstatement(loopstatement,forloopnode);
@@ -1046,7 +1055,7 @@
TWHILEREPEATNODE
*****************************************************************************}
- constructor Twhilerepeatnode.create(l,r:Tnode;tab,cn:boolean);
+ constructor twhilerepeatnode.create(l, r: Tnode; tab, cn: boolean);
begin
inherited create(whilerepeatn,l,r,nil,nil);
if tab then
@@ -1055,6 +1064,15 @@
include(loopflags,lnf_checknegate);
end;
+ constructor twhilerepeatnode.create(l, r, e: Tnode; tab, cn: boolean);
+ begin
+ inherited create(whilerepeatn,l,r,e,nil);
+ if tab then
+ include(loopflags, lnf_testatbegin);
+ if cn then
+ include(loopflags,lnf_checknegate);
+ end;
+
function twhilerepeatnode.pass_typecheck:tnode;
var
t:Tunarynode;
@@ -1432,14 +1450,24 @@
TFORNODE
*****************************************************************************}
- constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
+ //constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
+ //
+ // begin
+ // inherited create(forn,l,r,_t1,_t2);
+ // if back then
+ // include(loopflags,lnf_backward);
+ // include(loopflags,lnf_testatbegin);
+ // e:=nil;
+ // end;
- begin
- inherited create(forn,l,r,_t1,_t2);
+ constructor tfornode.create(l, r, _t1, _t2, _e: tnode; back: boolean);
+ begin
+ inherited create(forn,l,r,_t1,_t2);
if back then
include(loopflags,lnf_backward);
include(loopflags,lnf_testatbegin);
- end;
+ e:=_e;
+ end;
function tfornode.simplify(forinline : boolean) : tnode;
begin
@@ -1487,8 +1515,8 @@
ctemprefnode.create(temp),
t1));
{ create a new for node, it is cheaper than cloning entire loop body }
- addstatement(statements,cfornode.create(
- left,right,ctemprefnode.create(temp),t2,lnf_backward in loopflags));
+ addstatement(statements,cfornode.create(
+ left,right,ctemprefnode.create(temp),t2,e,lnf_backward in loopflags));
addstatement(statements,ctempdeletenode.create(temp));
{ all child nodes are reused }
left:=nil;
@@ -1495,6 +1523,7 @@
right:=nil;
t1:=nil;
t2:=nil;
+ e:=nil;
end;
@@ -1540,6 +1569,8 @@
if assigned(t2) then
typecheckpass(t2);
+ if Assigned(e) then
+ typecheckpass(e);
end;
@@ -1557,6 +1588,12 @@
if codegenerror then
exit;
+ if (Assigned(e)) then
+ begin
+ firstpass(e);
+ if codegenerror then exit;
+ end;
+
{ 'to' value must be evaluated once before loop, so its possible modifications
inside loop body do not affect the number of iterations (see webtbs/tw8883). }
if not (t1.nodetype in [ordconstn,temprefn]) then
Index: ninl.pas
===================================================================
--- ninl.pas (revision 32016)
+++ ninl.pas (working copy)
@@ -4301,7 +4301,7 @@
ctemprefnode.create(loopvar),
cinlinenode.create(in_low_x,false,packednode.getcopy),
cinlinenode.create(in_high_x,false,packednode.getcopy),
- loopbody,
+ loopbody,nil,
false);
addstatement(loopstatement,tempnode);
{ free the loop counter }
Index: optloop.pas
===================================================================
--- optloop.pas (revision 32016)
+++ optloop.pas (working copy)
@@ -472,7 +472,7 @@
{ create a new for node, the old one will be released by the compiler }
with tfornode(node) do
begin
- fornode:=cfornode.create(left,right,t1,t2,lnf_backward in loopflags);
+ fornode:=cfornode.create(left,right,t1,t2,e,lnf_backward in loopflags);
left:=nil;
right:=nil;
t1:=nil;
Index: optutils.pas
===================================================================
--- optutils.pas (revision 32016)
+++ optutils.pas (working copy)
@@ -205,6 +205,7 @@
tfornode(p).loopiteration:=cnothingnode.create;
DoSet(tfornode(p).t2,tfornode(p).loopiteration);
+
p.successor:=succ;
Breakstack.Delete(Breakstack.Count-1);
Continuestack.Delete(Continuestack.Count-1);
@@ -226,7 +227,7 @@
result:=p;
{ the successor of the last node of the while/repeat body is the while node itself }
DoSet(twhilerepeatnode(p).right,p);
-
+
p.successor:=succ;
{ special case: we do not do a dyn. dfa, but we should handle endless loops }
Index: pstatmnt.pas
===================================================================
--- pstatmnt.pas (revision 32016)
+++ pstatmnt.pas (working copy)
@@ -328,7 +328,7 @@
function while_statement : tnode;
var
- p_e,p_a : tnode;
+ p_e,p_a,else_a : tnode;
begin
consume(_WHILE);
@@ -335,7 +335,11 @@
p_e:=comp_expr(true,false);
consume(_DO);
p_a:=statement;
- result:=cwhilerepeatnode.create(p_e,p_a,true,false);
+ if (try_to_consume(_OTHERWISE)) then
+ else_a := statement
+ else
+ else_a := nil;
+ Result := cwhilerepeatnode.Create(p_e, p_a, else_a, True, False);
end;
{ a helper function which is used both by "with" and "for-in loop" nodes }
@@ -370,6 +374,7 @@
var
hp,
hblock,
+ else_a,
hto,hfrom : tnode;
backward : boolean;
loopvarsym : tabstractvarsym;
@@ -501,7 +506,12 @@
if assigned(loopvarsym) then
exclude(loopvarsym.varoptions,vo_is_loop_counter);
- result:=cfornode.create(hloopvar,hfrom,hto,hblock,backward);
+ if (try_to_consume(_OTHERWISE)) then
+ begin
+ else_a:=statement;
+ end else else_a:=nil;
+
+ result:=cfornode.create(hloopvar,hfrom,hto,hblock,else_a,backward);
end;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: whileotherwise.pp
Type: application/octet-stream
Size: 204 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20151011/40c11fae/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: forotherwise.pp
Type: application/octet-stream
Size: 657 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20151011/40c11fae/attachment-0001.obj>
More information about the fpc-devel
mailing list