mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 22:49:23 +02:00
* for-node cleanup, checking for uninitialzed from and to values
is now supported
This commit is contained in:
parent
be1808953c
commit
cc2789b680
@ -329,7 +329,6 @@ implementation
|
|||||||
var
|
var
|
||||||
l3,oldclabel,oldblabel : tasmlabel;
|
l3,oldclabel,oldblabel : tasmlabel;
|
||||||
temptovalue : boolean;
|
temptovalue : boolean;
|
||||||
hs : byte;
|
|
||||||
temp1 : treference;
|
temp1 : treference;
|
||||||
hop : topcg;
|
hop : topcg;
|
||||||
hcond : topcmp;
|
hcond : topcmp;
|
||||||
@ -348,31 +347,40 @@ implementation
|
|||||||
objectlibrary.getlabel(l3);
|
objectlibrary.getlabel(l3);
|
||||||
|
|
||||||
{ only calculate reference }
|
{ only calculate reference }
|
||||||
secondpass(t2);
|
opsize := def_cgsize(left.resulttype.def);
|
||||||
hs := t2.resulttype.def.size;
|
count_var_is_signed:=is_signed(left.resulttype.def);
|
||||||
opsize := def_cgsize(t2.resulttype.def);
|
|
||||||
|
|
||||||
{ first set the to value
|
{ first set the to value
|
||||||
because the count var can be in the expression !! }
|
because the count var can be in the expression !! }
|
||||||
do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
|
do_loopvar_at_end:=lnf_dont_mind_loopvar_on_exit in loopflags;
|
||||||
|
|
||||||
secondpass(right);
|
secondpass(t1);
|
||||||
{ calculate pointer value and check if changeable and if so }
|
{ calculate pointer value and check if changeable and if so }
|
||||||
{ load into temporary variable }
|
{ load into temporary variable }
|
||||||
if right.nodetype<>ordconstn then
|
if t1.nodetype<>ordconstn then
|
||||||
begin
|
begin
|
||||||
do_loopvar_at_end:=false;
|
do_loopvar_at_end:=false;
|
||||||
tg.GetTemp(exprasmlist,hs,tt_normal,temp1);
|
tg.GetTemp(exprasmlist,t1.resulttype.def.size,tt_normal,temp1);
|
||||||
temptovalue:=true;
|
temptovalue:=true;
|
||||||
cg.a_load_loc_ref(exprasmlist,opsize,right.location,temp1);
|
cg.a_load_loc_ref(exprasmlist,opsize,t1.location,temp1);
|
||||||
location_freetemp(exprasmlist,right.location);
|
location_freetemp(exprasmlist,t1.location);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
temptovalue:=false;
|
temptovalue:=false;
|
||||||
|
|
||||||
{ produce start assignment }
|
{ produce start assignment }
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
count_var_is_signed:=is_signed(t2.resulttype.def);
|
secondpass(right);
|
||||||
|
case left.location.loc of
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE :
|
||||||
|
cg.a_load_loc_ref(exprasmlist,left.location.size,right.location,left.location.reference);
|
||||||
|
LOC_REGISTER,
|
||||||
|
LOC_CREGISTER :
|
||||||
|
cg.a_load_loc_reg(exprasmlist,left.location.size,right.location,left.location.register);
|
||||||
|
else
|
||||||
|
internalerror(200501311);
|
||||||
|
end;
|
||||||
|
|
||||||
if lnf_backward in loopflags then
|
if lnf_backward in loopflags then
|
||||||
if count_var_is_signed then
|
if count_var_is_signed then
|
||||||
@ -392,15 +400,15 @@ implementation
|
|||||||
if temptovalue then
|
if temptovalue then
|
||||||
begin
|
begin
|
||||||
cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
|
cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,
|
||||||
temp1,t2.location,aktbreaklabel);
|
temp1,left.location,aktbreaklabel);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if lnf_testatbegin in loopflags then
|
if lnf_testatbegin in loopflags then
|
||||||
begin
|
begin
|
||||||
cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
|
cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
|
||||||
tordconstnode(right).value,
|
tordconstnode(t1).value,
|
||||||
t2.location,aktbreaklabel);
|
left.location,aktbreaklabel);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -413,11 +421,11 @@ implementation
|
|||||||
hop:=OP_ADD
|
hop:=OP_ADD
|
||||||
else
|
else
|
||||||
hop:=OP_SUB;
|
hop:=OP_SUB;
|
||||||
cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
|
cg.a_op_const_loc(exprasmlist,hop,1,left.location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not(cs_littlesize in aktglobalswitches) then
|
|
||||||
{ align loop target }
|
{ align loop target }
|
||||||
|
if not(cs_littlesize in aktglobalswitches) then
|
||||||
exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
|
exprasmList.concat(Tai_align.Create(aktalignment.loopalign));
|
||||||
cg.a_label(exprasmlist,l3);
|
cg.a_label(exprasmlist,l3);
|
||||||
|
|
||||||
@ -430,13 +438,12 @@ implementation
|
|||||||
hop:=OP_SUB
|
hop:=OP_SUB
|
||||||
else
|
else
|
||||||
hop:=OP_ADD;
|
hop:=OP_ADD;
|
||||||
cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
|
cg.a_op_const_loc(exprasmlist,hop,1,left.location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ help register must not be in instruction block }
|
if assigned(t2) then
|
||||||
if assigned(t1) then
|
|
||||||
begin
|
begin
|
||||||
secondpass(t1);
|
secondpass(t2);
|
||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
load_all_regvars(exprasmlist);
|
load_all_regvars(exprasmlist);
|
||||||
{$endif OLDREGVARS}
|
{$endif OLDREGVARS}
|
||||||
@ -451,7 +458,7 @@ implementation
|
|||||||
hop:=OP_SUB
|
hop:=OP_SUB
|
||||||
else
|
else
|
||||||
hop:=OP_ADD;
|
hop:=OP_ADD;
|
||||||
cg.a_op_const_loc(exprasmlist,hop,1,t2.location);
|
cg.a_op_const_loc(exprasmlist,hop,1,left.location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
cg.a_label(exprasmlist,aktcontinuelabel);
|
cg.a_label(exprasmlist,aktcontinuelabel);
|
||||||
@ -487,12 +494,12 @@ implementation
|
|||||||
if temptovalue then
|
if temptovalue then
|
||||||
begin
|
begin
|
||||||
cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
|
cg.a_cmp_ref_loc_label(exprasmlist,opsize,hcond,temp1,
|
||||||
t2.location,l3);
|
left.location,l3);
|
||||||
tg.ungetiftemp(exprasmlist,temp1);
|
tg.ungetiftemp(exprasmlist,temp1);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
cmp_const:=Tordconstnode(right).value;
|
cmp_const:=Tordconstnode(t1).value;
|
||||||
if do_loopvar_at_end then
|
if do_loopvar_at_end then
|
||||||
begin
|
begin
|
||||||
{Watch out for wrap around 255 -> 0.}
|
{Watch out for wrap around 255 -> 0.}
|
||||||
@ -597,18 +604,18 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if lnf_backward in loopflags then
|
if lnf_backward in loopflags then
|
||||||
begin
|
begin
|
||||||
if integer(cmp_const)=high(integer) then
|
if integer(cmp_const)=high(smallint) then
|
||||||
begin
|
begin
|
||||||
hcond:=OC_NE;
|
hcond:=OC_NE;
|
||||||
cmp_const:=low(integer);
|
cmp_const:=low(smallint);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if integer(cmp_const)=low(integer) then
|
if integer(cmp_const)=low(smallint) then
|
||||||
begin
|
begin
|
||||||
hcond:=OC_NE;
|
hcond:=OC_NE;
|
||||||
cmp_const:=high(integer);
|
cmp_const:=high(smallint);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@ -656,7 +663,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
|
cg.a_cmp_const_loc_label(exprasmlist,opsize,hcond,
|
||||||
cmp_const,t2.location,l3);
|
cmp_const,left.location,l3);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ this is the break label: }
|
{ this is the break label: }
|
||||||
@ -1443,7 +1450,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.102 2004-11-08 22:09:59 peter
|
Revision 1.103 2005-01-31 16:16:21 peter
|
||||||
|
* for-node cleanup, checking for uninitialzed from and to values
|
||||||
|
is now supported
|
||||||
|
|
||||||
|
Revision 1.102 2004/11/08 22:09:59 peter
|
||||||
* tvarsym splitted
|
* tvarsym splitted
|
||||||
|
|
||||||
Revision 1.101 2004/10/24 11:44:28 peter
|
Revision 1.101 2004/10/24 11:44:28 peter
|
||||||
|
@ -68,7 +68,7 @@ interface
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
twhilerepeatnode = class(tloopnode)
|
twhilerepeatnode = class(tloopnode)
|
||||||
constructor create(l,r,_t1:Tnode;tab,cn:boolean);virtual;
|
constructor create(l,r:Tnode;tab,cn:boolean);virtual;
|
||||||
function det_resulttype:tnode;override;
|
function det_resulttype:tnode;override;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
{$ifdef state_tracking}
|
{$ifdef state_tracking}
|
||||||
@ -196,9 +196,6 @@ interface
|
|||||||
end;
|
end;
|
||||||
tonnodeclass = class of tonnode;
|
tonnodeclass = class of tonnode;
|
||||||
|
|
||||||
{ for compatibilty }
|
|
||||||
function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
cwhilerepeatnode : twhilerepeatnodeclass;
|
cwhilerepeatnode : twhilerepeatnodeclass;
|
||||||
cifnode : tifnodeclass;
|
cifnode : tifnodeclass;
|
||||||
@ -227,28 +224,6 @@ implementation
|
|||||||
cgbase,procinfo
|
cgbase,procinfo
|
||||||
;
|
;
|
||||||
|
|
||||||
function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
|
|
||||||
|
|
||||||
var
|
|
||||||
p : tnode;
|
|
||||||
|
|
||||||
begin
|
|
||||||
case t of
|
|
||||||
ifn:
|
|
||||||
p:=cifnode.create(l,r,n1);
|
|
||||||
whilerepeatn:
|
|
||||||
if back then
|
|
||||||
{Repeat until.}
|
|
||||||
p:=cwhilerepeatnode.create(l,r,n1,false,true)
|
|
||||||
else
|
|
||||||
{While do.}
|
|
||||||
p:=cwhilerepeatnode.create(l,r,n1,true,false);
|
|
||||||
forn:
|
|
||||||
p:=cfornode.create(l,r,n1,nil,back);
|
|
||||||
end;
|
|
||||||
resulttypepass(p);
|
|
||||||
genloopnode:=p;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TLOOPNODE
|
TLOOPNODE
|
||||||
@ -361,9 +336,9 @@ implementation
|
|||||||
TWHILEREPEATNODE
|
TWHILEREPEATNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
constructor Twhilerepeatnode.create(l,r,_t1:Tnode;tab,cn:boolean);
|
constructor Twhilerepeatnode.create(l,r:Tnode;tab,cn:boolean);
|
||||||
begin
|
begin
|
||||||
inherited create(whilerepeatn,l,r,_t1,nil);
|
inherited create(whilerepeatn,l,r,nil,nil);
|
||||||
if tab then
|
if tab then
|
||||||
include(loopflags, lnf_testatbegin);
|
include(loopflags, lnf_testatbegin);
|
||||||
if cn then
|
if cn then
|
||||||
@ -705,42 +680,39 @@ implementation
|
|||||||
resulttype:=voidtype;
|
resulttype:=voidtype;
|
||||||
|
|
||||||
{Can we spare the first comparision?}
|
{Can we spare the first comparision?}
|
||||||
if (right.nodetype=ordconstn) and
|
if (t1.nodetype=ordconstn) and
|
||||||
(Tassignmentnode(left).right.nodetype=ordconstn) and
|
(right.nodetype=ordconstn) and
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
(lnf_backward in loopflags) and
|
(lnf_backward in loopflags) and
|
||||||
(Tordconstnode(Tassignmentnode(left).right).value>=Tordconstnode(right).value)
|
(Tordconstnode(right).value>=Tordconstnode(t1).value)
|
||||||
) or
|
) or
|
||||||
(
|
(
|
||||||
not(lnf_backward in loopflags) and
|
not(lnf_backward in loopflags) and
|
||||||
(Tordconstnode(Tassignmentnode(left).right).value<=Tordconstnode(right).value)
|
(Tordconstnode(right).value<=Tordconstnode(t1).value)
|
||||||
)
|
)
|
||||||
) then
|
) then
|
||||||
exclude(loopflags,lnf_testatbegin);
|
exclude(loopflags,lnf_testatbegin);
|
||||||
|
|
||||||
{ save counter var }
|
{ process the loopvar, from and to }
|
||||||
t2:=tassignmentnode(left).left.getcopy;
|
|
||||||
|
|
||||||
resulttypepass(left);
|
resulttypepass(left);
|
||||||
set_varstate(left,vs_used,true);
|
|
||||||
|
|
||||||
if assigned(t1) then
|
|
||||||
begin
|
|
||||||
resulttypepass(t1);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ process count var }
|
|
||||||
resulttypepass(t2);
|
|
||||||
set_varstate(t2,vs_used,false);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
resulttypepass(right);
|
resulttypepass(right);
|
||||||
|
resulttypepass(t1);
|
||||||
|
|
||||||
|
{ first set the varstate for from and to, so
|
||||||
|
uses of loopvar in those expressions will also
|
||||||
|
trigger a warning when it is not used yet }
|
||||||
set_varstate(right,vs_used,true);
|
set_varstate(right,vs_used,true);
|
||||||
inserttypeconv(right,t2.resulttype);
|
set_varstate(t1,vs_used,true);
|
||||||
|
set_varstate(left,vs_used,false);
|
||||||
|
|
||||||
|
{ Make sure that the loop var and the
|
||||||
|
from and to values are compatible types }
|
||||||
|
inserttypeconv(right,left.resulttype);
|
||||||
|
inserttypeconv(t1,left.resulttype);
|
||||||
|
|
||||||
|
if assigned(t2) then
|
||||||
|
resulttypepass(t2);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -750,25 +722,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
expectloc:=LOC_VOID;
|
expectloc:=LOC_VOID;
|
||||||
{ Calc register weight }
|
|
||||||
old_t_times:=cg.t_times;
|
|
||||||
if not(cs_littlesize in aktglobalswitches) then
|
|
||||||
cg.t_times:=cg.t_times*8;
|
|
||||||
|
|
||||||
firstpass(left);
|
firstpass(left);
|
||||||
|
|
||||||
if assigned(t1) then
|
|
||||||
begin
|
|
||||||
firstpass(t1);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
registersint:=t1.registersint;
|
|
||||||
registersfpu:=t1.registersfpu;
|
|
||||||
{$ifdef SUPPORT_MMX}
|
|
||||||
registersmmx:=left.registersmmx;
|
|
||||||
{$endif SUPPORT_MMX}
|
|
||||||
if left.registersint>registersint then
|
if left.registersint>registersint then
|
||||||
registersint:=left.registersint;
|
registersint:=left.registersint;
|
||||||
if left.registersfpu>registersfpu then
|
if left.registersfpu>registersfpu then
|
||||||
@ -778,7 +733,32 @@ implementation
|
|||||||
registersmmx:=left.registersmmx;
|
registersmmx:=left.registersmmx;
|
||||||
{$endif SUPPORT_MMX}
|
{$endif SUPPORT_MMX}
|
||||||
|
|
||||||
{ process count var }
|
firstpass(right);
|
||||||
|
if right.registersint>registersint then
|
||||||
|
registersint:=right.registersint;
|
||||||
|
if right.registersfpu>registersfpu then
|
||||||
|
registersfpu:=right.registersfpu;
|
||||||
|
{$ifdef SUPPORT_MMX}
|
||||||
|
if right.registersmmx>registersmmx then
|
||||||
|
registersmmx:=right.registersmmx;
|
||||||
|
{$endif SUPPORT_MMX}
|
||||||
|
|
||||||
|
firstpass(t1);
|
||||||
|
if t1.registersint>registersint then
|
||||||
|
registersint:=t1.registersint;
|
||||||
|
if t1.registersfpu>registersfpu then
|
||||||
|
registersfpu:=t1.registersfpu;
|
||||||
|
{$ifdef SUPPORT_MMX}
|
||||||
|
if t1.registersmmx>registersmmx then
|
||||||
|
registersmmx:=t1.registersmmx;
|
||||||
|
{$endif SUPPORT_MMX}
|
||||||
|
|
||||||
|
if assigned(t2) then
|
||||||
|
begin
|
||||||
|
{ Calc register weight }
|
||||||
|
old_t_times:=cg.t_times;
|
||||||
|
if not(cs_littlesize in aktglobalswitches) then
|
||||||
|
cg.t_times:=cg.t_times*8;
|
||||||
firstpass(t2);
|
firstpass(t2);
|
||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
@ -790,32 +770,12 @@ implementation
|
|||||||
if t2.registersmmx>registersmmx then
|
if t2.registersmmx>registersmmx then
|
||||||
registersmmx:=t2.registersmmx;
|
registersmmx:=t2.registersmmx;
|
||||||
{$endif SUPPORT_MMX}
|
{$endif SUPPORT_MMX}
|
||||||
|
cg.t_times:=old_t_times;
|
||||||
|
end;
|
||||||
|
|
||||||
firstpass(right);
|
|
||||||
{$ifdef loopvar_dont_mind}
|
|
||||||
{ Check count var, record fields are also allowed in tp7 }
|
|
||||||
include(loopflags,lnf_dont_mind_loopvar_on_exit);
|
|
||||||
hp:=t2;
|
|
||||||
while (hp.nodetype=subscriptn) or
|
|
||||||
((hp.nodetype=vecn) and
|
|
||||||
is_constintnode(tvecnode(hp).right)) do
|
|
||||||
hp:=tunarynode(hp).left;
|
|
||||||
if (hp.nodetype=loadn) and (Tloadnode(hp).symtableentry.typ=varsym) then
|
|
||||||
loopvar_notid:=Tvarsym(Tloadnode(hp).symtableentry).
|
|
||||||
register_notification([vn_onread,vn_onwrite],@loop_var_access);
|
|
||||||
{$endif}
|
|
||||||
if right.registersint>registersint then
|
|
||||||
registersint:=right.registersint;
|
|
||||||
if right.registersfpu>registersfpu then
|
|
||||||
registersfpu:=right.registersfpu;
|
|
||||||
{$ifdef SUPPORT_MMX}
|
|
||||||
if right.registersmmx>registersmmx then
|
|
||||||
registersmmx:=right.registersmmx;
|
|
||||||
{$endif SUPPORT_MMX}
|
|
||||||
{ we need at least one register for comparisons PM }
|
{ we need at least one register for comparisons PM }
|
||||||
if registersint=0 then
|
if registersint=0 then
|
||||||
inc(registersint);
|
inc(registersint);
|
||||||
cg.t_times:=old_t_times;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1441,7 +1401,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.106 2005-01-16 14:44:03 peter
|
Revision 1.107 2005-01-31 16:16:21 peter
|
||||||
|
* for-node cleanup, checking for uninitialzed from and to values
|
||||||
|
is now supported
|
||||||
|
|
||||||
|
Revision 1.106 2005/01/16 14:44:03 peter
|
||||||
* fix unreachable code check for repeat loop
|
* fix unreachable code check for repeat loop
|
||||||
|
|
||||||
Revision 1.105 2005/01/16 10:50:32 peter
|
Revision 1.105 2005/01/16 10:50:32 peter
|
||||||
|
@ -81,7 +81,7 @@ implementation
|
|||||||
else_a:=statement
|
else_a:=statement
|
||||||
else
|
else
|
||||||
else_a:=nil;
|
else_a:=nil;
|
||||||
if_statement:=genloopnode(ifn,ex,if_a,else_a,false);
|
result:=cifnode.create(ex,if_a,else_a);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ creates a block (list) of statements, til the next END token }
|
{ creates a block (list) of statements, til the next END token }
|
||||||
@ -116,7 +116,7 @@ implementation
|
|||||||
function case_statement : tnode;
|
function case_statement : tnode;
|
||||||
var
|
var
|
||||||
casedef : tdef;
|
casedef : tdef;
|
||||||
code,caseexpr,p,instruc,elseblock : tnode;
|
caseexpr,p : tnode;
|
||||||
blockid : longint;
|
blockid : longint;
|
||||||
hl1,hl2 : TConstExprInt;
|
hl1,hl2 : TConstExprInt;
|
||||||
casedeferror : boolean;
|
casedeferror : boolean;
|
||||||
@ -221,10 +221,7 @@ implementation
|
|||||||
casenode.addelseblock(statements_til_end);
|
casenode.addelseblock(statements_til_end);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
|
||||||
elseblock:=nil;
|
|
||||||
consume(_END);
|
consume(_END);
|
||||||
end;
|
|
||||||
|
|
||||||
result:=casenode;
|
result:=casenode;
|
||||||
end;
|
end;
|
||||||
@ -259,7 +256,7 @@ implementation
|
|||||||
|
|
||||||
first:=cblocknode.create(first);
|
first:=cblocknode.create(first);
|
||||||
p_e:=comp_expr(true);
|
p_e:=comp_expr(true);
|
||||||
repeat_statement:=genloopnode(whilerepeatn,p_e,first,nil,true);
|
result:=cwhilerepeatnode.create(p_e,first,false,true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -273,41 +270,42 @@ implementation
|
|||||||
p_e:=comp_expr(true);
|
p_e:=comp_expr(true);
|
||||||
consume(_DO);
|
consume(_DO);
|
||||||
p_a:=statement;
|
p_a:=statement;
|
||||||
while_statement:=genloopnode(whilerepeatn,p_e,p_a,nil,false);
|
result:=cwhilerepeatnode.create(p_e,p_a,true,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function for_statement : tnode;
|
function for_statement : tnode;
|
||||||
|
|
||||||
var
|
var
|
||||||
p_e,tovalue,p_a : tnode;
|
hp,
|
||||||
|
hloopvar,
|
||||||
|
hblock,
|
||||||
|
hto,hfrom : tnode;
|
||||||
backward : boolean;
|
backward : boolean;
|
||||||
loopvarsym : tabstractvarsym;
|
loopvarsym : tabstractvarsym;
|
||||||
hp : tnode;
|
|
||||||
begin
|
begin
|
||||||
{ parse loop header }
|
{ parse loop header }
|
||||||
consume(_FOR);
|
consume(_FOR);
|
||||||
p_e:=expr;
|
|
||||||
|
hloopvar:=factor(false);
|
||||||
|
|
||||||
{ Check loop variable }
|
{ Check loop variable }
|
||||||
hp:=nil;
|
|
||||||
loopvarsym:=nil;
|
loopvarsym:=nil;
|
||||||
if (p_e.nodetype=assignn) then
|
|
||||||
begin
|
|
||||||
hp:=tassignmentnode(p_e).left;
|
|
||||||
|
|
||||||
{ variable must be an ordinal, int64 is not allowed for 32bit targets }
|
{ variable must be an ordinal, int64 is not allowed for 32bit targets }
|
||||||
if not(is_ordinal(hp.resulttype.def))
|
if not(is_ordinal(hloopvar.resulttype.def))
|
||||||
{$ifndef cpu64bit}
|
{$ifndef cpu64bit}
|
||||||
or is_64bitint(hp.resulttype.def)
|
or is_64bitint(hloopvar.resulttype.def)
|
||||||
{$endif cpu64bit}
|
{$endif cpu64bit}
|
||||||
then
|
then
|
||||||
MessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
|
MessagePos(hloopvar.fileinfo,type_e_ordinal_expr_expected);
|
||||||
|
|
||||||
|
hp:=hloopvar;
|
||||||
while assigned(hp) and
|
while assigned(hp) and
|
||||||
(
|
(
|
||||||
{ record/object fields are allowed }
|
{ record/object fields are allowed in tp7 mode only }
|
||||||
(
|
(
|
||||||
|
(m_tp7 in aktmodeswitches) and
|
||||||
(hp.nodetype=subscriptn) and
|
(hp.nodetype=subscriptn) and
|
||||||
((tsubscriptnode(hp).left.resulttype.def.deftype=recorddef) or
|
((tsubscriptnode(hp).left.resulttype.def.deftype=recorddef) or
|
||||||
is_object(tsubscriptnode(hp).left.resulttype.def))
|
is_object(tsubscriptnode(hp).left.resulttype.def))
|
||||||
@ -350,8 +348,6 @@ implementation
|
|||||||
(vo_is_thread_var in tabstractvarsym(tloadnode(hp).symtableentry).varoptions))
|
(vo_is_thread_var in tabstractvarsym(tloadnode(hp).symtableentry).varoptions))
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
tabstractvarsym(tloadnode(hp).symtableentry).varstate:=vs_used;
|
|
||||||
|
|
||||||
{ Assigning for-loop variable is only allowed in tp7 }
|
{ Assigning for-loop variable is only allowed in tp7 }
|
||||||
if not(m_tp7 in aktmodeswitches) then
|
if not(m_tp7 in aktmodeswitches) then
|
||||||
begin
|
begin
|
||||||
@ -374,32 +370,31 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
MessagePos(tassignmentnode(p_e).left.fileinfo,type_e_illegal_count_var);
|
MessagePos(hloopvar.fileinfo,type_e_illegal_count_var);
|
||||||
end
|
|
||||||
else
|
|
||||||
Message(parser_e_illegal_expression);
|
|
||||||
|
|
||||||
if token=_DOWNTO then
|
consume(_ASSIGNMENT);
|
||||||
begin
|
|
||||||
consume(_DOWNTO);
|
hfrom:=comp_expr(true);
|
||||||
backward:=true;
|
|
||||||
end
|
if try_to_consume(_DOWNTO) then
|
||||||
|
backward:=true
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
consume(_TO);
|
consume(_TO);
|
||||||
backward:=false;
|
backward:=false;
|
||||||
end;
|
end;
|
||||||
tovalue:=comp_expr(true);
|
|
||||||
|
hto:=comp_expr(true);
|
||||||
consume(_DO);
|
consume(_DO);
|
||||||
|
|
||||||
{ ... now the instruction block }
|
{ ... now the instruction block }
|
||||||
p_a:=statement;
|
hblock:=statement;
|
||||||
|
|
||||||
{ variable is not used a loop counter anymore }
|
{ variable is not used a loop counter anymore }
|
||||||
if assigned(loopvarsym) then
|
if assigned(loopvarsym) then
|
||||||
exclude(loopvarsym.varoptions,vo_is_loop_counter);
|
exclude(loopvarsym.varoptions,vo_is_loop_counter);
|
||||||
|
|
||||||
for_statement:=genloopnode(forn,p_e,tovalue,p_a,backward);
|
result:=cfornode.create(hloopvar,hfrom,hto,hblock,backward);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1025,7 +1020,10 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if assigned(code) then
|
if assigned(code) then
|
||||||
|
begin
|
||||||
|
resulttypepass(code);
|
||||||
code.fileinfo:=filepos;
|
code.fileinfo:=filepos;
|
||||||
|
end;
|
||||||
statement:=code;
|
statement:=code;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1147,7 +1145,11 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.149 2004-12-26 16:22:01 peter
|
Revision 1.150 2005-01-31 16:16:21 peter
|
||||||
|
* for-node cleanup, checking for uninitialzed from and to values
|
||||||
|
is now supported
|
||||||
|
|
||||||
|
Revision 1.149 2004/12/26 16:22:01 peter
|
||||||
* fix lineinfo for with blocks
|
* fix lineinfo for with blocks
|
||||||
|
|
||||||
Revision 1.148 2004/12/07 16:11:52 peter
|
Revision 1.148 2004/12/07 16:11:52 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user