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 <pascaldra...@googlemail.com> wrote: > Am 11.10.2015 15:56 schrieb "MohsenTi" <mohsen.ti...@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@lists.freepascal.org > 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 - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel