Adriaan van Os wrote:
Frank Heckenbach wrote:
Adriaan van Os wrote:
Some more in Apple UCSD Pascal (just for the record)
- A compilation can be a program, or one or more units separated
with semicolons and ending with a period.
Several units separated with semicolons? Strange. Kind of contradicts the meaning of "unit" (in the common meaning of the word) to me ...
There will have been pragmatic reasons for it, way back in 1980. With 64 or 128 Kbyte memory you need a lot of segmentation and chaining, therefore small units. There was no --automake feature.
But why couldn't they be in separate files (or at least in one file without special syntax, i.e. `unit Foo ... end. unti Bar ... end.', like GPC used to allow)? Without automake, this should have been better, since one would have been able to compile just some of the units, not everything if everything is in one file.
(Or, actually, I think they should have separated implementation details like segmentation from the logical unit structure, i.e. allow segmentation on a smaller than unit basis.)
- File type INTERACTIVE
What difference does it make?
I suppose we can ignore the difference, since GPC does lazy input, anyway. So `type Interactive = Text;' might suffice.
- Predefined file KEYBOARD
GPC provides `Kbd' in the unit `Turbo3' (BP compatibility for Turbo Pascal 3.0 compatibility). Does it behave the same?
"The difference between INPUT and KEYBOARD is that when INPUT is used to refer to the keyboard, the typed characters are automatically displayed on the screen; when KEYBOARD is used, the characters are not automatically displayed." [1, page 12]
I take this as a yes.
- INTEGER type can be modified by a length attribute
Well, we have the `Size' attribute (probably different syntax, but the semantics might be the same?).
The 'Size' attribute denotes the number of decimal digits (BCD), not the number of bits.
" TYPE BIGNUM = INTEGER[ 12] VAR FATS: INTEGER[ 25];
This defines BIGNUM as a type which can have any integer value requiring not more than 12 decimal digits. FATS can have any integer value requiring not more than 25 digits. The length attribute can be any unsigned INTEGER constant up to and including 36." [1, page 19].
Again, if we have 128 bit integers someday, we could implement it (though binary, not BCD, but it shouldn't matter) -- though I don't like the syntax, of course ...
- LONG INTEGER type, represented internally as a binary-coded
decimal (BCD) number (up to 36 digits)
Nice. :-( I guess when GCC will support 128 bit integers, we can declare it as such (or the exact subrange), since the internal representation shouldn't matter.
Because integer values are "discrete" numbers. In non-BCD floating point you have the problem that you cannot even represent something simple like 2 euro 13 exactly (which is a horror for accounting applications).
I know, but that's nothing to do with BCD, just integer (or fixed point) vs. floating point. I always use standard (binary) integers for monetary amounts (in cents).
GPC supports 64 bit integers. This suffices for 10^17 Euro (or $) -- probably enough for most country's debts for the next few years. ;-)
So if that's the purpose, it might be enough to use LongestInt.
- Built-in functions UNITREAD, UNITBUSY, UNITWAIT and UNITCLEAR
The UNITxxx routines provide hardware-oriented low-level IO. "They allow a Pascal program to transfer a specified number of consecutive bytes between memory and a device. They are not controlled by filenames, directories, etc., but merely use device numbers and (for diskette drives) block numbers." [1, page 26]
Back in those good old times, there were no security issues, you simply had full control ! You could destroy everything or do wonderful things with it, like copying MS-DOS diskettes on an Apple IIgs !
procedure UNITREAD( UNITNUMBER, ARRAY, LENGTH [, [BLOCKNUMBER] [, MODE]] ) procedure UNITWRITE( UNITNUMBER, ARRAY, LENGTH [, [BLOCKNUMBER] [, MODE]] ) function UNITBUSY: boolean {always returns FALSE on the Apple II} procedure UNITCLEAR( UNITNUMBER)
If someone is interested, I can provide more details.
Well, under Unix they could be implemented by direct access to the devices (of course, this will work only for root or another special user with access permissions). Under Dos, anyway, and under Windows probably, too. So they could be done like the uglier routines of the BP-compatible `Dos' unit (probably also with appropriate conditionals).
SCAN( LIMIT, PEXPR, SOURCE)
PEXPR is a "partial expression" which specifies the target of the scan. PEXPR takes one of the following forms:
= CH <> CH
You mean `Scan (42, <> 'A', Foo)'???
<rant subject="syntax" level="200%"> ...
Oh dear, I'm quite shocked. Why do people make up such strange things? They could easily have made two separate routines (say `ScanEQ' and `ScanNE' -- this might be what can be implemented reasonably in GPC, with different syntax (*)) -- it would have taken them just one more predefined identifier instead of a completely irregular new syntax rule ...
What do they do? Can they be provided in a unit?
No problem for PWROFTEN, TREESEARCH
For TreeSearch with an untyped parameter and type-casting (which will be just as unsafe as the UCSD function).
(*) Just a thought. Perhaps the syntax could be handled with more-advanced preprocessor features, in particular string handling. Something like:
{$define Scan(A, B, C) {$if MacroIsPrefix (<>, MacroTrim (B))} ScanNE (A, MacroRemovePrefix (<>, MacroTrim (B)), C) {$else} ScanEQ (A, MacroRemovePrefix (=, MacroTrim (B)), C) {$endif} }
Such features are not present now, but it might be rather easy to add them to the new preprocessor. Of course, for this strange UCSD function, that's probably overkill, but that's not the only strange syntax we've seen recently.
Perhaps we'd have to see how far we'd get (and which preprocessor features would be required), but if it helps to keep a substantial amount of those strange syntaxes out of the actual compiler, I'd be inclined to strengthen the preprocessor (though I haven't advocated the use of macros in general) ...
Frank