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 <[email protected]> wrote: > Am 11.10.2015 15:56 schrieb "MohsenTi" <[email protected]>: > > > > 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 - [email protected] > http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel > >
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;
whileotherwise.pp
Description: Binary data
forotherwise.pp
Description: Binary data
_______________________________________________ fpc-devel maillist - [email protected] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
