21-Feb-86 19:21:23-PST,6723;000000000001 Return-Path: Received: from ucbvax.berkeley.edu by SUMEX-AIM.ARPA with TCP; Fri 21 Feb 86 19:21:00-PST Received: by ucbvax.berkeley.edu (5.45/1.9) id AA02188; Fri, 21 Feb 86 17:30:14 PST Received: from ucblapis.Berkeley.Edu (ucblapis.ARPA) by ucbjade.Berkeley.Edu (4.19/4.41.3) id AA17260; Fri, 21 Feb 86 13:05:47 pst Received: by ucblapis.Berkeley.Edu (4.19/4.41) id AA08756; Fri, 21 Feb 86 12:03:57 pst Date: Fri, 21 Feb 86 12:03:57 pst From: oster%ucblapis@BERKELEY.EDU Message-Id: <8602212003.AA08756@ucblapis.Berkeley.Edu> To: info-mac@sumex-aim.arpa Subject: T.M.L. review and bug workaround I like and use T.M.L. Pascal. The price to value ratio can't be beat. I've found it quite compatible with Lisa Pascal, and it is such a pleasure to get out of the stupid Lisa environment. Also, unlike C, I get strict type checking of pointers and the ability to pass procedures to the ROM without a lot of in-line assembly language or glue routines. (And, unlike C, Inside Mac directly applies!) (Please, no flames, It's just I find C without lint or make to be pretty undebuggable. (This is solely a reflection on MY abilities as a programmer.)) Since the compiler generates .Rel files directly, by default, (though it will generate .Asm on request), the compilation is faster than with compilers that can only generate .Asm files. { --- --- --- --- } Incompatibilities: A.) No support for separate compiliation -- this is by far the worst thing about the compiler. To create a seperately compiled unit, basically, you must 1.) ask the compiler to generate an .Asm file instead of its normal .Rel, 2.) edit the .Asm file to remove global entrypoints you don't want (such as the one for the program starting address) 3.) compile it with the MDS assembler. 4.) Then edit the Pascal source code for the unity to create a .iPas file of external declarations to be included in everything that uses the unit. this .iPas file should also incude a {$U file} directive so that the .Link file produced by compilation will include a reference to the compiled code. The good part of all this labor is that you really think about your code before you undertake to break it up. You wind up writing managers, in the style of the Mac managers. B.) In Lisa Pascal, INLINEs may be as long as you like. In T.M.L. INLINEs must be 2 bytes long. C.) Although you can create pointers to procedures, you can't execute them. The following two files are a work around for this. They define a function, Apply, that takes a collection of arguments and a ProcPtr and applies the ProcPtr to the arguments. Since Pascal does not allow Variadic functions, you need a different version of Apply for each class of use. So, I predefine a .Rel file that has Apply0 to Apply9 defined, and add Pascal declarations to the .iPas file as I need them. Sure made writing QuickSort easier!. { --- --- CUT HERE --- --- } ;File: Apply.Asm ;Author: David Phillip Oster ;Date: 12/25/85 ;Purpose: Provide the glue by which TML Pascal can use PorcPtrs. ;Distribution: This file is in the public domain. XDEF Apply0 XDEF Apply1 XDEF Apply2 XDEF Apply3 XDEF Apply4 XDEF Apply5 XDEF Apply6 XDEF Apply7 XDEF Apply8 XDEF Apply9 Apply0: Apply1: Apply2: Apply3: Apply4: Apply5: Apply6: Apply7: Apply8: Apply9: MOVE.L (SP)+,A0 ;Pop Return Address MOVE.L (SP)+,A1 ;Pop Last argument, i.e., ProcPtr MOVE.L A0,-(SP) ;Push Return Address JMP (A1) ;Dispatch to ProcPtr { --- --- CUT HERE --- --- } {$U Apply } { Author: David Phillip Oster Date: 12/25/85 Title: Apply.iPas Distribution: This file is in the public domain. ************** TML Pascal does not support procedures to functions, but this takes a procPtr as a last argument, and applies it to previous arguments. Since it cannot be written in Pascal, it is in Assembly. This is the interface file. ************** Declare new versions of Apply as required! (The procPtr must be the last argument!) ************** } FUNCTION Apply0(a, b:Ptr; Func:ProcPtr) : Boolean; EXTERNAL; PROCEDURE Apply1(a : WindowPtr; Func:ProcPtr); EXTERNAL; FUNCTION Apply2(a : StringPtr; Func : ProcPtr) : Char; EXTERNAL; FUNCTION Apply3(s : Str255; Func:ProcPtr) : Boolean; EXTERNAL; { Apply4 Apply5 Apply6 Apply7 Apply8 Apply9 } { --- --- CUT HERE --- --- } { --- --- --- --- } { Bug1. According to the pascal standard, you should be able to assign to a function name from inside an inner procedure. Not allowed in TML.} FUNCTION F(x : Integer) : Integer; PROCEDURE FInner(y : Integer); BEGIN F := y; {should be legal, isn't } END; { of FInner } BEGIN Finner(x+1); END; { the following is a work around } VAR FResult : Integer; { thank God you can mix VARs and PROCs ! } FUNCTION F(x : Integer) : Integer; PROCEDURE FInner(y : Integer); BEGIN FResult := y; {should be legal, isn't } END; { of FInner } BEGIN Finner(x+1); F := FResult; END; { --- --- --- --- } {Bug 2. The following is a compatibility bug in TML pascal: T.M.L. appears to pack solitary byte sized elements of structures differently from Lisa Pascal. Example: {'Style' is defined as a set in QuickDraw.iPas: StyleItem = (bold,italic,underline,outline,shadow,condense,extend); Style = SET OF StyleItem; Lisa Pascal, (and therefore, the mac ROM), has it taking one byte. followed by a filler byte in the def of a grafport: txFont: INTEGER; txFace: Style; txMode: INTEGER; In T.M.L. you get the filler first! If you say: "SetFace([outline])"; then: "Ord(thePort^.txStyle) = 0" will be true in T.M.L. The work around is to say: TYPE MyStyle : SignedByte; { 8 bit type in Lisa Pascal } ... txFont: INTEGER; mytxFace: MyStyle; txFiller : SignedByte; txMode: INTEGER; ... PROCEDURE MyTextFace(v : Integer); INLINE $A888; { * * * * * * } Now, when you say: SetFace([outline]) then "Ord(thePort^.myTxFace) <> 0" will be true. { --- --- --- --- } Errors in preceding review: unlike the claim in review a few days ago: For the type Str255 (which is used uniformly by Inside Mac, for almost all strings), Str[n] := Chr(13) works just fine, { --- --- --- --- } Conclusion: I've written programs for the Mac in Consualire C, in Aztec C, in MDS Assembler, in ExperLisp, in Portable Standard Lisp, in Xlisp, in MacPascal, in MacForth, in Forth-83, and in Lisa Pascal. My favorite language for development on the Mac is T.M.L.