home *** CD-ROM | disk | FTP | other *** search
- Compiler Extensions
- ===================
-
- The compiler has been extended with extra features. Most of which are
- designed to make interfacing with the amiga operating system easier.
- Other features are designed to make programming in Modula-2 less annoying.
- Avoid using these extensions if you wish to develop portable modules.
-
- Underscore
- ==========
-
- The underscore is a valid 'letter'.
- eg, '_Turbo_Modula_2' is a legal identifier.
-
- SHORTCARD, SHORTINT AND SHORTREAL
- =================================
-
- The types SHORTINT, SHORTCARD & SHORTREAL are not normally
- predeclared in other Modula-2 compilers:
-
- SHORTCARD is predeclared as [0..255] (* byte sized cardinal *)
- SHORTINT is predeclared as [-128..127] (* byte sized integer *)
- SHORTREAL Motorola fast floating point.
-
- Conversion Rules
- ================
-
- Signed (integer) and unsigned(cardinal) numeric subrange types may be freely
- mixed in expressions. The following conversion rules apply:
-
- VAR
- shortint : SHORTINT ;
- shortcard : SHORTCARD ;
- integer : INTEGER ;
- ...
-
- shortint+shortcard => VAL(INTEGER,shortint)+VAL(INTEGER,shortcard)
- shortint+cardinal => VAL(LONGINT,shortint)+VAL(LONGINT,cardinal)
-
- shortint+integer => VAL(INTEGER,shortint)+integer
- shortint+longint => VAL(LONGINT,shortint)+longint
-
- shortcard+cardinal => VAL(CARDINAL,shortcard)+cardinal
- shortcard+integer => VAL(INTEGER,shortcard)+integer
- shortcard+longint => VAL(LONGINT,shortcard)+longint
-
- integer+cardinal => VAL(LONGINT,integer)+VAL(LONGINT,cardinal)
-
- integer+longint => VAL(LONGINT,integer)+longint
-
- cardinal+longint => VAL(LONGINT,cardinal)+longint
-
- Where '+' could be any binary operator.
- The result type in each conversion should be obvious.
-
- Qualified Import aliasing
- =========================
-
- An imported global module name may be aliased.
-
- IMPORT Graphics , Intuition ;
-
- VAR
- rp : Graphics.RastPortPtr ;
- win : Intuition.WindowPtr ;
-
- Can be rewritten:
-
- IMPORT G := Graphics , I := Intuition ;
-
- VAR
- rp : G.RastPortPtr ;
- win : I.WindowPtr ;
-
- Imported library versions
- =========================
-
- When importing an Amiga library module ( Dos, Intuition, Graphics etc ),
- an optional version number can be specified:
-
- IMPORT Intuition{33} ;
-
- FROM Dos{36} IMPORT System ;
-
- The values 33 & 36 will be passed to Exec.OpenLibrary by Intuition.o & Dos.o
- If no version number is specified, zero is assumed.
-
- Intuition.o, Dos.o etc will cache the highest version opened so far
- in order to reduce calls to Exec.OpenLibrary.
-
- The version number must be a decimal literal (not an arbitrary expression)
- this simplifies the parser in programs like M2B.
-
- Structure assignment
- ====================
-
- It is possible to assign to an array or record structure in a single
- statement, the right hand side being a list of bracketed expressions.
-
- The syntax of the assignment statement is extended to:
-
- $ assignment = designator ":=" ass_rhs .
- $ ass_rhs = "["[asslist]"]" | expression.
- $ asslist = ass_rhs{,ass_rhs}
-
- VAR x : ARRAY [0..6] OF INTEGER ;
-
- x := [f(y),2,4,a,0,0,0] ; (* The expressions need NOT be constant *)
-
- Trailing elements/fields need not be assigned to,in which case they will
- be zeroed.Any automatically inserted compiler padding fields will also be 0.
-
- x := [f(y),2,4,a] ; (* same as above *)
-
- If a record contains variant fields then the compiler assumes (and checks
- against) the first variant.In other words you can only assign to the
- first variant field(s).
-
- examples:
-
- VAR
- matrix = ARRAY [0..3],[0..2],[0..2] OF LONGINT ;
-
- PROCEDURE InitMatrix ;
- BEGIN
- matrix:=[[[7FFFH, 0, 0],[ 0,7FFFH, 0],[ 0, 0,7FFFH]],
- [[32642, 0,2856],[ 0,7FFFH, 0],[-2856, 0,32642]],
- [[32642,2856, 0],[-2856,32642, 0],[ 0, 0,7FFFH]],
- [[7FFFH, 0, 0],[ 0,32642,2856],[ 0,-2856,32642]]] ;
- END InitMatrix ;
-
- TYPE
- NewMenu = RECORD (* Gadtools structure *)
- nm_Type : SHORTCARD ;
- CASE : INTEGER OF
- | 0 : nm_Label : STRING ;
- | 1 : nm_Image : ImagePtr ;
- END ;
- nm_CommKey : STRING ;
- nm_Flags : BITSET ;
- nm_MutualExclude : LONGINT ;
- nm_UserData : ADDRESS ;
- END ;
-
- VAR
- demomenu : ARRAY [0..11] OF NewMenu ;
-
- BEGIN
- demomenu :=
- [
- [ NM_TITLE,"Project" ],
- [ NM_ITEM, "Run", "R", {}, 0, MENU_RUN ],
- [ NM_ITEM, "Step", "S", {}, 0, MENU_STEP ],
- [ NM_ITEM, NM_BARLABEL ],
- [ NM_ITEM, "Slower Horizontal", "1", {}, 0, MENU_HSLOW ],
- [ NM_ITEM, "Faster Horizontal", "2", {}, 0, MENU_HFAST ],
- [ NM_ITEM, "Slower Vertical", "3", {}, 0, MENU_VSLOW ],
- [ NM_ITEM, "Faster Vertical", "4", {}, 0, MENU_VFAST ],
- [ NM_ITEM, NM_BARLABEL ],
- [ NM_ITEM, "Quit", "Q", {}, 0, MENU_QUIT ],
- [ NM_END ]
- ] ;
-
- Open array heap variables
- =========================
-
- In Modula-2 it is possible to declare open arrays only as formal parameters.
- The compiler allows open arrays to be declared as pointer base types.
-
- VAR
- p : POINTER TO ARRAY OF CHAR ;
-
- Like formal parameters, the open array must be 1 dimensional.
-
- The NEW substitution mechanism has to be extended to allow declarations
- of such heap variables.
-
- NEW(p,exp) ; where exp is an integer/cardinal expression.
-
- This expands to ALLOCATE( p , exp*SIZE(p^[0]));
-
- There is no bounds checking associated with this type of array.
- It is not possible to do any operation on the open array,only individual
- elements may be accessed:
-
- The designator p^ may never appear on its own, the '^' must always be
- followed by a '[' eg p^[10].
-
- If the follow declarations exist:
-
- VAR
- x : POINTER TO ARRAY OF type ;
- y : ARRAY [low..hi] OF type ; (* normal array *)
-
- Then the assignment
-
- x := y ; is allowed. This is equivalent to
- x := ADR( y ) ;
-
- If the base type of the open array(x^[0]) is CHAR then,
-
- x := "help" ; is allowed and is equivalent to
- x := ADR("help") ;
-
- The SYSTEM.STRING type is predeclared as POINTER TO ARRAY OF CHAR.
- The array pointed to by a STRING variable should always be 0C terminated.
-
-
- This kind of pointer occurs in the C language, and so is quite useful
- when programming with the amiga OS and the Ansi C libraries. However it is
- not true to Modula's strong typing philosophy and therefore its
- indiscriminate use should be avoided.
-
- Pointer casting in selector lists
- =================================
-
- It is possible to insert type casts in variable selector lists:
-
- foo := bar(NewMenuPtr)^.nm_Label(ImagePtr) ;
-
- The syntax of the designator is extended to:
-
- $ designator = qualident {"."ident|"["ExpList"]"|"("qualident")"| "^" }.
-
- This method of casting is restricted to (and from) pointer types.
- It is very useful when using Intuitions BOOPSI system.
-
- Variable length argument lists
- ==============================
-
- A procedure may be declared to take a variable number of arguments.
- To declare such a procedure, the formal parameter list must end with '..':
-
- PROCEDURE VarArgsProc( x : INTEGER ; .. ) ;
- (* There must be at least 1 normal formal parameter *)
-
- There is no standard way of accessing the unknown parameters from Modula-2.
- This kind of declaration normally occur in Amiga OS & C interface modules.
- However you can declare them in implementation & program modules:
-
- PROCEDURE CreateGad( kind:LONGINT; VAR ng:GT.NewGadget; tag1:LONGINT; .. ) ;
- (* topazAttr, visualInfo, window, lastAdded are global variables *)
- BEGIN
- ng.ng_TextAttr := ADR( topazAttr ) ;
- ng.ng_VisualInfo := visualInfo ;
- INC( ng.ng_LeftEdge, window^.BorderLeft ) ;
- INC( ng.ng_TopEdge , window^.BorderTop ) ;
-
- lastAdded := GT.CreateGadgetA( kind, lastAdded, ng, ADR( tag1 ) )
- END CreateGad ;
-
- If a SHORTREAL or REAL actual corresponds to a '..' formal
- then the parameter is converted to a LONGREAL before being passed.
-
- Newline and tab characters
- ==========================
-
- String literals may contain newline (\n) & tab(\t) characters.
-
- InOut.WriteString("Hello\tworld\n");
-
- If '\' in a string is not followed by one of 't' 'n' '\' then the compiler
- will report an error.
- To represent '\' use '\\'.
-
- "\n" & "\t" are also legal character constants as well as strings.
-
- Exit codes
- ==========
-
- A return statement inside the initialization statement sequence of the root
- program module may contain an optional integer expression. This expression,
- if executed, will represent the return code for the program.
- If no expression is supplied, or if execution falls through, 0 is returned.
-
- MODULE foo ;
- ...
- BEGIN
- RETURN 20
- END foo.
-
- The standard AmigaDOS return codes are:
-
- 00: program was successful.
- 10: warning (non fatal 'error').
- 20: fatal error.
-
- Alternatively StdLib.exit(X), will terminate the program with return code X.
-
- Coroutines
- ==========
-
- The pseudo module SYSTEM does not contain any coroutine facilities,
- instead the library module 'Coroutines' should be used.
-
- SHORTSET BITSET & LONGSET constants
- ===================================
-
- The compiler predefines 3 set types.
-
- SHORTSET = SET OF [0..07] ; SIZE = 1 Byte
- BITSET = SET OF [0..15] ; SIZE = 2 Byte
- LONGSET = SET OF [0..31] ; SIZE = 4 Byte
-
- The type of an unqualified set constant has been extended to support these
- types.
-
- {}, {0}, {0,1} ... {0..7} are compatible with SHORTSET,BITSET & LONGSET
- {8}, {8,9} ... {8..15} are compatible with BITSET & LONGSET
- {16} .. {16..31} are only LONGSETs
-
- By compatible I mean both expression compatible & assignment compatible.
-
- VAR
- shortset : SHORTSET ; bitset : BITSET ; longset : LONGSET ;
-
- shortset:= {1} (*valid*); shortset:= {8} (*wrong*); shortset:= {16}(*wrong*)
- bitset := {1} (*valid*); bitset := {8} (*valid*); bitset := {16}(*wrong*)
- longset := {1} (*valid*); longset := {8} (*valid*); longset := {16}(*valid*)
-
- INCL & EXCL
- ===========
-
- As well as the normal definitions of the standard procedures INCL/EXCL
- the second parameter of these procedures may be a set expression.
-
- example:
-
- INCL(bitset,{1,2}) is identical to bitset := bitset+{1,2}.
- EXCL(bitset,{1,2}) is identical to bitset := bitset-{1,2}.
-
- However the INCL/EXCL versions generate atomic code.
-
- BCPL pointers
- =============
-
- The DOS operating subsystem was partly implemented in the BCPL programming
- language, which used long word pointers,as opposed to normal byte pointers.
- It is possible to declare a BCPL long word pointer in Turbo Modula-2
-
- TYPE
- FileLockPtr = BCPL POINTER TO FileLock ; (* BCPL is a reserved keyword *)
-
- Instances of this pointer can be dereferenced as normal.
-
- The type SYSTEM.BADDRESS exists and is analogous to the normal
- SYSTEM.ADDRESS type.
-
- If an assignment to a BCPL pointer from an ADDRESS typed expression occurs
- then the compiler will automatically perform the necessary conversion:
-
- VAR lock : FileLockPtr ; v : FileLock ;
-
- lock := ADR(v) ; (* will work, but only if v is long word aligned *)
-
- The reverse assignment from a BADDRESS expression to a normal pointer will
- also be converted properly.
-
- You must be careful not to cast between the 2 different kinds of pointers
- as no conversion will take place. Instead there are 2 functions in the
- SYSTEM module that can be used.
-
- PROCEDURE SYSTEM.BTOA( bp : BADDRESS ) : ADDRESS ;
- PROCEDURE SYSTEM.ATOB( p : ADDRESS ) : BADDRESS ;
-
- The base variable of a BCPL pointer should always be long word aligned.
- Modula-2 global variables are always longword aligned as is the memory
- allocated using the StdLib.malloc & Storage.ALLOCATE functions.
-
- SHORTFLOAT & LONGFLOAT
- ======================
-
- As well as the normal FLOAT conversion function, which always converts
- to REAL, there are 2 other integer/cardinal->real conversion functions:
-
- SHORTFLOAT, converts an integer/cardinal into a SHORTREAL
- LONGFLOAT , converts an integer/cardinal into a LONGREAL
-
- Psuedo Module System
- ====================
-
- The following types are declared in SYSTEM:
-
- ADDRESS
- BADDRESS see above
- BYTE
- WORD
- LONGWORD like BYTE & WORD except 32-bits long
-
- SHORTSET (also pervasive)
- BITSET (also pervasive)
- LONGSET (also pervasive)
- SHORTREAL (also pervasive)
- FFP Motoral Fast Floating Point (FFP=SHORTREAL)
- STRING see above
-
- Functions declared in SYSTEM:
-
- ADR
- TSIZE
- BTOA see above
- ATOB see above
-
- OFFSET OFFSET( recordType , field ) : LONGINT
- Returns the byte offset of the field in the record.
-
- CAST CAST( TYPEid,expression) : TYPEid
- Performs a typecast: same as to TYPEid(expression).
- eg str := CAST(STRING,98)
- str := STRING(98)
-
- MAKEID MAKEID( STRING ) : LONGINT
- String should <= 4 characters.
-
- Comment Options
- ===============
-
- Unnested comments in your source code can be used to override command line
- options. The format is (* @X+ *) to enable an option or (* @X- *) to disable
- it. These comments should normally be placed at the top of your code.
-
- The options are:
-
- @C(+/-) Enable/Disable Large Code option.
- @D(+/-) Enable/Disable Large Data option.
- @B(+/-) Enable/Disable Array Bounds Checking.
- @P(+/-) Enable/Disable Pointer Checking.
- @A(+/-) Enable/Disable Alternative BSS naming convention.
-
- There are also two other options which relate to individual procedures:
-
- @G See examples/src/Hook.mod
- @O See ansi-c/SetJmp.def
-
- DEFINITION FOR C MODULE'S
- =========================
-
- To make it easy to interface with code written in the 'C' language it
- is possible to declare non standard definition modules.
- There are 3 closely related kinds:
-
- 1.DEFINITION FOR C MODULE (eg StdLib.def)
-
- There is no corresponding implementation module.
- This kind of definition module normally contains a list of declarations
- which are defined in some C library or object file.
- A normal Modula-2 module that wishes to use the functions/variables
- declared in this kind of module simply imports them as normal.
- To enable correct linking however, the library or object files must be
- specified on the command line
-
- >m2b CallsX.mod X.o X.lib
-
- See examples/for_c/ for an example of calling a 'C' function.
-
- The library (c.lib) which contains all the function declared in
- StdLib.def,CType.def etc is automatically included by DCC,
- so we dont have to specify it on the command line.
-
- 2.DEFINITION FOR AMIGALIB MODULE (eg Console.def)
-
- Mainly used to define AmigaDos devices (functions in amiga.lib).
- Like FOR C except all variable and strings declarations declared in the
- definition module are expected to be found in the coressponding Modula-2
- object file. For the compiler to generate such an object file there must
- be a corressonding implementation module,which is normally empty
- eg Console.mod or opens the device).
- The implementation module may contain procedure declaration which
- should only impelement macros not coded in the object file or library
- eg StdIO.mod .
-
- 3.DEFINITION FOR LIBRARY MODULE (eg GadTools.def)
-
- Used to open and define AmigaDos libraries.
- Identical to FOR AMIGALIB except when such a module is imported an
- optional library version number can be specified (see line 75 ).
- This version number can be read using the pervasive cardinal variable
- 'VERSION', for an example see GadTools.mod, and is noramlly passed to
- to function OpenLib, which inturn calls Exec.OpenLibrary.
- The initialisation body of an implementaion for library module must be
- capable of being called more than once ie with different versions
- arguments.
-