Hello,
All the tests below were on the latest (?) binary release of
GNU Pascal for mingw. The result of "gpc -v" is:
gpc version 2.1 (20020510), based on 2.95.3-6 (mingw special)
I'm interested in standard (ISO) modes, especially ISO 7185,
so I have been using the "--classic-pascal" option. I'm only
indicating that (in FLAG comments) where I suspect that, what
GNU Pascal currently does may be appropriate, when standard
compliance is not requested.
First, some test programs with non-standard features:
program az1(output);
(* FLAG --classic-pascal *)
const c=2+2; (* WRONG - violation of 6.3 of ISO 7185 *)
begin
writeln('failed')
end.
program az2(output);
(* FLAG --classic-pascal *)
const p=nil; (* WRONG - violation of 6.3 of ISO 7185 *)
begin
writeln('failed')
end.
program az3(output);
(* FLAG --classic-pascal *)
procedure q(x:integer);
const xx=x*x; (* WRONG - violation of 6.3 of ISO 7185 *)
begin
end;
begin
writeln('failed')
end.
program az4(output);
(* FLAG --classic-pascal *)
begin
case 4 of
2+2: (* WRONG - violation of 6.8.3.5 of ISO 7185 *)
end;
writeln('failed')
end.
program az5(output);
(* FLAG --classic-pascal *)
var r:record
case boolean of
false..true:() (* WRONG - violation of 6.8.3.5 of ISO 7185 *)
end;
begin
writeln('failed')
end.
program az6(output);
(* FLAG --extended-pascal *)
begin
if ord('')=32 then; (* WRONG - violation of 6.7.6.4 of ISO 10206 *)
writeln('failed')
end.
program az7(output);
(* FLAG --classic-pascal *)
begin
if []<[1] then; (* WRONG - violation of 6.7.2.5 of ISO 7185 *)
writeln('failed')
end.
program az8(output);
(* FLAG --classic-pascal *)
type t=set of char;
function f:t; (* WRONG - violation of 6.6.2 of ISO 7185 *)
begin
f:=[]
end;
begin
writeln('failed')
end.
program az9(output);
(* FLAG --classic-pascal *)
type t=record end;
var x:t;
function f:t; (* WRONG - violation of 6.6.2 of ISO 7185 *)
begin
f:=x
end;
begin
writeln('failed')
end.
program az10(output);
(* FLAG --classic-pascal *)
procedure q(procedure r);
begin
end;
begin
q(nil); (* WRONG - violation of 6.6.3.4 of ISO 7185 *)
writeln('failed')
end.
program az11(output);
(* FLAG --classic-pascal *)
var a:record
case b:boolean of
true,false:()
end;
procedure p(var x:boolean);
begin
end;
begin
p(a.b); (* WRONG - violation of 6.6.3.3 of ISO 7185 *)
writeln('failed')
end.
program az12(output);
(* FLAG --classic-pascal *)
procedure q(procedure r);
begin
r:=r (* WRONG - violation of 6.4.6 of ISO 7185 *)
end;
begin
writeln('failed')
end.
program az13(output);
(* FLAG --classic-pascal *)
var t:array [boolean] of integer;
begin
if t=t then; (* WRONG - violation of 6.7.2.5 of ISO 7185 *)
writeln('failed')
end.
program az14(output);
(* FLAG --classic-pascal *)
begin
if 'ab'='abc' then; (* WRONG - violation of 6.7.2.5 of ISO 7185 *)
writeln('failed')
end.
program az15(output);
(* FLAG --classic-pascal *)
begin
write('failed');
writeln('1':0,'22':0,3:0) (* WRONG - violation of 6.9.3.1 of ISO 7185 *)
(* Besides, writing "13" seems inconsistent *)
end.
program az16(output);
(* FLAG --classic-pascal *)
var r:record end;
begin
with (r) do; (* WRONG - violation of 6.8.3.10 of ISO 7185 *)
writeln('failed')
end.
program az17(output);
(* FLAG --classic-pascal *)
var p:^integer;
begin
new((p)); (* WRONG - violation of 6.6.5.3 of ISO 7185 *)
writeln('failed')
end.
program az18(output);
(* FLAG --classic-pascal *)
var a:array [1..1] of integer;
begin
(a)[1]:=10; (* WRONG - violation 6.5.3.2 of ISO 7185 *)
writeln('failed')
end.
Correct programs, which don't compile:
(*
az19.pas: In main program:
az19.pas:4: division by zero
*)
program az19(output);
begin
if false then
writeln('failed: ',1/0)
else
writeln('OK')
end.
(*
az20.pas: In main program:
az20.pas:7: warning: ISO Pascal forbids this use of packed array components
*)
program az20(output);
(* FLAG --classic-pascal -Werror *)
var t:packed array [1..1,1..1] of boolean;
i:integer;
begin
i:=1;
t[1,i]:=false;
writeln('OK')
end.
(*
az21.pas: In main program:
az21.pas:11: type mismatch in array index
az21.pas:11: array subscript is not of ordinal type
*)
program az21(output);
var t:array [1..1] of integer;
procedure r(x:integer);
begin
end;
function q:integer;
begin
q:=1
end;
begin
r(t[q]);
writeln('OK')
end.
(*
az22.pas: In procedure `P':
az22.pas:5: function definition does not match previous declaration
az22.pas: In function `X':
az22.pas:6: undeclared identifier `Y' (first use in this routine)
az22.pas:6: (Each undeclared identifier is reported only once
az22.pas:6: for each routine it appears in.)
az22.pas:7: warning: return value of function not assigned
*)
program az22(output);
function x:integer;forward;
procedure p;
function x(y:integer):integer;
begin
x:=y
end;
begin
end;
function x;
begin
x:=1
end;
begin
writeln('OK')
end.
(*
az23.pas: In main program:
az23.pas:3: parse error before `..'
az23.pas:5: parse error before `Else'
*)
program az23(output);
begin
if []=(..)
then writeln('OK')
else writeln('failed')
end.
Incorect programs - should not compile:
program az24(output);
begin
if 1.1 in [] then; (* WRONG - real is not an ordinal type *)
writeln('failed')
end.
program az25(output);
var real:real; (* WRONG - can't create new definition and use the old one *)
begin
writeln('failed')
end.
program az26(output);
begin
writeln('failed: ',1:2.3) (* WRONG - field width should be integer *)
end.
program az27(output);
begin
writeln('failed: ','xx':true) (* WRONG - field width should be integer *)
end.
program az28(output);
var i:integer;
begin
for i:=0 to nil do; (* WRONG - type of final value not compatible with integer *)
writeln('failed')
end.
program az29(output);
var f:file of file of char; (* WRONG - file type is an illegal component type *)
begin
writeln('failed')
end.
program az30(output,output); (* WRONG - program parameters are not distinct *)
begin
writeln('failed')
end.
program az31(output);
type t=record x:^r(* WRONG *)eal end;
begin
writeln('failed')
end.
program az32(output);
procedure q;forward; (* WRONG - no definition of procedure q *)
begin
writeln('failed')
end.
program az33(output);
begin
writeln('failed: ',3:2:1) (* WRONG - that form is only applicable to reals *)
end.
program az34(output);
function f:integer;
begin
f:=1
end;
procedure p(function f); (* WRONG - incorrect declaration of functional parameter *)
begin
end;
begin
writeln('failed')
end.
program az35(output);
var output:file of real;
begin
writeln('failed') (* WRONG - output is not of type "text" *)
end.
Programs demonstrating internal compiler error:
(*
d:\src\gcc-2.95.3-20010828\gcc\p\gpc-common.c:1390:build_pascal_binary_op: failed assertion `result'
az36.pas: In main program:
az36.pas:4: Internal compiler error.
*)
program az36(output);
begin
if 0 in ([]*[1])
then writeln('failed')
else writeln('OK')
end.
(*
az37.pas: In main program:
az37.pas:3: ISO Pascal requires an entire `for' variable
az37.pas:3: invalid operands to binary <=
az37.pas:3: invalid lvalue in assignment
az37.pas:3: Internal compiler error in `do_abort', at toplev.c:2301
*)
program az37(output);
begin
for char:=1 to 1 do; (* WRONG *)
writeln('failed')
end.
Programs crashing compiler:
program az38(output);
begin
if 1 in 1 then; (* WRONG *)
writeln('failed')
end.
program az39(output);
var s:set of boolean;
begin
s:=1; (* WRONG *)
writeln('failed')
end.
program az40(output);
procedure q(x:integer);forward;
procedure q;
begin
end;
function r; (* WRONG *)
begin
r:=1
end;
begin
writeln('failed')
end.
program az41(output);
var t:array [(a)] of integer;
begin
t[char]:=1; (* WRONG *)
writeln('failed')
end.
program az42(output);
const s=1;
type t=^s; (* WRONG *)
begin
writeln('failed')
end.
Finally, programs giving incorrect results:
program az43(output);
(* FLAG --classic-pascal *)
(* The reason, I'm including that option is that there may
be some dialect implemented by GNU Pascal, which does not
define the order of evaluation for parameters of "write".
ISO standards are clear about it *)
var a,b,c,d,x:integer;
f:text; (* Result is correct if you change that to
f:file of integer *)
function g(y:integer):integer;
begin
write(f,x*y);
x:=x+2;
g:=x+y;
end;
begin
rewrite(f);
x:=1;
write(f,g(3),g(1));
reset(f);
read(f,a,b,c,d);
if (a=3) and (b=6) and (c=3) and (d=6)
then writeln('OK')
else writeln('failed: ',a,b,c,d)
end.
program az44(output);
var x:integer;
function f:integer;
begin
f:=x;
x:=2
end;
begin
x:=1;
if [1]=[f]
then writeln('OK')
else writeln('failed')
end.
program az45(output);
var x:boolean;
function f:integer;
begin
f:=1;
x:=true
end;
begin
x:=false;
if 1 in [1,f] then
if x
then writeln('OK')
else writeln('failed')
end.