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.