From 5752be310dd4e233a7c5ad1641006b87e0c875b1 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 4 Nov 2009 12:07:42 +0000 Subject: [PATCH] compiler: - fix for-in loop for string const array - add some test from Alexander S. Klenin (issue #0014990) git-svn-id: trunk@14041 - --- .gitattributes | 6 ++++++ compiler/nflw.pas | 27 +++++++++++++++++++++++---- compiler/pp.lpi | 2 +- tests/test/tforin10.pp | 1 + tests/test/tforin11.pp | 1 + tests/test/tforin12.pp | 10 ++++++++++ tests/test/tforin13.pp | 8 ++++++++ tests/test/tforin14.pp | 24 ++++++++++++++++++++++++ tests/test/tforin15.pp | 39 +++++++++++++++++++++++++++++++++++++++ tests/test/tforin16.pp | 7 +++++++ tests/test/tforin17.pp | 6 ++++++ 11 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 tests/test/tforin12.pp create mode 100644 tests/test/tforin13.pp create mode 100644 tests/test/tforin14.pp create mode 100644 tests/test/tforin15.pp create mode 100644 tests/test/tforin16.pp create mode 100644 tests/test/tforin17.pp diff --git a/.gitattributes b/.gitattributes index 9820b0bc8f..896aafd913 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8229,6 +8229,12 @@ tests/test/tfinal2.pp svneol=native#text/pascal tests/test/tforin1.pp svneol=native#text/pascal tests/test/tforin10.pp svneol=native#text/plain tests/test/tforin11.pp svneol=native#text/plain +tests/test/tforin12.pp svneol=native#text/pascal +tests/test/tforin13.pp svneol=native#text/pascal +tests/test/tforin14.pp svneol=native#text/pascal +tests/test/tforin15.pp svneol=native#text/pascal +tests/test/tforin16.pp svneol=native#text/pascal +tests/test/tforin17.pp svneol=native#text/pascal tests/test/tforin2.pp svneol=native#text/pascal tests/test/tforin3.pp svneol=native#text/pascal tests/test/tforin4.pp svneol=native#text/pascal diff --git a/compiler/nflw.pas b/compiler/nflw.pas index e09770af93..9a055bd7ff 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -304,10 +304,13 @@ var loopstatement, loopbodystatement: tstatementnode; loopvar, arrayvar: ttempcreatenode; arrayindex, lowbound, highbound, loopbody, forloopnode: tnode; + is_string: boolean; begin { result is a block of statements } result:=internalstatements(loopstatement); + is_string := ado_IsConstString in tarraydef(expr.resultdef).arrayoptions; + if (node_complexity(expr) > 1) and not is_open_array(expr.resultdef) then begin { create a temp variable for expression } @@ -316,8 +319,16 @@ begin expr.resultdef.size, tt_persistent,true); - lowbound:=cinlinenode.create(in_low_x,false,ctemprefnode.create(arrayvar)); - highbound:=cinlinenode.create(in_high_x,false,ctemprefnode.create(arrayvar)); + if is_string then + begin + lowbound:=genintconstnode(1); + highbound:=cinlinenode.create(in_length_x,false,ctemprefnode.create(arrayvar)) + end + else + begin + lowbound:=cinlinenode.create(in_low_x,false,ctemprefnode.create(arrayvar)); + highbound:=cinlinenode.create(in_high_x,false,ctemprefnode.create(arrayvar)); + end; addstatement(loopstatement,arrayvar); addstatement(loopstatement,cassignmentnode.create(ctemprefnode.create(arrayvar),expr.getcopy)); @@ -325,8 +336,16 @@ begin else begin arrayvar:=nil; - lowbound:=cinlinenode.create(in_low_x,false,expr.getcopy); - highbound:=cinlinenode.create(in_high_x,false,expr.getcopy); + if is_string then + begin + lowbound:=genintconstnode(1); + highbound:=cinlinenode.create(in_length_x,false,expr.getcopy); + end + else + begin + lowbound:=cinlinenode.create(in_low_x,false,expr.getcopy); + highbound:=cinlinenode.create(in_high_x,false,expr.getcopy); + end; end; { create a loop counter } diff --git a/compiler/pp.lpi b/compiler/pp.lpi index 92250a4003..1ab569db54 100644 --- a/compiler/pp.lpi +++ b/compiler/pp.lpi @@ -44,7 +44,7 @@ - + diff --git a/tests/test/tforin10.pp b/tests/test/tforin10.pp index 549d1d952e..156e437303 100644 --- a/tests/test/tforin10.pp +++ b/tests/test/tforin10.pp @@ -5,6 +5,7 @@ program tforin10; {$mode objfpc}{$H+} +{$apptype console} type TSomeClass = class diff --git a/tests/test/tforin11.pp b/tests/test/tforin11.pp index c76e8825d2..9324530049 100644 --- a/tests/test/tforin11.pp +++ b/tests/test/tforin11.pp @@ -5,6 +5,7 @@ program tforin11; {$mode objfpc}{$H+} +{$apptype console} var s: String; diff --git a/tests/test/tforin12.pp b/tests/test/tforin12.pp new file mode 100644 index 0000000000..d4a0ac6aa5 --- /dev/null +++ b/tests/test/tforin12.pp @@ -0,0 +1,10 @@ +{mode objfpc} +{$apptype console} +type T = array [1..3] of Char; +var + a: array [1..3] of T = ('asd', 'sdf', 'ddf'); + s: T; +begin + for s in a do + Writeln(s); +end. diff --git a/tests/test/tforin13.pp b/tests/test/tforin13.pp new file mode 100644 index 0000000000..e32bd4a362 --- /dev/null +++ b/tests/test/tforin13.pp @@ -0,0 +1,8 @@ +{mode objfpc} +{$apptype console} +var + ch: Char; +begin + for ch in ['a'..'c', '0'..'3', '_'] do + Writeln(ch); +end. diff --git a/tests/test/tforin14.pp b/tests/test/tforin14.pp new file mode 100644 index 0000000000..2be38d8d4f --- /dev/null +++ b/tests/test/tforin14.pp @@ -0,0 +1,24 @@ +{mode objfpc} +{$apptype console} +type + T = array [1..3] of Integer; + + +procedure P(a: array of T); +var + r: T; + i: Integer; +begin + for r in a do + begin + for i in r do Write(i, ' '); + Writeln; + end; +end; + +const + r1: T = (1,2,9); + r2: T = (3,4,5); +begin + P([r1, r2]); +end. diff --git a/tests/test/tforin15.pp b/tests/test/tforin15.pp new file mode 100644 index 0000000000..32add6fa02 --- /dev/null +++ b/tests/test/tforin15.pp @@ -0,0 +1,39 @@ +{$mode objfpc} +{$apptype console} + +type + T = class + stop: boolean; + F: Integer; + function MoveNext: Boolean; + property Current: Integer read F; + end; + +Twice = type Integer; + +function T.MoveNext: Boolean; +begin + Result := not stop; + stop := true; +end; + +operator enumerator(a: Integer): T; +begin + Result := T.Create; + Result.F := a; + Result.stop := false; +end; + +operator enumerator(a: Twice): T; +begin + Result := T.Create; + Result.F := a * 2; + Result.stop := false; +end; + +var + i: Integer; +begin + for i in Twice(1) do + Writeln(i); +end. \ No newline at end of file diff --git a/tests/test/tforin16.pp b/tests/test/tforin16.pp new file mode 100644 index 0000000000..692c02c7aa --- /dev/null +++ b/tests/test/tforin16.pp @@ -0,0 +1,7 @@ +{mode objfpc} +{$apptype console} +const S = 'abc'; +var ch: Char; +begin + for ch in S do Writeln(ch); +end. diff --git a/tests/test/tforin17.pp b/tests/test/tforin17.pp new file mode 100644 index 0000000000..e482a4382b --- /dev/null +++ b/tests/test/tforin17.pp @@ -0,0 +1,6 @@ +{mode objfpc} +{$apptype console} +var ch: Char; +begin + for ch in 'abc' do Writeln(ch); +end. \ No newline at end of file