Apple
and Borland Pascals Compared
Neil
A Six, Raytheon Programmer
Apple and Borland
Pascals Compared
Updated:
04-16-01
My name is Neil A Six. I'm a programmer working at Raytheon (formerly Hughes) in Tucson, AZ. I had worked on a embedded project involving a proprietary Raytheon microprocessor, and when I began, no assembler for it was available to me. Having some experience in writing software tools, I undertook to write one, originally in ANSI C, thinking to maximize portability beyond the Macintosh I was using.
However, after I finished the initial version, and distributed it to a few places, I began thinking about its maintenance, and with C, that got my attention: C isn't very safe to maintain, and its lack of type checks bothered me! So I decided to rewrite it in CodeWarrior 7 Pascal (which I have a personal copy of). However, this version proved to be pretty buggy (especially its runtime library), which kind of defeated my purpose! I later discovered that Apple's Pascal was available free, along with MPW which it runs under. I decided to give it a try, and to my not great surprise, it was very stable and trustworthy (doubtlessly because its development pedigree dates back to 1981).
My assembler didn't seem to run any slower than its C version, even with runtime checks on, perhaps because it's I/O-intensive. I was able to generate the assembler as an MPW tool, which has certain advantages, especially scripting. I was utterly unable to get CodeWarrior Pascal to do the same - its Pascal runtime library doesn't mesh with the MPW tool library! I decided to focus thereafter on Apple Pascal, making sure that the code still compiled under CodeWarrior to keep my options open.
I left that project not long ago, and since then the developers after me began using Wintel as a development platform. I wanted to make the assembler available to them without abandoning the Macintosh version. After doing some initial investigation, and with the help of some orphaned Borland manuals, I discovered that it was much closer to Apple Pascal than I expected. I don't have the Borland 7 disks and it's not available free; however, I found a solution: TMT's Borland-compatible Pascal is available for free, and with its DOS extender, it runs under all Microsoft operating systems that I tried it on (plain DOS, Windows 3.1,95, and NT). Furthermore, I can run TMT Pascal under an old version of SoftWindows on my PowerMac.
The only problem is its rather useless runtime error messages, and that it compiles more slowly than Borland. I won't say that Pascal portability is as easy as with C, but with discipline, the differences can be mitigated. Later CodeWarrior versions probably fix the problems I had, and moreover, they support Win32 targeting too (but I understand that MetroWerks no longer supports Pascal).
The following is the information I gathered on the MPW Pascal (Apple) and Borland Pascal (Wintel) differences. Most of them pertain to CodeWarrior, too. In order to share source files between compilers, it is essential to exploit the a{b} keyword syntax, which allows easy porting between them if you have a stream editor like MPW StreamEdit or Unix sed.
NOTE: This may be of interest to those who want to make portable command-line applications (as I have done). GUI programmers probably won't care!
If anyone would like to contact me with regards to any of my research, or add to or correct the information provided here, please feel free to contact me. My e-mail address is nasix@west.raytheon.com.
| UCSD-style units |
| Can declare constants using expressions |
| Objects (differences not yet verified) |
| @ prefix operator |
| Hex constants |
| Single, Double, Comp, Extended real types |
| LongInt, MaxLongInt |
| String type & its subroutines |
| MemAvail,IOResult,FillChar,Seek,Sizeof subroutines |
| Variable typecasts |
| I,R,D directives |
| Apple | Borland | Comment |
| otherwise | else | |
| cycle | continue | Borland v. 7 predefined ident |
| leave | break | Borland v. 7 predefined ident |
| PLFilePos | FilePos | |
| PLFlush | Flush | |
| PLCrunch | Truncate | |
| MoveLeft MoveRight |
Move | Borland handles overlapping regions |
| ord4 | ord | Apple ord yields Integer unless param already pointer or LongInt. Borland rejects pointer parameter |
| Huge integer consts considered real |
rejected | Append ".0" to resolve |
To mitigate above differences, use a{b} syntax so stream-editing script can change to b{a} and back, where a is Apple name and b is Borland equivalent.
| Apple | Borland | Solution |
| BSL,BSR | infix shl,shr | Define for Borland |
| BAnd,BOr,BXor,BNot | infix and,or,xor,not | Define unique functions, since Apple integer params are zero-extended.BNot(x) = -1 - x |
| HiWrd,LoWrd,Inf,NaN | none | Define for Borland |
| none | Upcase,Lo,Hi,Int,Frac | Define for Apple |
| none | Randomize,Random(int) | Define for Apple (using QuickDraw Random & qd.randSeed) |
| Toolbox units | none | Define for Borland when possible - e.g., SANE,TextUtils. |
| Apple | Borland | Comment |
| none | Unit initialization | Best practice is to define initialization subroutine, even for trivial data structures. |
| none | Variable initializers | |
| Leading hex zeroes significant | insignificant | E.g., $8000 = -32768 (Apple), 32768 (Borland) |
| predefined types ShortInt,Byte,Word |
Simulate or avoid altogether | |
| Can index a string literal | can't | E.g., 'ABCD'[3] = 'C' |
| Forwards need subprogram prototype 1st time | both times | |
| Packs to bit level | byte level | Borland ignores packed |
| Pointer | Ptr | Pointer has a LongInt param, yields 32-bit pointer. Ptr has segment & offset integer params, yields 20-bit pointer |
| NewPtr,DisposePtr | GetMem,FreeMem | Apple Memory functions; Borland subroutines |
| Mark/Release,Get/Put,ScanEq/ScanNe | none | Mark/Release supported in Borland v. 7 predecessors |
| 2040 max set elements | 256 max set elements | |
OV+ directive, -ov option |
Q+ directive, /$Q+ option |
Overflow-check enable Borland v. 7 predecessors lack Q directive |
| Longint multiply always unchecked | Checked based on Q directive | |
| infix &,| or SC+ directive | B- directive | Avoid requiring short-circuit evaluation |
| Open,Rewrite,Reset with filename | Assign |
Portable sequence: Open{Assign}(f,str); Rewrite(f)
or
Reset{Assign}(f,str); Reset(f)
|
| BlockRead,BlockWrite functions | procedures | |
| diagnostic | none | Diagnostic defined in unit IntEnv. NT & Unix, but not DOS, have stderr analogous to diagnostic |
| Unit IntEnv ArgC,ArgV | ParamCount,ParamStr | |
| IFC NOT UNDEFINED/ELSEC/ENDC | IFDEF/ELSE/ENDIF | Conditional compilation |