Compiler options and directives

The compiler's behavior may be tailored in two ways: by the compiler options available from the command line or by using compiler directives written directly into the Oberon source text. The Commando tool may be used to examine the available functions, parameters and options for Oberon and build a command line.
  1. The MPW Oberon command line
  2. Compiler options
  3. Compiler directives
    1. Control of code generation
    2. Conditional compilation
    3. Other directives

The MPW Oberon command line

The Oberon command line conforms to the following syntax:
Oberon [option|file]…
You can specify one or more filenames. Each source file is compiled separately-compiling the file Module.mod creates object file Module.mod.o. By convention, Oberon source filenames end in a .mod suffix. Options and filenames may be written in any order on the command line.

Compiler errors and warnings are written to diagnostic output which can be written to another file or redirected. Progress and summary information is also written to diagnostic output, if requested.

Note: Writing error messages and warning may sometimes confuse the MPW Shell-it will break into Macsbug. We were unable so far to resolve that problem. It seems to be somewhere in the MPW environment and not in MPW Oberon.

Compiler options

The MPW Oberon compiler options are symbols in the command line sending instructions to the compiler. The following table contains all options supported by MPW Oberon in alphabetical order.

-b
Force generation of object code. There is no definition module in Oberon, so changing the implementation of a module low in a program's module hierarchy results in "unnecessary" compilation of many modules triggered by Make. MPW Oberon skips compilation, if a file's modification date is greater than the modification date of all imported symbol files.
-c
Perform a syntax check only. No object code is generated.
-clear
Initialize all local pointers to NIL. This option is used normally in conjunction with the -nc option . All pointer variables within a procedure are set to NIL. Note that pointers within locally allocated dynamic variables are not cleared.
-cp
Write a warning for every use of a non-standard language feature. Use this option if you want to use a source file with a different compiler and you want to be sure that only standard Oberon is used.
-d name=TRUE|FALSE
Define a compiler variable. Compiler variables are used in conditional compilation. See "Compiler directives" for the directives used for conditional compilation. MPW Oberon predefines the following compiler variables:
SADE SADE information is enabled
MC68040 Use MC68040 instruction set
MC68881 Use MC68881 instruction set
MAIN Module is main-module
INITDATA Local-Data will be initialized
ULM Ulmer Oberon is enabled
Some of these compiler variables are initialized to the values specified by the corresponding command-line options.
-g
Allow more than 32K global variables. Note that the code generated will run slower and become bigger since offsets with 32 bits must be generated.
-i pathname[,pathname]…
Search for imported modules in the specified directories. Multiple -i options may be specified. At most, 15 directories will be searched. The search order for imported modules is as follows:
  1. The filename is assumed to be the same as the module name (with a .mod suffix appended). This file is searched in to directory containing the input file. If the file is not found, the following directories are searched:
  2. The directories specified by the -i options, in the order listed.
  3. The directories and the Shell variable {OInterfaces}.
