Difference between revisions of "Mode MacPas"

From Lazarus wiki
Jump to navigationJump to search
(More MacPas constructs added)
 
(72 intermediate revisions by 14 users not shown)
Line 1: Line 1:
Mode MacPas tries to be compatible with the Pascal dialects commonly used on Macintosh, that is Think Pascal, Metrowerks Pascal, MPW Pascal.
+
{{Mode_MacPas}}
  
==Extensions to Free Pascal==
+
Mode MacPas tries to be compatible with the Pascal dialects commonly used on [[:Category:Mac OS Classic|Macintosh]], that is [[THINK Pascal]], [[Metrowerks Pascal]] and [[MPW Pascal]]. For tips on porting from traditional [[Mac Pascal]] compiler to [[Free Pascal]], see [[Porting from Mac Pascal]]
Compiler variables is currently equivalent to what is called macro in fpc/turbo/delphi terminology. They might be separated in the future (for mode macpas), to correspond better with the mac world.
 
  
* $SETC <compvar>:= <expr> -- sets a compiler variable's value to an expression. ":=" as well as "=" are allowed. If not already defined it's defined.
+
==Differences compared to standard Free Pascal==
 +
Here differences between the Macintosh dialect  of Pascal and the standard dialect of Free Pascal (which is Turbo Pascal) are listed.
 +
 
 +
===Implemented (in 2.0.2)===
 +
* The file extension .p is supported, in mode MacPas.
 +
* The unit MacPas.pp is automatically included whenever mode MacPas is used. It should contain such stuff that is normally built in into Mac Pascal compiler.
 +
* $CALLING MWPASCAL Tells the compiler to use calling conventions according to Metrowerks Pascal. The only difference to the default is that, in MWPASCAL, CONST record parameters are always passed by reference.
 +
* Type checking of compile time expression (actually this is not MacPas specific)
 +
* Compile time variable can be given on the command line, syntax -dMYCOMPVAR:=3 or -dMYCOMPVAR2:=TRUE (no spaces). Hexadecimal values are not supported, though.
 +
 
 +
====Compile time constructs====
 +
* Compile time variables are now different from macros. However, they are related. In the FPC documentation, what is written about macros, is often also valid for compile time variables. The difference is that macro substitution is only done with real macros (which are defined by $DEFINEC). Compile time variables on the other hand are defined by $SETC.
 +
* Exportable compile time variables/macros. Compile time variables and macros defined in the interface part of a unit are exported to other MACPAS units, in the same manner as ordinary Pascal constructs. See more below under '''Exportable macros'''.
 +
* Compile time variables may be assigned to hexadecimal numbers, like $2345.
 +
* $SETC <compvar>:= <expr> -- sets a compiler variable's value to an expression. ":=" as well as "=" are allowed. If not already defined, it is defined.
 +
* $DEFINEC <macro> <content> defines a macro <macro>, whose substitution text is <content>. -- as its counterpart $DEFINE. Parameterised macros are not supported.
 
* $IFC, $ELSEC, $ENDC -- as their counterparts $IF, $ELSE, $END
 
* $IFC, $ELSEC, $ENDC -- as their counterparts $IF, $ELSE, $END
 +
* $ERRORC directive, similar to $ERROR
 
* UNDEFINED <compvar> -- in compiler variable expressions
 
* UNDEFINED <compvar> -- in compiler variable expressions
 +
* Compile time function OPTION(X), which returns, whether the compiler option X is set. Works for one letter options only.
 
* TRUE, FALSE -- as values in compiler variable expressions
 
* TRUE, FALSE -- as values in compiler variable expressions
* compiler variables may be assigned hexadecimal numbers, like $2345
+
* Compiler directive $PUSH and $POP, which saves/restores the current state of all local compiler switches.
* UNIV modifer for types in parameter lists is accepted, but does nothing.
+
* Compiler option $J makes a variable external
 +
* Compiler option $Z makes variables and procedures externally visible
 +
* Compiler option $OV (+/-) sets overflow checking (FPC 2.5.1)
 +
