Trailing-Edge - PDP-10 Archives - decuslib20-01 - decus/20-0003/pascal.bwr
There are 5 other files named pascal.bwr in the archive. Click here to see a list.
Rachel Schwab at NIH has kindly run A.H.J. Sale's Pascal Validation
Suite for me.  There are 4 kinds of tests:
  conformance - see if a correct program works
  deviance - see if an incorrect program is detected
  error check - see if runtime checks work
  quality - see how well the compiler handles things where the
	implementor has the option of being cheap

I am starting on conformance tests, as these seem the most crucial.
The summary states that of 137 tests, there were 21 failures.  I am
going to list the failures.  Some of these should just be taken as
warnings that until I fix them, the things shown will not work.
In other cases I am looking for advice.

6.2.2-3   Arthur Sales' favorite bug:  
	      type T=foo;
	      procedure x;
	        type X=^T;
	  X ends up defined as ^foo when it should be ^bar.  this is
	  because the compiler is a bit too much one-pass.  This is
	  fixable, and I will fix it.  Note that the problem is the
	  fact that T was defined at an outer block level.  Had the
	  T=foo not been there, x=^T would have been recognized as
	  a forward reference and handled properly.

6.2.2-8   Assignment to a function works only at the top level of
	  the function.  It should also work within any functions
	  declared within that function.  I guess I agree with that.
	  This should be easy to fix, if everyone agrees with Sales'
	  interpretation of the language spec.
		FIXED and    Compiler ill mem ref's when compiling
	some degenerate record declaration.  Probably a null record
	declaration.  This should be easy to fix.
		FIXED    Supposedly the compiler failed when asked to compile
	file of a pointer type.  I claim that the test is erroneous.
	First, it is not clear to me what a file of pointers is.
	But more important, they have FILE OF X, where X is a local
	variable.  I have tried a simple test using FILE OF ^INTEGER,
	and it seems to work (though I am still not sure what it
		ERROR IN TEST   This is the first of several tests that fail because of
	the way EOLN is handled.  In the Revised Report, when you
	reach the end of line on INPUT, INPUT^ is supposed to contain
	a blank, and GET(INPUT) will get the first char of the next
	line.  In this implementation, INPUT^ contains <cr>, <lf>, or
	whatever.  And if the end of line is <cr>,<lf>, it takes two
	GET's to get to the next line.  However a single READLN will
	still work. Other tests that fail because of my current end of
	line processing will simply refer to "the EOLN problem".

6.5.1-1  Arrays of files are not allowed nor are files allowed to be
	items in a record.
		FIXED. and   These two tests purport to test what goes
	on when you pass procedures as parameters to other procedures.
	Unfortunately they assume a non-standard syntax for procedure
	declarations in this case (the syntax in the ISO proposal 
	rather than in the Revised Report).  As far as I know, our
	system would handle their test properly if the syntax was
	fixed.  Eventually I will probably adopt the ISO syntax also.
		TEST BASED ON ISO    This program does RESET(FYLE), where FYLE is a local
	variable (i.e. not mentioned in the program statement), and
	no REWRITE has ever been done to the file.  My Pascal
	distinguishes between empty files and files that do not
	exist at all.  This test wants the file to be treated as
	empty, i.e. the RESET works but you get EOF(FYLE).  Instead
	my runtime system complains that you have tried to open
	a non-existent file "DSK:FYLE.", and prompts for a new file
	name (at least I hope that is what it did - Rachel didn't
	say exactly what happened).  Clearly my intepretation is a
	remnant of thinking of FILE's in Pascal as operating system
	files, rather than as abstract sequence variables.  For my
	purposes my interpretation is more useful.  However I agree
	with Sales that the language seems to imply the other
	interpretation.  I seem to have the following choices:
	   - another {$... kludge
	   - another optional extra parameter to RESET
	   - ignore the Pascal spec
	I regard the abstract sequence interpretation as a nightmare
	and propose to ignore this problem.
		FIXED for internal files.  For external files
		it seems most likely that this is a user error,
		and you are still prompted for a new file name.

6.6.2-3   Some undetermined error with EXP, apparently a bad value
	returned.  Unless my real number scanner is doing something
	bad, this seems to imply a precision problem of some sort
	in the underlying routine.  Since EXP calls the Fortran
	library function, this would be DEC's problem.  they are
	redoing the whole Fortran library because of precision
	problems, so I will tentatively say this is being taken care
	of.  (But I will check to make sure it is really Fortran's
		UNKNOWN, probably not a problem   Compiler does not handle a sparse CASE statement.  I
	believe this has been fixed since.
		FIXED   FOR I := 1 TO MAXINT causes overflow the last time
	through.  This is a monster.  Currently this loop is
	   i := 1;
	   while i <= maxint do
	     i := i + 1
	So clearly the last time through the loop the program
	tries to compute maxint+1 and overflows.  The problem is
	that the Revised Report clearly states that a FOR loop
	is equivalent to
	   i := start; S; i := i+1; S; i:= i+1; S; ... i := end; S;
	That is, I is NOT incremented after the final occurence
	of the body.  Indeed it seems that according to the Revised
	Report the value of I at the end of the loop is well-defined
	if end >= start  (I would be left equal to END), and that the
	whole construction is illdefined otherwise.  This conflicts
	with the User's Guide (which is bound in the same volume),
	which states explicitly that if end < start, the FOR 
	statement is not executed (presumably this means that
	I is unchanged, and that the sideeffects of any functions
	called while evaluating START and END are undone), and
	that if the FOR loop is normally exited, the value of I is
	undefined.  So one has a generally ill-defined mess here.

	My initial inclination is to change things as follows:
	   for i := m to n do P:
		move t,m
		movem t,i
	loop:	aos i
		move t,i
		camge t,n
		jrst loop
	This would leave I set to M if the loop never gets done
	(N < M), and set to N otherwise.  The overflow when N
	is MAXINT would not occur.  The problem with this change
	is that I know that I have code that depends upon the
	fact that I is now left at N+1 after a normal exit from
	the loop.  I fear that other users do, too.  And worse,
	that the compiler may.  Changing this is likely to result
	in subtle problems showing up in the compiler and many
	other Pascal programs.  The question is, is the cure
	worse than the disease in this case?  Note that it is not
	really fair to use MAXINT in conformance tests, since the
	Report doesn't even define MAXINT.  Nor as far as I can
	see do they ever state what is supposed to happen when
	integer arithmetic overflows.  It is nearly hopeless to
	get a really clean result on the PDP-10, so overflow
	with negative numbers happens at -MAXINT-1, not -MAXINT
	(because of 2's complement arithmetic).  I suspect that
	Sales is being a bit too literal-minded about the
	definition of FOR here.
		COMPLEX, probably not worth fixing.  [probably
		based on ISO, too]

6.9.1-1 and 6.9.3-1    EOLN problem

6.9.4-3, 6.9.4-4, 6.9.4-7, and 6.9.5-1   These tests check what
	is written by WRITE applied to integers, reals,
	Booleans, and WRITELN.  To check exactly what is 
	written, they read the string back into a packed array
	of char, and then look at it.  Alas, since standard
	Pascal can't read into strings, they use code like
	   for i := 1 to 10 do
	Now the problem with this is the B is a packed array.
	According to the Revised Report, it is illegal to pass
	an element of a packed array to a procedure by reference.
	It seems that this is exactly what is being done, and
	the compiler refuses it.  The problem, of course, is that
	call by reference is done by passing an address, and
	there is no address to pass for an object in the middle
	of a packed array.  (They could have passed a byte pointer,
	but then procedures taking reference parameters would have
	to assume that all of its parameters are byte pointers,
	which would slow things down.)  Now we could certainly
	change the implementation such that READ is not implemented
	by passing the address of B[I].  Instead the internal
	routines could be made into functions, and the compiler
	could retrieve the returned value and assign it.  The
	compiler could then do the deposit byte into packed
	structures.  But I guess I think that what they have done
	is in fact illegal Pascal, and I don't know how much
	trouble I want to go to to make it work.
		FIXED (i.e. you can now read into packed objects)
	Rachel tells me that some of these tests still don't work.
	I have checked Jensen and Wirth, and think that WRITE
	does what it says.  I conjecture that these tests are
		TEST BASED ON ISO [or Sales interpretation]

6.9.4-15   I will have to look into this.  Rachel seems to have
	mistyped something.  But what it looks like is that if
	you do WRITE(X), where X is not a file (i.e. you default
	the output file name), you get the current definition
	of OUTPUT.  That is, if you have a local variable called
	OUTPUT, that is what you get.  According to the Revised
	Report, when you default the file name you get the
	standard file OUTPUT, not whatever local definition may
	be in effect.  This should be easy to fix, and I will
	fix it.

Other problems not showing up in the validation suite:

READ and WRITE are not implemented for non-TEXT files.  READ(f,x)
	should be equivalent to x := f^; get(f) in this case.

The funny pseudo-type POINTER cannot be passed by reference.
The code clearly does not intended to distinguish between call
by ref and call by value for these pseudo-types.  There is a
history of sufficient subtlety that I don't dare change this
right before a major release of the system.

Upper and lower case letters are treated as the same in sets
		COMPLEX - will not be fixed soon

Only 5 parameters can be passed to a parametric procedure.
The problem here is the with Jensen and Wirth's parametric
procedures, one can't verify at compile time that the
number of parameters the user has passed is right.  One
could do it at runtime, but special machinery would be
needed.  If the user gets it wrong, the stack will be blown,
and nobody (probably even PASDDT) will know what is going on.
I decided to be safe by only allowing the number of args
that will fit into the AC's.  Then if he blows it, nothing
serious will be wrong.  This whole problem will go away
when the ISO standard is adopted and I implement it, since
one will be able to check arguments at compile time.
		COMPLEX - will not be fixed soon

It is not possible to read the smallest negative integer.
This will never show up on a validation test, since I
can read -MAXINT.
		COMPLEX - requires rewriting integer read,
		which will not be done soon