-initvar
Initialize all local variables to $7267. This option works properly in conjunction with the -clear option where the latter takes precedence.
-main
Consider module body as the main entry point. This option is needed for the linker because there is no main program in Oberon. It is preferable to use the compiler directive $MAIN to indicate the main program in order to simplify the Makefile.
-mgb ch8
Include v2.0 compatible Macsbug symbols (eight characters only, in a special format)
-mbg [on|full]
Include full (untruncated) symbols for Macsbug. The maximum length for Macsbug symbols is 255 characters.
-mbg off
Don't include symbols for Macsbug.
-mbg number
Include Macsbug symbols truncated to the specified number. If number is 0, no Macsbug symbols are included. The default is to generate Macsbug symbols truncated to 31 characters.
-mc68040
Tune code generation for an MC68040. This option prohibits generation of some floating-point instructions emulated by the MC68040. The MC68040's instruction MOVE16 will be used in moving blocks of memory. Note that this option does not imply the -mc68881 option since there exist an MC68LC040 not supporting floating-point.
-mc68881
Generate code for the MC68881. The compiler will emit FPU-instructions for floating-point arithmetic. If this options is not given, SANE will be used for floating-point operations. If you specify this option the compiler recognizes a couple of additional standard procedures resembling the arithmetic functions supported by the MC68881. See "Predefined routines" for a list for standard functions.
-nc
Generate a check for NIL before dereferencing a pointer. This option is used in conjunction with -clear option mainly during the testing phase. If this option is specified, an exception will be raised when a NIL-pointer is dereferenced. If the -nc option is given, the behavior of the standard procedure NEW is modified. Newly allocated blocks are cleared, so that all pointer variables are set to NIL.
-noass
Suppress code generation for the ASSERT procedure.
-o file
Redirect the object code to the given file. If this option is not given, the object code is placed into a file with the name Module.mod.o when compiling Module.mod. The object file is placed in the same directory as the source file. Using the -o option you can redirect the output into another file giving its name. The name may contain a full or partial path.
-opt off
Turn off all optimizations produced by MPW Oberon.
-opt [on|full]
Optimize the generated object code. To limit this option, specify one or more of the following modifiers:
noreg Do not use register variables.
noreload Do not optimize reloads.
nosbra Do not generate short branches.
noexpr Do not optimize expressions.
You may use a comma-separated list of modifiers. The default is enable all optimizations.
-ov
Turn on overflow checking. Note that the generated code becomes slower and bigger.
-p
Display progress and summary information to diagnostic output. Note that this slows the compiler down.
-r
Turn on range checking. Indices to arrays and arguments to the standard function CHR are checked.
-rc
Suppress code for illegal selectors. In Oberon a CASE statement with an illegal selector (i.e. a selector not given as a label) results in a run-time exception. By specifying the -rc option, the compiler suppresses the code for exception generation.
-rr
Suppress code for missing RETURNs. In Oberon a function must return a value using a RETURN statement. If a function terminates without RETURN, a run-time exception is raised. Given this option, the compiler suppresses code for exception generation.
-s
Permit replacing symbol file. If there was a change in a module's definition part, a new symbol file is needed. To prevent erroneous modifications to the public part of a module, replacing the symbol file is not allowed until the -s option is given.
-sym off
Don't emit SADE object file information. This is the default.
-sym [on|full]
Emit complete SADE object file information. To limit this option, specify one or more of the following modifiers:
nolines Do not include information about statement positions.
notypes Do not include information about the structure of data types.
novars Do not include information about global and local variables.
You may use a comma-separated list of modifiers.
-t
Report compilation time to diagnostic output. The -p options also report this information.
-tc
Suppress type checks.
-ulm
Generate code compatible with Ulm's Oberon System. Ulm's Oberon System was written by Andreas Borchert at the University of Ulm. This compiler support an older version of Oberon where pointers passed by reference get an accompanying type tag.
-w
Suppress generation of warnings. MPW Oberon reports warning messages for some common "problems" to diagnostic output.

Compiler directives

Compiler directives, also called pragmas, are commands embedded directly into the Oberon source text. Every compiler directive begins with a dollar sign and must be enclosed in comment delimiters. You can put only one directive within a comment. Directives are not case sensitive. Any character after the directive until the and of the comment are ignore and may be used for a comment.

The MPW Oberon compiler directives are listed alphabetically in the followingtable with the default conditions marked by asteriks. The individual directives are discussed in the following sections.