* $ALIGN MAC68K, POWER, RESET (also POWERPC as equivalent of POWER in FPC 2.5.1)
 +
* Compiler directive LibExport is recognized, but does nothing at the moment. It may be implemented in the future.
 +
* Metrowerks compiler directive $UNDEFC and $ELIFC
 +
* Metrowerks compile time expression DEFINED <compvar>
 +
* Support for some Turbo/Delphi compiler directives as well, $DEFINE $UNDEF $IFDEF $IFNDEF $IF $ELSE $ENDIF $ELSEIF
 +
 
 +
====Language====
 +
* Object Pascal, Mac style. New, Dispose, Member are supported.
 +
* A procedure passed as parameter can be directly declared in the formal parameter list (anonymous procedure types).
 +
* OTHERWISE in case constructs (actually it was already supported even for Turbo Pascal)
 +
* Procedure Leave does the same as Break
 +
* Procedure Cycle does the same as Continue
 +
* Procedure Exit(<procname>), which works like Exit, but accepts the procname as parameter. <procname> must be the name of the procedure, in which Exit is used in. Non-local exit (as allowed in some Mac pascal implementations) is not allowed. Exit with return value as a parameter is not allowed. You can use "return <exit_value>;" though, as in Metrowerks Pascal.
 +
* Operators | and & (boolean operators, which are always evaluated as short-circuit boolean expressions)
 +
* UNIV modifier for types in parameter lists is accepted, but does nothing (update, it has been implemented in FPC 2.5.1)
 
* C directive for procedure declarations. Same as CDECL.
 
* C directive for procedure declarations. Same as CDECL.
* ... in procedure declaration, denoting a C var arg style funtion.
+
* "..." in procedure declaration, denoting a C var arg style function.
* IMPLEMENTATION is not needed in units if empty.
+
* IMPLEMENTATION is not needed in units, if empty.
* Procedures declared in the interface section which do not have a counterpart in the implementation section is considered external (we call them implicit external)
+
* External directive
* $ALIGN MAC68K, POWER, RESET
+
* Procedures declared in the interface section, which do not have a counterpart in the implementation section, are considered external (we call them implicit externals). Their external name is prefixed with the C_prefix of the target. On Mac OS this is an empty string, whereas on Darwin/macOS it is an underscore, so that it will properly link with macOS' libraries (which are compiled with gcc).
 +
* Ord function can take a pointer as argument
 +
* Use of FourCharCode ( e. g. OSType, ResType) constants directly as parameters. This is done by an overloaded assignment operator defined in the file MacPas.pp
 +
* Ord4
 +
* All kinds of procedure variable stuff, compatible with Think Pascal and Metrowerks Pascal.
  
New 2004-07-05:
+
===Implemented (in 2.1.1)===
* In Mode MacPas, files may have the extension .p.
+
* return <value>
* Compiler directive $PUSH and $POP which saves/restores the current state of all local compiler switches.
+
* compile time expressions are now short circuit evaluated
* Function Exit(procname) which work like Exit, but accept the procname as parameter. Procname must be the name of the procedure in which Exit is used in. Non-local exit (as allowed in some mac pascal implementations is not allowed)
+
* Bit-level packing of records and arrays
* Function Leave, does the same as Break
+
 
* Function Cycle, does the same as Continue
+
===Planned===
* Operator |�same as boolean OR, & same as boolean AND.
+
* Nested procedure parameters (allowing a nested procedure to be actual parameter to another procedure) (update, it has been implemented in FPC 2.5.1)
* $ERRORC directive, similar to $ERROR
+
* Propagating uses
 +
* Open (for files)
 +
* HiWrd, LoWrd (since supported in both Think Pascal and Metrowerks)
 +
 
 +
===Not Supported===
 +
Here is an (incomplete) list of mac pascal constructs which are not supported in mode mac at the moment, perhaps some of them will be supported in the future:
  
