Artur Kornilowicz wrote:
Hello,
I think gpc does not work properly when one gives a boolean function as a condition in repeat until loop. Please find an example below. I tested it on 2 different machines working under Linux and Darwin.
When you change
repeat until F1(a,b);
by
repeat x := F1(a,b); until x;
in procedure F2, then it works.
Greetings Artur
program tester;
function F1(a,b : string):boolean; begin writeln('F1(',a,',',b,')',length(a),' ',length(b)); F1:=true; end;
procedure F2(a,b : string); begin // writeln('F2(',a,',',b,')',length(a),' ',length(b)); //not necessary //when you add above, below works repeat until F1(a,b); //incorrect result repeat until F1('3','3'); //correct result //not necessary end;
var c: string; //not necessary
begin c:='1'; //not necessary repeat until F1(c,c); //correct result //not necessary F2('2','2'); end.
Remarks:
a) to have smaller example you can delete all lines with comment "not necessary" at the end of the line.
b) when F1 and F2 have only one parameter they seem to work.
Outputs:
Mac, Darwin Version: gpc 20030830, based on gcc-3.3.2 F1(2,1)1 1 F1(2,)1 1 // why the second printing is empty? F1(2,1)1 1
Intel, Linux gpc 20040516, based on gcc-3.3.1 artur@alioth:~> ./a.out F1(1,1)1 1 Segmentation fault artur@alioth:~>
Later Ernst-Ludwig Bohnen wrote:
It seems to me that the problem is using the suspicious type 'string'. Declare 'type s=string (100)' and change all types 'string' by 's'. This works on my Linux with gpc version 20040516, based on gcc-3.2.3. F1(1,1)1 1 F1(2,2)1 1 F1(3,3)1 1
Only line:
var c: string;
is suspicious. In fact the compiler treats it as:
var c: string(255);
Arthur's version of `F1' can handle strings of arbitrary length (well, up to stack limit). Changing that to fixed length works around the problem. In this case better workaround is probably passing strings as `const' parameters (avoids useless copy):
function F1(const a,b : string):boolean;
However, the original is supposed to work. The patch below below should fix the problem:
--- gpc-20040516/p/parse.y~ 2004-09-11 03:03:51.000000000 +0200 +++ gpc-20040516/p/parse.y 2004-09-13 14:12:38.000000000 +0200 @@ -1818,10 +1818,11 @@ { emit_nop (); expand_start_loop_continue_elsewhere (1); } pushlevel statement_sequence p_until { LOCATION_NOTE (@5); expand_loop_continue_here (); } - boolean_expression poplevel + boolean_expression { LOCATION_NOTE (@7); expand_exit_loop_if_false (0, build_pascal_unary_op (TRUTH_NOT_EXPR, $7)); + poplevel_expand (0, 1); expand_end_loop (); } ;