Note: Compiler directives must start immediately after the comment is opened. If there are any characters between the opening (*-symbol and the $-sign, the compiler directive will not be recognized.

$C+
Detect invalid selectors in CASE*
$C-
Ignore invalid selectors
$CALLING OBERON
Use Oberon calling convention for subsequent declarations*
$CALLING PASCAL
Use Pascal calling convention for subsequent declarations
$ELSE
Compile source text if compExpr in preceding $IF or $ELSIF is FALSE
$ELSIF compExpr
Compile subsequent source text if compExpr is TRUE and compExpr in preceding $IF or $ELSIF is FALSE
$END
End range of conditionally compiled source text
$IF compExpr
Compile subsequent source text if compExpr is TRUE
$J+
Global data definitions may be defined in another file
$J-
Global data definitions must be in Oberon source file*
$MAIN
Indicate module's initialization as main entry point
$OV+
Detect arithmetic overflows*
$OV-
Ignore arithmetic overflows*
$POP
Restore the save option settings
$PUSH
Save the current option settings
$R+
Perform range checking of arrays and CHR*
$R-
Do not perform range checking of arrays and CHR
$Parameter
Assign registers for procedure parameters
$REGVAR+
Use registers to store local variables*
$REGVAR-
Do not use registers to store local variables
$S name
Place subsequent routines in specified segment
$SET name compExpr
Define compile-time variable
$TAGS+
Data types will have type tags*
$TAGS-
Data types do not have type tags
$TYPECHECK+
Generate code for type checks*
$TYPECHECK-
Do not generate code for type checks

Control of code generation

The $C directive

(*$C+*)
(*$C-*)
A CASE statement in Oberon generates an exception if a selector was supplied not explicitly listed. The effect of the directive may be simulated by using an empty ELSE within the CASE statement.

The $CALLING directive

(*$CALLING PASCAL*)
(*$CALLING OBERON*)
High-level languages on the Macintosh (M68000 systems) use different methods for passing parameters to procedures. MPW Oberon supports two so-called calling conventions: Oberon and Pascal. By default the Oberon convention is normally used for procedures calls (see "Oberon calling convention" for a detailed description). The operating system uses the Pascal calling convention. Both conventions are similar but not equivalent.

You must specify which calling convention to use when passing procedures to the operating system that will be called later on by the system. Typical examples for such procedures are filter routines for events or handlers for Apple events. Such routines must use the Pascal calling convention. Note that to both procedures and procedure types a calling convention is attached.

The MPW Oberon interface files contain definitions of procedure types used by the Macintosh ROMs. All these types use the Pascal convention. If you try to pass a procedure with the same parameters but a different calling convention, MPW Oberon will report an error. For example, if you want to write a filter for the Dialog Manager's routine ModalDialog, you must use the $CALLING directive:

(*$CALLING PASCAL*)
PROCEDURE Filter(dialog: Dialogs.DialogPtr;
VAR event: Events.EventRecord;
VAR item: INTEGER): BOOLEAN;
BEGIN
(*your code here*)
END Filter;
(*$CALLING OBERON*)

The $J directive

(*$J+*)
(*$J-*)
The directive $J+ allows global data declared in a module to be defined in another file, the connections being made be the linker. Such connections are case sensitive. The default directive $J- requires all definitions to be in the Oberon source file.

The $OV directive

(*$OV+*)
(*$OV-*)
The default condition $OV- prevents the compiler from generating code to detect arithmetic overflow during expression evaluation. The directive $OV+ causes it to produce such code.

The $R directive

(*$R+*)
(*$R-*)
The $R+ directive instructs the compiler to generate code to perform range checking of array bounds and arguments to the CHR standard function. The default, $R-, is to suppress the generation of such code.

The $PARAMETER directive

(*$PARAMETER ProcName([register[,register]+])[:register] *)
The $PARAMETER directive allows to assign registers for the parameters of the procedure ProcName. This directive must be given immediately before the declaration of the corresponding procedure. Otherwise it will be ignored. Currently MPW Oberon restricts use of the $PARAMETER directive to inline procedures.

The name given in the $PARAMETER directive is case sensitive and must match the name of the following procedure. For every parameter of the procedure a register must be given. MPW Oberon supports the registers D0-D7, A0-A7, and FP0-FP7 for parameters. FP0-FP7 may be used only when the code for the MC68881 is generated. See "Passing parameters in registers" for an example and further details.

The $REGVAR directive

(*$REGVAR+*)
(*$REGVAR-*)
MPW Compiler uses some registers for storing values of local variables (see "Oberon calling convention" for further details). The $REGVAR- directive instruct the compiler to place all local variables in memory. The default, $REGVAR+, instructs the compiler to use registers for variables.

Note: Sometimes you should switch off register variables to improve speed. MPW Oberon can't perform detailed analysis of the source code due to the lack of an intermediate representation, so loading and restoring registers may take longer than directly using the variables on the stack. This applies especially to very short procedures.

The $S directive

(*$S segmentName*)
By default the compiler instructs the linker to place all routines of a module within a single segment. The module's name is used as the case-sensitive identifier for the segment. The $S directive allows to specify that subsequent routines be directed to the specified segment. The $S directive can only appear between global routines. See "Segmentation control" for further details about segmenting your program.

Note: You may use at most 20 different segments in one source file.

The $TYPECHECK directive

(*$TYPECHECK+*)
(*$TYPECHECK-*)
Type tags are used in Oberon to keep the type of a variable allocated on the heap. If an operation tries to modify a variable with a type not allowed, a run-time exception is generated. The command $TYPECHECK- instructs the compiler to suppress such type checks. The default, $TYPECHECK+, is produce such tests. See "Passing dynamic structures to the operating system" for further information about type tags.

Conditional compilation

MPW Oberon lets you compile sections of your source text conditionally by means of $IF, $ELSIF, $ELSE, and $END directives. The $IF and $ELSIF directives are controlled by the value of a compile-time expression. Directives for conditional compilation may be nested. The rules covering such nesting are the same as for IF statements of the Oberon language. Nesting may be 32 levels deep.

Compile-time expressions may be formed out of compile-time variables, Boolean constants, and the Boolean operators ~, OR, and &. You may use the alternate notations ¬ and AND for the operators ~ and & respectively. Compile-time expressions are always of type BOOLEAN. The grammar governing the structure of compile-time expression is:

Expression ::= Term ["OR" Term].
Term ::= Factor [("AND"|"&") Factor].
Factor ::= identifier | "TRUE" | "FALSE" | ("~"|"¬") Factor
Identifiers start with a letter and may contain letters, digits, and underscores and denote compile-time variables. If a compile-time variable was not assigned a value prior to its first usage, MPW Oberon defines it with a value of FALSE. Variables may be defined by using the -d option or the $SET directive.

Note: Conditional compilation was added to MPW Oberon mainly for porting the universal interface files. Using the facilities provided for conditional compilation so far, transforming the interface files for use with Oberon is relatively easy but tedious.

The $IF directive

(*$IF compExpr*)
The $IF directive causes the compiler to compile subsequent source text until the next $ELSIF, $ELSE, or $END directive, only if the value of the compile-time expression compExpr is TRUE.

The $ELSE directive

(*$ELSE*)
The $ELSE directive marks the beginning of source text that is compiled only if all compExprs in the corresponding $IF and $ELSIF directives evaluated to FALSE.

The $ELSIF directive

(*$ELSIF compExpr*)
The $ELSIF directive causes the compiler to compile subsequent source text until the next $ELSIF, $ELSE, or $END directive, only if the value of the compile-time expression compExpr is TRUE.

The $END directive

(*$END*)
The $END directive marks the end of a section of conditionally compiled source text, matching a $IF directive.

The $SET directive

(*$SET varName compExpr*)
The $SET directive assigns the compile-time variable varName the value of the compile-time expression compExpr. If a compile-time variable with the given name does not exist, it will be defined.

Note: You may use at most 20 different compile-time variables in one source file.

Other directives

The $MAIN directive

(*$MAIN*)
The $MAIN directive instructs the compiler to identify the module body of the current module as the main entry point. Only one module linked into a program may be marked as the main module. This option is needed because Oberon does not have a main program.

The $PUSH and $POP directives

(*$PUSH*)
(*$POP*)
The $PUSH directive allows to save the current option settings. You may nest $PUSH directive five times. The $POP directive restores the options saved by the most recent $PUSH. It is an error to have more $POPs than $PUSHs. Use $PUSH and $POP to modify an option without changing its original value.

The $TAGS directive

(*$TAGS+*)
(*$TAGS-*)
The $TAGS- directive instructs the compiler to mark subsequently declared types as "untagged". Dynamic variables of an untagged types do not have a type tag, so type check and type guard may not be performed. Untagged variables are used when allocating structures passed to the system. The default, $TAGS+, is to not mark types as untagged. See "Type tags in MPW Oberon" for further information about type tags.
Previous Section, Next Section, Contents
Jürgen Geßwein, 2. Juni 1995