New 2004-07-15:
+
* StringOf
* Compiler directive $J makes a variable external
+
* HiWord, LoWord (same as HiWrd, LoWrd)
* Compiler directive $Z makes variables and procedures externally visible
+
* Implicit forward declaration of objects (In an object declaration, one cannot refer to an object not yet declared)
* External directive after a procedure declaration
+
* In object declarations, the method name cannot be preceded with the class name (as in Think Pascal)
* Ord function can take a pointer as argument
+
* Arithmetic compiler variable expressions
 +
* Goto between different nesting levels (e.g., no goto from a nested procedure to a parent procedure)
 +
* Exit between different nesting levels.
 +
* Working implementation of UNIV keyword (update, it has been implemented in fpc 2.5.1)
  
...more will be added
+
===Free Pascal constructs allowed in Mode MacPas===
 +
Free Pascal constructs which currently are allowed in Mode MacPas, but which actually are not in the Macintosh dialect. If conflicts arises, some of them might be disallowed in future. Traditionally some of this functionality has been offered through Apple's Universal Interfaces. The list is not complete.
  
==Not Supported==
+
* [[Assign]](filename, file). In Macintosh Pascal the file name is given as an (optional) parameter directly to Reset(file, filename), Rewrite(file, filename) or Open(file, filename) (Open do open for both reading and writing).
Here is an (incomplete) list of mac pascal constructs which are not supported at the moment, some of them will hopefully be supported in the future:
+
* Bitwise operators "shr". "shl", "and", "or", "not"  etc. In Macintosh Pascal the functions BSR, BSL, BAND, BOR, BNOT are used instead. (Boolean operators "and", "or", "not" is of course allowed in Macintosh Pascal)
 +
* [[Assigned|Assigned(pointer)]]. An alternative is "pointer <> nil".
 +
* Append, Blockread, BlockWrite, Erase (delete files from disk), Filesize, Flush, Rename, SeekEof, SeekEoln, SetTextBuf, Truncate.
 +
* [[Addr]], Compare*, *Seg, Fill*, Freemem, Getmem, High, Low, [[move|Move]], MoveChar0, Ofs, Ptr (Note: In Apple's Universal Interfaces, Ptr is a datatype describing a generic pointer) , ReAllocMem, Release.
 +
* Hi, Lo. For conversion to 16 bit integers, in Macintosh Pascal you can use HiWord, LoWord. Note that Hi/Lo work on 64, 32 and 16 bit integers and return the upper/lower 32/16/8 bits depending on the argument.
 +
* [[Int]]
 +
* BinStr, HexStr, OctStr, SetLength, SetString, StringOfChar, [[Val]], [[Str]]
 +
* ChDir, GetDir, MkDir, RmDir, [[RunError|Runerror]]
 +
* Paramcount, Paramstr (since classic Mac OS does not have command line interface)
 +
* Halt (param). Halt without parameter works in Macintosh Pascal.
 +
* [[assert|Assert]]
 +
* Exclude, Include (for sets)
 +
* LongJmp, SetJmp (exists in Metrowerks but not Think)
 +
* Direct pointer arithmetics. In Macintosh Pascal, you must cast pointers to numbers before doing arithmetics.
  
* A nested procedure cannot be an actual parameter to a procedure.
+
==Exportable macros==
* No anonymous procedure types in formal parameters.
+
Only a mode MacPas unit will export macros and only a mode MacPas unit will import them. As before, MacPas and non-MacPas units can be used by each other but macros will then not be visible for use.
* No propagating uses
 
* Compiler directives defined in the interface are not exported
 
* No arithmetic compiler variable expressions
 
  
==Compiling Apple's Universal Headers==
+
Macros will start to be exported right after the {$MODE MACPAS} directive. If no such directive is given, but -Mmacpas is given on the command line, macros will start to be exported right after the UNIT keyword.
The work to make Universal Headers 3.4 compile by FPC is on the way. It is possible to compile all units normally used in a traditionally classic MacOS application, except for unit fp.p. Unfortunatelly at the moment, unit Carbon.p does not compile, since it depends on fp.p..
 
  
But the following info about FPC must be added in ConditionalMacros.p, please add it above the MPW Pascal section. An <tt>{$ENDC}</tt>  must be added at the end of the compiler description sections.
+
To support this, for a unit, {$MODE MACPAS} if forbidden after the UNIT keyword. For other mode switches it is like before.
  
<tt>
+
Caveat 1: If {$MODE MACPAS} is given before UNIT, the macros defined between this point and UNIT is exported, if the unit is compiled as part of a program or other unit, but is not exported if the unit is compiled from the commandline (at top level). To be deterministic, do not put macros before UNIT.
{$IFC NOT UNDEFINED FPC}
 
    {
 
        Free Pascal Compiler, an open source compiler,
 
        see http://www.freepascal.org
 
    }
 
    {$SETC TARGET_CPU_PPC              := NOT UNDEFINED CPUPOWERPC}
 
    {$SETC TARGET_CPU_68K              := NOT UNDEFINED CPUM68K}
 
    {$SETC TARGET_CPU_X86              := NOT UNDEFINED CPUI386}
 
    {$SETC TARGET_CPU_MIPS              := FALSE}
 
    {$SETC TARGET_CPU_SPARC            := NOT UNDEFINED CPUSPARC}
 
    {$SETC TARGET_RT_MAC_CFM            := NOT UNDEFINED MACOS}
 
    {$SETC TARGET_RT_MAC_MACHO          := NOT UNDEFINED DARWIN}
 
    {$SETC TARGET_RT_MAC_68881          := FALSE}
 
    {$SETC TARGET_OS_MAC                := (NOT UNDEFINED MACOS) OR (NOT UNDEFINED DARWIN)}
 
    {$SETC TARGET_OS_WIN32              := NOT UNDEFINED WIN32}
 
    {$SETC TARGET_OS_UNIX              := (NOT UNDEFINED UNIX) AND (UNDEFINED DARWIN)}
 
    {$SETC TARGET_RT_LITTLE_ENDIAN      := NOT UNDEFINED FPC_LITTLE_ENDIAN}
 
    {$SETC TARGET_RT_BIG_ENDIAN        := NOT UNDEFINED FPC_BIG_ENDIAN}
 
    {$SETC TYPE_EXTENDED                := TRUE}
 
    {$SETC TYPE_LONGLONG                := FALSE}
 
    {$SETC TYPE_BOOL                    := FALSE}
 
    {$SETC TYPED_FUNCTION_POINTERS      := TRUE}
 
{$ELSEC}
 
</tt>
 
  
Other tweaks needed:
+
Caveat 2: Deviation from Think Pascal and Metrowerks Pascal: Macros from used units is not in effect until after the whole uses clause (incl semicolon) has been parsed.
* In Multiprocessing.p and some other files, some argument names are "object". Change to something else, e g obj.
 
  
Note:
+
==Apple's Universal Interfaces==
* The varaible qd in Quickdraw needs to be allocated somewhere, since it is declared with $J directive in UI. So it is defined in System.pp.
+
Starting with FPC 2.04, Apple's Universal interfaces are included with FPC. They are from the same source tree that is available at http://www.microbizz.nl/gpc.html, only a slightly more recent version (r165 as of 2.0.4).

Latest revision as of 18:19, 3 September 2022

English (en) français (fr)

Mode MacPas tries to be compatible with the Pascal dialects commonly used on Macintosh, that is THINK Pascal, Metrowerks Pascal and MPW Pascal. For tips on porting from traditional Mac Pascal compiler to Free Pascal, see Porting from Mac Pascal

Differences compared to standard Free Pascal

Here differences between the Macintosh dialect of Pascal and the standard dialect of Free Pascal (which is Turbo Pascal) are listed.

Implemented (in 2.0.2)

  • The file extension .p is supported, in mode MacPas.
  • The unit MacPas.pp is automatically included whenever mode MacPas is used. It should contain such stuff that is normally built in into Mac Pascal compiler.
  • $CALLING MWPASCAL Tells the compiler to use calling conventions according to Metrowerks Pascal. The only difference to the default is that, in MWPASCAL, CONST record parameters are always passed by reference.
  • Type checking of compile time expression (actually this is not MacPas specific)
  • Compile time variable can be given on the command line, syntax -dMYCOMPVAR:=3 or -dMYCOMPVAR2:=TRUE (no spaces). Hexadecimal values are not supported, though.

Compile time constructs

  • Compile time variables are now different from macros. However, they are related. In the FPC documentation, what is written about macros, is often also valid for compile time variables. The difference is that macro substitution is only done with real macros (which are defined by $DEFINEC). Compile time variables on the other hand are defined by $SETC.
  • Exportable compile time variables/macros. Compile time variables and macros defined in the interface part of a unit are exported to other MACPAS units, in the same manner as ordinary Pascal constructs. See more below under Exportable macros.
  • Compile time variables may be assigned to hexadecimal numbers, like $2345.
  • $SETC <compvar>:= <expr> -- sets a compiler variable's value to an expression. ":=" as well as "=" are allowed. If not already defined, it is defined.
  • $DEFINEC <macro> <content> defines a macro <macro>, whose substitution text is <content>. -- as its counterpart $DEFINE. Parameterised macros are not supported.
  • $IFC, $ELSEC, $ENDC -- as their counterparts $IF, $ELSE, $END
  • $ERRORC directive, similar to $ERROR
  • UNDEFINED <compvar> -- in compiler variable expressions
  • Compile time function OPTION(X), which returns, whether the compiler option X is set. Works for one letter options only.
  • TRUE, FALSE -- as values in compiler variable expressions
  • Compiler directive $PUSH and $POP, which saves/restores the current state of all local compiler switches.
  • Compiler option $J makes a variable external
  • Compiler option $Z makes variables and procedures externally visible
  • Compiler option $OV (+/-) sets overflow checking (FPC 2.5.1)
  • $ALIGN MAC68K, POWER, RESET (also POWERPC as equivalent of POWER in FPC 2.5.1)
  • Compiler directive LibExport is recognized, but does nothing at the moment. It may be implemented in the future.
  • Metrowerks compiler directive $UNDEFC and $ELIFC
  • Metrowerks compile time expression DEFINED <compvar>
  • Support for some Turbo/Delphi compiler directives as well, $DEFINE $UNDEF $IFDEF $IFNDEF $IF $ELSE $ENDIF $ELSEIF

Language

  • Object Pascal, Mac style. New, Dispose, Member are supported.
  • A procedure passed as parameter can be directly declared in the formal parameter list (anonymous procedure types).
  • OTHERWISE in case constructs (actually it was already supported even for Turbo Pascal)
  • Procedure Leave does the same as Break
  • Procedure Cycle does the same as Continue
  • Procedure Exit(<procname>), which works like Exit, but accepts the procname as parameter. <procname> must be the name of the procedure, in which Exit is used in. Non-local exit (as allowed in some Mac pascal implementations) is not allowed. Exit with return value as a parameter is not allowed. You can use "return <exit_value>;" though, as in Metrowerks Pascal.
  • Operators | and & (boolean operators, which are always evaluated as short-circuit boolean expressions)
  • UNIV modifier for types in parameter lists is accepted, but does nothing (update, it has been implemented in FPC 2.5.1)
  • C directive for procedure declarations. Same as CDECL.
  • "..." in procedure declaration, denoting a C var arg style function.
  • IMPLEMENTATION is not needed in units, if empty.
  • External directive
  • Procedures declared in the interface section, which do not have a counterpart in the implementation section, are considered external (we call them implicit externals). Their external name is prefixed with the C_prefix of the target. On Mac OS this is an empty string, whereas on Darwin/macOS it is an underscore, so that it will properly link with macOS' libraries (which are compiled with gcc).
  • Ord function can take a pointer as argument
  • Use of FourCharCode ( e. g. OSType, ResType) constants directly as parameters. This is done by an overloaded assignment operator defined in the file MacPas.pp
  • Ord4
  • All kinds of procedure variable stuff, compatible with Think Pascal and Metrowerks Pascal.

Implemented (in 2.1.1)

  • return <value>
  • compile time expressions are now short circuit evaluated
  • Bit-level packing of records and arrays

Planned

  • Nested procedure parameters (allowing a nested procedure to be actual parameter to another procedure) (update, it has been implemented in FPC 2.5.1)
  • Propagating uses
  • Open (for files)
  • HiWrd, LoWrd (since supported in both Think Pascal and Metrowerks)

Not Supported

Here is an (incomplete) list of mac pascal constructs which are not supported in mode mac at the moment, perhaps some of them will be supported in the future:

  • StringOf
  • HiWord, LoWord (same as HiWrd, LoWrd)
  • Implicit forward declaration of objects (In an object declaration, one cannot refer to an object not yet declared)
  • In object declarations, the method name cannot be preceded with the class name (as in Think Pascal)
  • Arithmetic compiler variable expressions
  • Goto between different nesting levels (e.g., no goto from a nested procedure to a parent procedure)
  • Exit between different nesting levels.
  • Working implementation of UNIV keyword (update, it has been implemented in fpc 2.5.1)

Free Pascal constructs allowed in Mode MacPas

Free Pascal constructs which currently are allowed in Mode MacPas, but which actually are not in the Macintosh dialect. If conflicts arises, some of them might be disallowed in future. Traditionally some of this functionality has been offered through Apple's Universal Interfaces. The list is not complete.

  • Assign(filename, file). In Macintosh Pascal the file name is given as an (optional) parameter directly to Reset(file, filename), Rewrite(file, filename) or Open(file, filename) (Open do open for both reading and writing).
  • Bitwise operators "shr". "shl", "and", "or", "not" etc. In Macintosh Pascal the functions BSR, BSL, BAND, BOR, BNOT are used instead. (Boolean operators "and", "or", "not" is of course allowed in Macintosh Pascal)
  • Assigned(pointer). An alternative is "pointer <> nil".
  • Append, Blockread, BlockWrite, Erase (delete files from disk), Filesize, Flush, Rename, SeekEof, SeekEoln, SetTextBuf, Truncate.
  • Addr, Compare*, *Seg, Fill*, Freemem, Getmem, High, Low, Move, MoveChar0, Ofs, Ptr (Note: In Apple's Universal Interfaces, Ptr is a datatype describing a generic pointer) , ReAllocMem, Release.
  • Hi, Lo. For conversion to 16 bit integers, in Macintosh Pascal you can use HiWord, LoWord. Note that Hi/Lo work on 64, 32 and 16 bit integers and return the upper/lower 32/16/8 bits depending on the argument.
  • Int
  • BinStr, HexStr, OctStr, SetLength, SetString, StringOfChar, Val, Str
  • ChDir, GetDir, MkDir, RmDir, Runerror
  • Paramcount, Paramstr (since classic Mac OS does not have command line interface)
  • Halt (param). Halt without parameter works in Macintosh Pascal.
  • Assert
  • Exclude, Include (for sets)
  • LongJmp, SetJmp (exists in Metrowerks but not Think)
  • Direct pointer arithmetics. In Macintosh Pascal, you must cast pointers to numbers before doing arithmetics.

Exportable macros

Only a mode MacPas unit will export macros and only a mode MacPas unit will import them. As before, MacPas and non-MacPas units can be used by each other but macros will then not be visible for use.

Macros will start to be exported right after the {$MODE MACPAS} directive. If no such directive is given, but -Mmacpas is given on the command line, macros will start to be exported right after the UNIT keyword.

To support this, for a unit, {$MODE MACPAS} if forbidden after the UNIT keyword. For other mode switches it is like before.

Caveat 1: If {$MODE MACPAS} is given before UNIT, the macros defined between this point and UNIT is exported, if the unit is compiled as part of a program or other unit, but is not exported if the unit is compiled from the commandline (at top level). To be deterministic, do not put macros before UNIT.

Caveat 2: Deviation from Think Pascal and Metrowerks Pascal: Macros from used units is not in effect until after the whole uses clause (incl semicolon) has been parsed.

Apple's Universal Interfaces

Starting with FPC 2.04, Apple's Universal interfaces are included with FPC. They are from the same source tree that is available at http://www.microbizz.nl/gpc.html, only a slightly more recent version (r165 as of 2.0.4).