Click here to see interesting book recommendations! |
A2O V3 User's Guide |
|
Copyright (1995-1999) by ModulaWare.com
The OpenVMS Oberon-2 Compiler A2O|H2O are implementations of the programming language Oberon-2. H2O generates VAX and A2O generates Alpha native code. Both compilers are designed to run under the OpenVMS operating system.
The purpose of this manual is to explain how to compile, link and execute (stand-alone) Oberon-2 programs under the OpenVMS Alpha|VAX operating system. Also described are the basic data types, storage allocation and alignment, calling conventions, and system dependent features. The appendix contains language report clarifications, restrictions and extensions, implementation specific programming hints, a summary of the OpenVMS-specific foreign interface modules, the compiler's help file, installation guide, release notes, and an index.
The usage of Alpha Oberon, an extensible, graphical development environment for A2O, is explained in the on-line Alpha Oberon User's Guide (AlphaOberon_Guide.Text)
Revision: A2O|H2O V3.0: Oct-1997
Edited and © (1995-1997) by
Günter Dotzel
http://www.modulaware.com/
AlphaOberon System website (download, updates, and upgrades):
This user guide has been designed to support the development and
execution of
Oberon-2 programs written in Oberon-2 under OpenVMS. It is based
on the OPenVMS
Modula-2 (MaX|MVR) user's guide which itself was derived from
ETH-Zürich's LIDAS
Database System (Modula/R) user's manual.
A2O|H2O consist of a front- and a back-end. The front-end is based
on ETH-Zürich's
portable Oberon-2 compiler OP2 written in Oberon[-1]. OP2 was
designed by Regis
Crelier at ETH-Zürich. OP2 was manually translated to Modula-2
for bootstrap purposes. The front-end incorporates an Oberon-2
source code
analyser written in Oberon[-1]. This analyser was developed by
Stefan Ludwig at
ETH-Zürich in 1992. The back-end of A2O|H2O is based on ModulaWare's
OpenVMS
Modula-2 Compiler (MaX|MVR) and is also written in Modula-2.
It was developed
at ModulaWare. So most parts of A2O|H2O are written in Modula-2.
ModulaWare's Oberon-2 (A2O|H2O) and Modula-2 (MaX|MVR) OpenVMS
compilers
share the same ISO Modula-2 Standard Library under OpenVMS. The
library
implementation is written in Modula-2 and was also developed
at ModulaWare.
Besides OpenVMS object files, A2O can also generate Oberon System
specific code-files
for AlphaOberon (OLF[64]). AlphaOberon is ModulaWare's 64 bit
port of ETH-Zürich's
Oberon System V4 for OpenVMS Alpha. The code generated for stand-alone
and
embedded modules is essentially identical; only the object file
format is different. The OLF
files are structural much simpler and shorter than the OpenVMS
object files. In addition to
code, constants, objects and linkage section, OLF files contain
data for the automatic
garbage collector and symbol information for procedures and variables
as well as
line-number/program-counter correlation for the AlphaOberon post-mortem
and run-time
debugger.
After compilation, Oberon code-files can be activated directly
from AlphaOberon without
linking, whereas stand-alone Oberon-2 programs require linking
with the OpenVMS
system linker. A2O can be invoked from Alpha Oberon with the
usual Oberon System
command Compiler.Compile or Folds.Compile, which runs A2O in
a spawned process,
accepting input from a marked viewer or file selection. Compilation
errors are displayed in
the system log viewer.
Detailed implementation notes of Alpha Oberon are contained in
the ModulaTor issues
number
#59,
#63,
#66,
#67,
#68,
and #72
(see below).
Hanspeter Mössenböck: The Programming Language Oberon-2. ETH-Zürich
Report Nr.
160, May 1991, revised May 1992.
The programming language Oberon-2 itself is described in a separate
report. Several
books about Oberon-2 are available in German and English:
Marc Brandis, Regis Crelier, Michael Franz, Josef Templ: The Oberon
System Familiy,
ETH-Zürich Report 174, April 1992.
Günter Dotzel: Alpha Alpha/OpenVMS Modula-2 and Oberon-2 Compiler
Project
(implementation notes). In: Peter Schulthess (Hsg.): Proceedings
of the Joint Modular
Languages Conference, University of Ulm, Germany, 28-30 September
1994.
Universitätsverlag Ulm, 1994
Regis Crelier: OP2: A portable Oberon Compiler. ETH-Zürich Report
Nr. 125, Feb-1990.
Hanspeter Mössenböck: Differences between Oberon and Oberon-2.
ETH-Zürich Report
Nr. 160, May 1991, revised May 1992.
Hanspeter Mössenböck: Objektorientierte Programmierung in Oberon-2.
Springer Verlag,
1992. Also available in English in early 1993. Referred to as
OOPiO2 in this manual.
Cuno Pfister (ed.), Beat Heep, Josef Templ: Oberon Technical Notes.
ETH-Zürich Report
Nr. 156, Mar-1991.
Martin Reiser, Niklaus Wirth: Programming in Oberon. Addison Wesley,
1992.
Josef Templ: A Symmetric Solution to the Load/Store problem. ETH-Zürich
Report 157,
1991.
Further documentation and examples for A2O, H2O and AlphaOberon
are contained in
the following issues of The ModulaTor:
[1, 8] Elmar Baumgart: The ISO Modula-2 Standard Library - A Collection
of Definition Modules with example and test programs,
#14
[2,2] Elmar Baumgart: ISO Modula-2 Standard I/O Library Test Programs,
#20
[2, 7.1] Elmar Baumgart: Test Program for ISO Modula-2's library
modules Processes
& Semaphores with an Oberon-2 multi-programming excursion,
#25
[2. 7.2] Günter Dotzel: H2O: ModulaWare's new Oberon-2 Compiler
for VAX/VMS -
Implementation and distribution kit details, #25
[2, 8] Elmar Baumgart: The ISO Modula-2 for Oberon-2 - Definition
of Interface Modules
with example and test programs, #14.
[2, 9] Günter Dotzel: How to count bits in Modula-2 - The old
fashioned type transfer
function versus ISO Modula-2's SYSTEM.CAST, #27
[2, 9.1] Günter Dotzel: How to count bits in Oberon-2 - Manually
transpiling from Modula-2 to
Oberon-2, #27
[3,1] The ModulaTor's Forum by Taylor Hutt, Günter Dotzel: Communication
about Persistent Objects in Oberon-2, #30
[3, 1.1] Hartmut Goebel, Günter Dotzel: Persistent Objects in
Oberon-2 on OpenVMS, #30
[5, 7] Hartmut Goebel: Alpha Oberon: The Oberon System for Alpha
under OpenVMS (6), #59
[5, 11] Günter Dotzel: "Working with AlphaOberon" (3),
#63
[6, 2] [6, 3] [6, 4] [6, 5] Dotzel, Günter; Goebel, Hartmut:
Porting the Oberon System to Alpha,
(22), #66
[6, 6] [6, 7] Dotzel, Günter; Goebel, Hartmut: The AlphaOberon
Run-Time Debugger, (8),
#67
[6, 8] Dotzel, Günter; Goebel, Hartmut: 64 Bit Address Extension
of the Alpha Oberon-2
Compiler, (3), #68
[Nr. 72] Dotzel, Günter; Pirkelbauer, Peter: Object model for
AlphaOberon System and
Alpha Oberon-2 Compiler, #72
OpenVMS Operating System Manuals:
OpenVMS Symbolic Debugger Reference Manual (not supplied)
OpenVMS Linker Reference Manual (not supplied)
OpenVMS Architecture Handbook (not supplied)
[Alpha] Richard L. Sites (ed.): Alpha Architecture Reference Manual.
Digital Press,
Burlington, 1992
[VAX] Digital: VAX Architecture Handbook, Maynard, 1981
Creation and execution of Oberon-2 programs under OpenVMS works
as with under
language compilers.
In general, Oberon-2 programs are composed of separate modules.
The first step in
creating an executable program is to edit the different source
files containing the
compilation units. There is no separation between main module,
definition modules, and
implementation modules as in Modula-2.
NOTE: The Oberon-2 compiler distinguishes upper and lower case
characters. Hence, all
identifiers must be spelled exactly as they are defined. All
reserved words and standard
names must be capitalized.
Source files are compiled separately. The order in which this
has to be done depends on
the import/export relationships between the modules. Circular
and recursive imports are
not allowed.
Two kinds of output files are produced (besides an optional listing
file):
1. Processing an Oberon-2 source file results in a symbol file,
containing a coded module
description readable by the compiler. This file is needed each
time when the source file is
re-compiled or when another compilation unit imports this module.
Symbol files store a
so-called module key which is used by the compiler to check the
interface consistency of
separately compiled modules. When compiling a module, a new symbol
file is generated
and compared to the old one. If the old and new symbol files
are identical, then the
module's interface part did not change and the new symbol file
is deleted. In this case, the
old symbol file with the old version key is kept.
2. Except for so-called foreign language interface modules, the
result of processing a
module is an object file readable by the OpenVMS-linker.
Finally, the separate object files have to be linked together
to form an executable image
file. Execution of this file can be started by the RUN command.
A full OpenVMS file specification has the form
node::device:[directory]filename.filetype;version
node, device, directory and version are optional items. The filetype
specification may be
omitted in certain cases. The default type depends on usage:
Default file types:
MOD Oberon-2 or Modula-2 source file
SYN Oberon-2 symbol file: input to and
output from Oberon-2 compiler
SYN64 64 bit Oberon-2 symbol file: input to and
output from Oberon-2 compiler
SYO 64
bit Oberon-2 symbol file: input to and
output from Oberon-2 compiler with fine-grained symbol-files
OBJ object
code file: output from Modula-2 or Oberon-2 compiler
(or from any other language compiler under OpenVMS)
OBJ64
64
bit object code file: output from Oberon-2 compiler A2O
OLF 32
bit Oberon load file: output from Oberon-2 compiler A2O
for AlphaOberon with fine-grained symbol-files
OLF64
64
bit Oberon load file: output from Oberon-2 compiler A2O
for AlphaOberon
MOD_LIS
source
file listing
DEF Modula-2
definition source file
SYM Modula-2
symbol file: input to and
output from Modula-2 compiler
MOC encrypted
Modula-2 or Oberon-2 source file
MAR VAX-Assembler
source file
EXE output
from linker
MAP linker
map file
Each Oberon-2 compilation unit has to be compiled separately.
In case of a non-existing
symbol file (or when the objects exported from the module are
changed) a symbol file is
generated in addition to an object file. Optionally a source
file listing may be produced.
The compiler also searches for and reads the symbol files belonging
to imported
modules. The same search strategy as with the Modula-2 compiler
MaX|MVR is applied.
The Oberon-2 compiler is invoked by the A2O (Alpha) or H2O (VAX)
command which has
the following form:
$ A2O { /qualifier } file-spec { /qualifier }
$ H2O { /qualifier } file-spec { /qualifier }
file-spec
determines the source file containing the compilation unit. Only
one file is accepted. The
default file type for Oberon-2 programs is MOD.
qualifiers
See below. Most of the qualifiers are identical to those of the
Modula-2 Compiler MVR.
In interactive mode, you can also enter the file specification
on a seperate line by typing a
carriage return after the command name. The system responds with
a prompt for the file
specification:
$ A2O <return>
_File:
Although the compiler is a so-called one-pass compiler, processing
of a source file
comprises one, two or three phases. On termination the compiler
returns a status code in
the reserved global symbols $STATUS and $SEVERITY which indicates
either a success
or a severe error during compilation. This information can be
used for controlling the
execution of OpenVMS command procedures (see OpenVMS Guide to
Using Command
Procedures for details). If the compiler run is aborted by ^C
or ^Y while using the
/list/machinecode qualifiers, then a plain-ascii work file (h2o_interpass.tmp)
remains on
the default directory and should be deleted or purged to recover
disk space.
The normal succession of the Compiler's passes:
A2O|H2O command qualifiers control optional compiler settings.
For every qualifier there
is a negative form to suppress the respective effect. The negative
form is indicated by a
leading "NO", e.g., "NOLIST" is the negative form of "LIST".
The meanings of the
qualifiers and their default values are listed below in a short
form. See Appendix (Help
File) for a detailed description.
ANALYSE[=(OptionList)] Source code analyser; options are intermediate_items,
count_statements, redefine_methods, used_before_set, var_parameters,
and
exported_items; all default.
To be used only in combination with /NoObject /NoMachine_Code
/NoSymFile
/NoCross_Reference. See 2.5 for a detailed description of the
analyser. (This option
is unsupported).
CHECK[=(OptionList)] Code is generated to perform run-time checks
for out-of-range
array index bounds, case label exception for case-statement without
else-part, and
type tests and guards; options are stackcheck, indexcheck, typecheck,
overflowcheck, rangecheck, pointerinit, asserteval (A2O only),
and heapinit; all
default.
CROSS_REFERENCE cross reference table is included in the source
listing. This
qualifier is effective only when used in conjunction with LIST.
(This option is
unsupported).
DEBUG The DEBUG qualifier produces information to be used by the
OpenVMS
Symbolic Debugger (or the symbol dump in AlphaOberon trap handler)
and the
run-time error reporting mechanism.
INTEGER_type_match_pointerSize This qualifier determines together
with the qualifier
/PointerSize the size of the pervasive type INTEGER. For default
(/NoInteger/PointerSize=32), the basic data types SHORTINT is
a 8 Bit, INTEGER
is a 16 Bit and LONGINT is a 32 Bit signed number. When using
/Integer, the types
SHORTINT and LONGINT are no longer pervasive. With /Integer/PointerSize=32,
the pervasive data type INTEGER is a 32 Bit signed number (same
as INTEGER in
MaX Modula-2) and with /Integer/PointerSize=64, it is a 64 Bit
signed number.
Always available are SYSTEM.SIGNED_8, SYSTEM.SIGNED_16,
SYSTEM.SIGNED_32 and SYSTEM.SIGNED_64. Attention, when swapping
this
compilation option, because the symbol file will change when
an object containing
INTEGER is exported.
Size of SHORTINT/INTEGER/LONGINT in bits ("-" = type is not available):
LOG If the LOG option is enabled, the following information is
displayed: compiler
version, succession of the compiler phases, and the names of
the symbol files read.
MACHINE_CODE A readable representation of the generated code is
included in the
source listing. This qualifier is effective only in conjunction
with the LIST qualifier. In
this case a temporary work file is created before the listing
generation pass. This file
with the file type .TMP is deleted on termination of the compilation
process.
OBJECT An object file for the linker is produced. The qualifier
has the form:
/OBJECT[=file-spec] You may specify a file for the object module.
The default is a
file of type OBJ which takes the name of the source file. If
the source file contains a
definition module this qualifier has no effect.
QUERY The QUERY qualifier forces the compiler to ask explicitly
for the symbol files to
be read. By default, QUERY is disabled and the compiler uses
a standard strategy
to search for the symbol files (see 2.3). The standard search
strategy is also
effective when QUERY is enabled but no file specification is
given.
POINTERSIZE=x (A2O only): With x=32, pointers, addresses and LONGINT
are 32 bit,
and with x=64, pointers, addresses and LONGINT are 64 bit quantities.
See
ModulaTor issue nr. 68. The option value x=64 is not yet supported
and would need
at least OpenVMS 7.0.
PACKED_RECORD (A2O only): Fields in records are aligned on a byte
boundary.
Default: NoPacked_Record. AlphaOberon only: A Requirement of
the garbage
collector is that record field elements of pointer type must
be naturally aligned (4
byte boundary). This is only guaranteed autmatically when using
/NoPacked_Record.
PARSE_TREE Display a parse tree (unsupported; reserved for use
by ModulaWare only).
SYMFILE A new symbol file is created automatically if there is
no old symbol file or if the
interface specification was modified in the source file. The
old file is always
looked-up with the search default strategy (file name is contructed
from the
module-name). The option has the form: /SYMFILE[=file-spec].
You may supply an
optional output file specification for the symbol file. The default
output file gets the
name of the source file with the default file type SYN[64] or
SYO with fine-grained
symbol-files. Version limit minimum of at least 2 is required
for the
compatibility/version check of the symbol file. It is recommended
to use the full module
name as source file name, e.g. if the module is called Xyz then
the file name should be
XYZ.MOD.
H2O Command Qualifiers
In contrast to Modula-2, the Oberon-2 Report doesn't specify any
syntax (directive or
pseudo comments) for local control of run-time checks to be enabled
or disabled. Only
global control which affects the whole compilation unit is available
via command line
qualifier (see the /Check compilation qualifier above).
In the default case (i.e., when no file name is specified in query
mode) the compiler
applies a standard strategy to search for the symbol files needed:
The default file name is
constructed out of the full module name; if no file can be found,
the file name is
constructed out of the first 9 characters of the module's name;
if no file is found, the last
try uses only the first 6 characters of the module's name. A
file type SYN is assumed.
Note, that the module name is converted to the file name by transforming
all lower-case
letters to capital letters. The compiler checks, whether the
symbol file found contains the
correct module; this check is case-sensitive.
The file is first searched in the user's default directory. If
the search fails, directories with
the logical names MOD$LIB_LIST (may be a directory name list),
MOD$LIBRARY,
MOD$LIBRARY_1 up to MOD$LIBRARY_9 are searched (in this order).
The entire
process is performed first in the process logical name table,
then in the group logical
name table, and finally in the system logical name table. Each
search terminates when
the first undefined logical name is encountered. If the file
has not yet been found, the
directories with the logical names MOD$SYSTEM and LIDAS$SYSTEM
are searched.
Compilation qualifier /Analyse[=(OptionsList)] enables the source
code analyser.
The Analyser marks by default:
- all non-exported variables/constants/types/fields that are declared
but never used, used
before being initialized ( * ), never initialized, and initialized
but never used.
- non-exported [type-bound] procedures that are never called.
- modules that are imported but never used.
( * ) For variables declared in a different scope, no warning
is produced (see option
used_before_set, however).
Options (complementing each other):
intermediate_items: redeclaration of/use of/assignment to intermediate
items. Additionally
marks items that are already declared in an outer scope. and
the use of or assignment to
intermediate items (e.g. local variables/parameters declared
in an outer scope).
count_statements: number of statements in module. Reports the
number of statements
(assignments, if, while, proc calls, etc.) in the module. This
is convenient for determining
the complexity of a program (instead of lines of code).
redefine_methods: redefinition of type bound procedures. Additionally
marks the
redefinition of type bound procedures.
used_before_set: used before set for different scopes. Additionally
marks 'used before
set' for variables declared in a different scope.
var_parameters: use of var parameters. Additionally marks variables
that are used as var
parameters and are therefore not ensured to be initialized.
exported_items: use/initialization of exported items. Additionally
marks exported items
that are declared but not used by the module itself, used before
being initialized, never
initialized, and initialized but never used.
Conditional compilation, usually implemented as compiler directives
(or pseudo
comments) is not supported in Oberon-2. However there are situations,
where system
dependent code should be maintained in a single source file to
avoid code duplication.
AlphaOberon provides an Oberon Texts tool called VersionElems,
which allows to
manage different versions of source code sections.
After compilation, the separate object modules are linked together
to produce an
executable OpenVMS image file. Note, linking is not neither required
nor possible with
AlphaOberon.
To link the modules, use the LINK command in the following form:
$ LINK { /command qualifier } file-spec-list
command qualifiers
Specify output file options. Refer to the OpenVMS Linker Reference
Manual for detailed
information.
file-spec-list
Specifies the input files to be linked. File specifications can
be separated by commas or
plus signs. The first file in the list should contain the main
module.
To create executable code you must specify all your object files
to be linked, except the
ones stored in default object file libraries.
By default, the object files input to the linker are assumed
to be of type OBJ. To link a 64
bit object file, append .OBJ64 to the first object file name
in the link command. For the rest
of the files in the file list the linker then also takes .obj64.
If no other specification is given,
the executable image file takes the name of the first object
file and is of type EXE.
In interactive mode you may enter the file specifications on
a separate line by typing a
carriage return after the command name. The system responds with
a prompt for the file
specification.
Below, a few qualifiers are listed which may be of interest to
the Oberon-2 programmer.
For some qualifiers there are also negative forms. Refer to the
OpenVMS Linker
Reference Manual for detailed information.
The MAP qualifier directs the linker to generate a map file containing
a summary of the
image's characteristics, a list of contributing modules, and
a list of global symbols and
values. The qualifier has the form:
/MAP[=file-spec]
where the optional file specification designates the map file.
The default is a file of type
MAP with the name of the first object file.
By default, MAP is disabled for interactive mode and enabled for
batch mode.
In conjunction with /MAP the modifying qualifiers BRIEF or FULL
and
CROSS_REFERENCE may be used.
/BRIEF and /FULL define the amount of information included in
the map file, as follows:
/BRIEF produces a summary of the image's characteristics and a
list of contributing
modules.
/FULL adds a summary of characteristics of image sections in the
linked image to the
normal map file.
/CROSS_REFERENCE can be used with /MAP or /MAP/FULL to include
cross-reference
information for global symbols in the map file.
By default, CROSS_REFERENCE is disabled.
If the DEBUG qualifier is used, the program will always be executed
under the control of
the debugger. (You may suppress this by issuing /NODEBUG with
the RUN command.)
By default, DEBUG is disabled.
The TRACEBACK qualifier is used to have error messages accompanied
by symbolic
traceback information.
By default, TRACEBACK is enabled.
/DEBUG implies /TRACEBACK.
Summary: Link Command Qualifiers
The OpenVMS Oberon-2 compiler provides identification information
for describing the
relationship between symbol files and object files belonging
to the same module. This
identification is in fact the compilation date and time of the
corresponding definition
module and it is passed to the linker in the form of an Entity
Ident Consistency Check
subrecord.
The linker checks the Entity Ident Consistency Check subrecord
of each object module
before it links them together. If object files of two modules
importing different versions of
the same definition module are encountered the linker issues
a warning message. In such
a case, the object files giving rise to the message should be
replaced by newly compiled
ones.
For more information about the Entity Ident Consistency Check
subrecords, see the
OpenVMS Linker Reference Manual.
The RUN command starts the execution of an executable image file.
It has the form:
$ RUN [ /[NO]DEBUG ] file-spec
The file must be specified; the file type may be omitted, EXE
is assumed in this case.
The DEBUG qualifier allows to run the program under control of
the debugger, even if you
have issued the H2O and LINK commands without this qualifier.
/NODEBUG will override
a /DEBUG given at link time.
Note, with AlphaOberon, running a stand-alone program is accomplished
by activating a
command of the form ModuleName.ProcName (any exported, parameterless
procedure)
with the middle mouse button.
Currently, the OpenVMS Symbolic Debugger runs Oberon-2 programs
with the language
mode set to PASCAL. Both modes use the syntax of the Pascal language.
Because of the
differences between the two languages, some features work differently:
-1- No distinction is made between lower and upper case letters
in identifiers.
-2- Don't use succ, Succ, SUCC, pred, in, div or mod ... as Oberon-2
identifiers. VAX
Pascal is not case sensitive which implies that the OpenVMS degugger
in language
Pascal is not case sensitive. Since PRED and SUCC are predeclared
standard functions
in the Debugger in language Pascal, there is no way to access
user defined variables with
the following names: PRED, Pred, pred, ... SUCC, Succ, and succ.
-3- Module bodies are treated as parameterless procedures with
the name of the modules
(for setting break points).
Note: The differences 1 to 3 above may lead to name conflicts
inside the debugger, which
are not always handled properly.
-4- All variables and procedures can only be accessed in the context
of the module they
are defined in (see OpenVMS debugger commands: use SET MODULE/ALL;
SHOW
CALL; and SET SCOPE).
-5- Sets are displayed and must be entered in PASCAL's notation,
using square brackets
('[', ']').
-6- Open array parameters are known to the debugger as fixed size
arrays with lower bound
of 0 and upper bound of 2**16-1. Use examine array[0:9] to get
the first 10 values of a
dynamic array. Multi-dimensional open arrays are currently considered
to have one
dimension only in the debugger symbol table (DST).
-7- Oberon-2's dynamic arrays, created with NEW can not be examined
directly. The pointer
variable to such a dymamic array points to a descriptor which
consists of a list of dimensions
and a pointer to the actual array data, all quadword size.
-8- Constant and type identifiers are not known to the debugger.
-9- Dynamic type of a pointer is not known by the debugger. Use
module Objects and
Objects_Types (Types with AlphaOberon) to access the run-time
type name information.
For debugging it is recommended to declare temporary variables
of the appropriate static
record types, to be able to examine all associated fields and
elements of the pointer's base
type. This is accomplished by using a with-statement to select
the dynamic type and assign
the record data to a temporary record variable of the correct
static type. Another possibility is
to use low-level debugger features. The debugger is able to cast
the type of a variable
(examine/type=...; see OpenVMS-debugger manual), but this means
you must either know
the type name or retrieve the dynamic type name using procedure
Objects_Types.TypeName
-10- For multi-dimensional arrays (whose type is static) use the
notation a[i][j] instead of
a[i,j], for index-ranges use a[m:n].
-11- Single- or multi-dimensional dynamic arrays are implemented
as pointer to a
contiguous data block consisting of descriptor and array data
values. The descriptor consts
of n entries with the maximal index for a n-dimensional array
LEN(a, 0..n-1) and a pointer to
the first data element. Examining dynamic arrays is currently
not directly supported by the
debugger.
-12- The type SYSTEM.PTR is treated as ADDRESS_32 or ADDRESS_64
depending on
/pointersize.
Note, with AlphaOberon, the OpenVMS debugger can't be used. AlphaOberon
features a
post-mortem debugger which displays a symbolic procedure trace-back
and the contents of
all local variables (of basic type) of the invocation call chain.
A run-time debugger, based on
University Linz's RTD, is also available. In contrast to the
OpenVMS debugger, RTD can
handle variable of dynamic type as well as multi-dimensional
open and dynamic arrays.
The basic addressable unit is the 8-bit byte on the VAX-11 and
32 bit word on Alpha. On
Alpha, the compiler can generate code to deal with smaller types
and unaligned access.
In the following list for each data type the number of bytes
needed in memory and the
representation of the values is indicated.
SIGNED_8 Needs one byte in memory. Minimal value -128; maximal
value 127. The type
SIGNED_8 is implemented using the VAX-11 signed byte integer
data type: bit 7 is
the sign bit; bit 6 is the most significant bit. For arithmetic
on Alpha, bit 7 is
propagated into bits 8 to 63.
SIGNED_16 (in module SYSTEM) Needs two bytes in memory Minimal
value -65536;
maximal value 65535. The type SIGNED_16 is implemented using
the VAX-11
signed word integer data type: bit 15 is the sign bit; bit 14
is the most significant bit.
For arithmetic on Alpha, bit 15 is propagated into bits 16 to
63.
SIGNED_32 Needs four bytes in memory. Minimal value -2'147'483'648;
maximal value
2'147'483'647. The type SIGNED_32 is implemented using the VAX-11
signed long
integer data type: bit 31 is the sign bit; bit 30 is the most
significant bit. For arithmetic
on Alpha, bit 31 is propagated into bits 32 to 63.
SIGNED_64 (in module SYSTEM; A2O only) Needs eight bytes in memory.
Bit 63 is the
sign bit; bit 62 is the most significant bit. All relational
and arithmetic operators as
defined for SIGNED_32 are also defined for SIGNED_64.
UNSIGNED_32 (in module SYSTEM) needs four bytes (32 bits) in memory.
No arithmetic
or relational operations are currently allowed on this type.
UNSIGNED_64 (in module SYSTEM; A2O only) needs eight bytes (64
bits) in memory.
No arithmetic or relational operations are currently allowed
on this type.
SHORTINT If the compilation option /NoInteger is selected, this
type is identical to
SIGNED_8, otherwise this type is not known (pervasive).
INTEGER If the compilation option /NoInteger is selected, this
type is identical to
SIGNED_16, otherwise the pervasive type INTEGER is identical
to SIGNED_x,
where x determined by the compilation option /pointersize=x,
with x either 32 or 64.
LONGINT If the compilation option /NoInteger is selected, this
type is identical to
SIGNED_x, where x determined by the compilation option /pointersize=x,
with x
either 32 or 64. Otherwise, if the compilation option /Integer
is selected, this type is
not known (pervasive).
BOOLEAN Needs one byte (8 bits) in memory. The type must be considered
as an
enumeration (FALSE,TRUE) with the values FALSE = 0 and TRUE =
1 (bit 0). Other
values may cause problems.
CHAR Needs one byte (8 bits) in memory. ASCII character set is
used. The
implementation guarantees for variables the range 0..255 (octal
0B..377B).
Constants in the range 0X..0FFX or equivalently CHR(0)..CHR(255)
are allowed.
REAL Needs four bytes (32 bits) in memory. The type REAL is implemented
using the
VAX-11 F-FLOATING data type. On Alpha, REAL is S_FLOATING with
/IEEE
compilation option.
LONGREAL Needs eight bytes (64 bits) in memory. The type REAL
is implemented using
the VAX-11 D-FLOATING data type. On Alpha, LONGREAL is T_FLOATING
with
/IEEE compilation option.
COMPLEX Needs eight bytes (64 bits) in memory. The type COMPLEX
is implemented
using real and imaginary number part of the VAX-11 F-FLOATING
data type. On
Alpha, the base type of COMPLEX is S_FLOATING with /IEEE compilation
option.
This type is known only in combination with the compilation qualifier
/COMPLEX. No
operations are currently allowed with this type.
LONGCOMPLEX Needs eight bytes (128 bits) in memory. The type LONGCOMPLEX
is
implemented using real and imaginary number part of the VAX-11
D-FLOATING data
type. On Alpha, the base type of COMPLEX is T_FLOATING with /IEEE
compilation
option. This type is known only in combination with the compilation
qualifier
/COMPLEX. No operations are currently allowed with this type.
SET Needs four bytes (32 bits) in memory (suffix "H" means hexadecimal).
Examples:
SYSTEM.VAL(SYSTEM.SIGNED_32, {}) is 00000000H (empty set)
SYSTEM.VAL(SYSTEM.SIGNED_32, {0}) is 00000001H (bit 0)
SYSTEM.VAL(SYSTEM.SIGNED_32, {1}) is 00000002H (bit 1)
. . .
SYSTEM.VAL(SYSTEM.SIGNED_32, {30}) is 40000000H (bit 30)
SYSTEM.VAL(SYSTEM.SIGNED_32, {31}) is 80000000H (bit 31)
SYSTEM.VAL(SYSTEM.SIGNED_32, {0..31}) is 0FFFFFFFFH (bit 31)
LONGSET Needs four bytes (64 bits) in memory (suffix "S" means
hexadecimal).
Examples:
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{}) is 0000000000000000S (empty
set)
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{0}) is 0000000000000001S
(bit 0)
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{1}) is 0000000000000002S
(bit 1)
. . .
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{30}) is 0000000040000000S
(bit 30)
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{63}) is 8000000000000000S
(bit 63)
SYSTEM.VAL(SYSTEM.SIGNED_64, LONGSET{0..63}) is 0FFFFFFFFFFFFFFFFS
(bit 63)
Enumerations Not available in Oberon-2. Their allocation is shown
here, to be able to
interface to Modula-2 data types: Needs one byte (8 bits) if
type contains 256 or less
elements; Needs two bytes (16 bits) if type contains more than
256 elements. The
first value of the enumeration is represented by the integer
value 0; the following
enumeration values get the next integer values accordingly.
Subranges Not available in Oberon-2. Their allocation is shown
here, to be able to
interface to Modula-2 data types: Subrange Types are represented
according to
their base type.
Pointer types Need four bytes (32 bits) with /pointersize=32 or
eight bytes (64 bits) with
/pointersize=64 (A2O only) in memory. Pointers are implemented
as virtual addresses in
process space (VAX: 32 bits, Alpha: 64 bits). NIL is represented
by the value 0. The
so-called type-tag is stored at offset -4 (H2O) and -8 (A2O)
of the pointer value. The
pervasive procedure NEW automatically allocates additional storage
needed for the
record or array descriptors.
Record types Records are stored field by field. Each field is
allocated according to its type
and aligned on a byte boundary, in their declaration order. With
the default
/unpacked_record compilation option, elements are naturally aligned:
If the field is of
pervasive type T, the record offset is a multiple of MIN( SIZE(T),
8). If the field is of record
type T, the record offset is aligned according to the largest
pervasive type within type T. If
the field is of array type, the record offset is aligned according
to the element type.
A type descriptor (type tag) containing information about associated
type bound
procedures, record key values of possible base types together
with symbolic type names
and type size are stored in separate read-only program section
in the object file.
Array types An array is stored and aligned according to the type
of its elements. Every
element is also aligned according to its type.
Dynamic array types Are implemented as pointers to dynamic array
descriptors (see
pointer types above).
BYTE One byte is needed in memory.
LOC One byte is needed in memory. Synonym for BYTE.
SHORTWORD Two bytes are needed in memory.
WORD Four bytes are needed in memory.
LONGWORD Four bytes are needed in memory. Synonym for WORD.
QUADWORD Eight bytes are needed in memory.
OCTAWORD Sixteen bytes are needed in memory.
ADDRESS_32 Four bytes are needed in memory (POINTER TO BYTE).
ADDRESS_64 Eight bytes are needed in memory (POINTER TO BYTE).
PTR Is identical to ADDRESS_32 with /pointersize=32 or identical
to ADDRESS_64 with
/pointersize=64 (A2O only). PTR represents the byte address of
a storage location. Any
pointer can be assigned to PTR. A formal variable parameter of
type PTR allows to
substitute any pointer variable as actual parameter. PTR is equivalent
to Modula-2's
SYSTEM.ADDRESS, but no arithmetic operators apply to this type.
To do address
arithmetic use SYSTEM.VAL to cast PTR to LONGINT.
F_FLOATING Four bytes (32 bits) are needed in memory. With /noieee
synonym for the
type REAL.
D_FLOATING Eight bytes (64 bits) are needed in memory. With /noieee
synonym for the
type LONGREAL.
G_FLOATING Eight bytes (64 bits) are needed in memory.
S_FLOATING Four bytes (32 bits) are needed in memory. With /ieee
synonym for the type
REAL. A2O only.
T_FLOATING Eight bytes (64 bits) are needed in memory. With /ieee
synonym for the type
LONGREAL. A2O only.
H_FLOATING Sixteen bytes (128 bits) are needed in memory. With
/axp synonym for the
type G_FLOATING.
F_COMPLEX Eight bytes (64 bits) are needed in memory. With /complex/noieee
synonym
for the type COMPLEX.
D_COMPLEX Sixteen bytes (128 bits) are needed in memory. With
/complex/noieee
synonym for the type LONGCOMPLEX.
G_COMPLEX Sixteen bytes (128 bits) are needed in memory.
S_COMPLEX Eight bytes (64 bits) are needed in memory. With /complex/ieee
synonym for
the type COMPLEX. A2O only.
T_COMPLEX Sixteen bytes (128 bits) are needed in memory. With
/complex/ieee synonym
for the type LONGCOMPLEX. A2O only.
H_COMPLEX Sixteen bytes (128 bits) are needed in memory. With
/axp synonym for the
type G_COMPLEX.
NIL In addition to the purposes described in the Oberon-2 Report,
NIL serves as a hidden
constant used to indicate that no actual parameter is substitued
in a call of a foreign
procedure declared in a so-called foreign interface module (FIM)
(see 6.3) where the
formal parameter passing specification is "optionalPar" (...$O).
Substitution of NIL as
actual parameter in a procedure call is only allowed if the coresponding
formal parameter
of the called procedure is specified to be optional. In this
case NIL is compatible with any
data type even when the formal parameter is a variable parameter
(VAR).
Access violation at run-time may result in case of abuse of NIL.
NIL is the only way to
indicate omission of parameters. But there is another way to
have different declarations
for the same procedure: The module name of a FIM is ignored at
link time. This allows to
omit trailing parameters in the declaration. Assume the system
service sys$optional is
specified to have an optional second parameters. It can be declared
in and imported from
two FIMs with different declaration:
In the context of the OpenVMS operating system, a procedure is
a routine entered by a
CALL (VAX) or JSR (Alpha) instruction. In a Oberon-2 program,
such a routine can be a
function or a procedure written in Oberon-2 an OpenVMS system
service routine, a
Run-Time Library (RTL) procedure or a procdure written in a foreign
language.
This chapter provides information on calling conventions used
by the OpenVMS
Oberon-2 compiler and on calling OpenVMS system services and
OpenVMS RTL
procedures. A basic knowledge of the OpenVMS procedure calling
and argument passing
mechanisms is assumed. For more information see the OpenVMS Run-Time
Library
Reference Manual and the VAX or Alpha linker reference and calling
conventions as well
as the processor architecture handbook.
OpenVMS VAX Oberon-2 uses the VAX-11 CALLS instruction to call
procedures. Each
time a procedure is called, the Oberon-2 compiler constructs
an argument list on the
stack. The arguments in the list are based on the parameter type
and the parameter kind
(value or reference) specified in the formal parameter list and
the values in the actual
parameter list.
OpenVMS Alpha Oberon-2 uses the Alpha JSR instruction to call
procedures. Each time
a procedure is called, the Oberon-2 compiler stores the address
of first 6 arguments in the
processor registers R16 to R21. This is the standard OpenVMS
parameter passing mode,
for value and variable parameter.
Only in system services, RTL routines or foreign procedures, the
parameter passing
mode could be by immediate value. In this case, the values are
passed in R16 to R21
when integer or in F16 to F21 when floating point. Complex data
types are passed as a
pair of floating point values (real and imaginary part); they
are passed in consecutive
places. If there are more than 6 parameters, the compiler constructs
a quadword aligned
argument list on the stack. The arguments in the list are based
on the parameter type and
the parameter kind (value or reference) specified in the formal
parameter list and the
values in the actual parameter list.
The OpenVMS procedure calling standard defines three mechanisms
by which
arguments are passed to procedures:
1. by-reference
2. by-immediate-value
3. by-descriptor
The following table describes the mechanisms that are used by
the OpenVMS Oberon-2
compiler, depending on the type and the kind of the formal parameter.
The additional data
types of the Modula-2 language, marked by an "*", are also shown
for the case of mixed
language programmming.
An open array parameter is passed by n+1 arguments, where n is
the number of
dimensions.
The parameter list created by the compiler for the open array
formal parameter definition
(...; [VAR] A: ARRAY OF [ARRAY...] type; ...)
is equivalent to the following foreign parameter definition (see
6.3 for a description of the
$I-suffix)
(...; high_0$I: CARDINAL; [high_1$I: CARDINAL; ...] adrA$I : SYSTEM.PTR;
...)
with adrA$I = ADR(A) and high_n$I = LEN(A, n)-1. In case of a
value parameter, the
called procedure is reponsible for making a local copy of the
array on the stack. This is
automatically done in the entry or prologue code of procedure.
Variable Record Parameters:
The parameter list created by the compiler for the formal variable
record parameter
definition
(...; VAR R: Record_Type; ...)
is equivalent to the following foreign parameter definition (see
6.3 for a description of the
$I- and $R-suffixes)
(...; tag$I: CARDINAL; adrR$I : SYSTEM.PTR; ...)
with adrr$I = ADR(R) and tag$I = record type tag pointer value
which points to the
records base type with extension level 0 (key[0]).
A function returns a value to the calling program. The method
by which a value is returned
depends on its type as listed below:
Access to procedures written in other VAX|Alpha programming languages,
especially to
the OpenVMS system services and Run-Time Library routines, and
access to external
variables (global symbols) of any type including any procedure
types is provided through
special modules, so-called foreign interface or definitions modules
(FIMs). They serve
only to export the descriptions (symbol file) of the respective
procedures and have no
corresponding Oberon-2 implementation modules.
Motivation: The goal was not to extend the Oberon-2 syntax with
additional keywords
%FOREIGN, %IMMED, %STDESCR, and %REF as in Modula-2 (MaX|MVR).
The
simplest syntactic extension with the at least the power of expressiveness
compared to
Modula-2 (MaX|MVR) was to allow dollar-signs in identifiers within
a limited scope of FIMs
only. Since under OpenVMS all operating system service routines
contain at least one
"$"-sign in their names, this extension of the syntax for Oberon-2
identifiers could not be
avoided.
A "$"-sign contained anywhere in the module name defines the module
being a FIM. This
is no limitation of the scope for module names, since the compiler
declares all entries
exported in the interface as external symbols. The name of a
FIM is ignored at the linker
level. Note, in Modula-2 (MaX|MVR), this is accomplished by the
keyword "%FOREIGN"
which prefixes the keywords "DEFINITION MODULE".
There is no different syntax for an Oberon-2 FIM. This means that
procedure declarations
must have a "END proc_name". The procedure's body "BEGIN " before
the "END
proc_name" is optional as defined in the Oberon-2 Report. But
it is recommended to use
only
PROCEDURE proc_name ...; END proc_name;
instead of
PROCEDURE proc_name ...; BEGIN END proc_name;
because Oberon-2 syntactically requires a "RETURN expression"
if the procedure is a
function.
This section contains the formal definitions of foreign procedures
and variables to be linked
to Oberon-2 programs. Procedure and variable names must be known
to the linker and the
calling convention must match at the linker level.
To allow full utilisation of the OpenVMS procedure calling standard,
additional parameter
passing specifiers have been introduced for parameter names,
applicable only within FIMs
(Modula-2 notation):
Oberon-2 parameter name suffixes defining parameter passing mechanism:
...$I denotes
passing by immediate value; not allowed for
formal parameter being open array or VAR parameter.
Parameter's type size must be either
1, 2, 3, 4, 8, 12, or 16 bytes
(in Modula-2: %IMMED p: T). On Alpha, complex data types
are treated as two paramters (real and imaginary part)
...$R denotes
passing by reference; allowed for variable
or value formal parameters, but makes sense only for
open arrays or VAR record types (in this case, ...$N
is implied), because otherwise this is the default mechanism.
(in Modula-2: [VAR] %REF p: T)
...$N denotes
passing by reference without Oberon-2's additional
type descriptor provided for any VAR parameter record (VarParRec).
Only allowed for variable formal parameters of record type.
(Modula-2 has no type descriptors/tags;
MaX uses a dummy tag with value 0 to be compatible with A2O;
MVR does not know about VarParRec tags.)
...$O denotes
optional parameter for any parameter type
(value and variable); it can be used as well as other suffixes.
...$O implies ...$N (no type descriptor).
An actual parameter being a constant expression with
the value NIL or 0 indicates parameter omission. ...$O makes
only sense for parameter values passed by reference.
Immediate
parameters can't be optional, otherwise the called
routine can't detect whether the caller wants to pass a NIL
value or whether the parameter is omitted. (In Modula-2,
SYSTEM.NOP serves the same purpose as NIL in H2O|A2O)
...$S denotes
passing by string descriptor; to be used only
for one-dimensional open arrays with element type CHAR.
A manually constructed variable of record TYPE
STDESCR* = RECORD len: LONGINT; a: SYSTEM.PTR END;
could also be used with parameter passing specification
...$R (see above).
(in Modula-2: [VAR] %STDESCR s: ARRAY OF CHAR)
Note, that these ...$x suffixes can't be combined. Only one suffix
is evaluated.
As an example, a FIM called CommandLangInterface$ is shown which
allows access to
some screen handling procedures:
Warning: Foreign definition modules should not be written without
knowledge about the
parameter passing mechanisms involved. See example in Appendix
(Examples for
foreign language interface definitions).
There are applications (e.g., system programming) for which the
language rules may turn
out to be too restrictive. For this reason, Oberon-2 provides
some means for "low level
programming"; most of them are implementation dependent.
The programmer is urged to use these low level facilities very
carefully and only if it
seems unavoidable. He will be much less protected against errors
because low level
facilities are not checked for consistency with language rules.
Clarifications:
VAL (T, expression) allowed where an expression of type T is allowed.
VAL (T, variable_designator) allowed where an expression or variable
designator of type
T is allowed. This is not a language extension, its a feature
of the ETH Oberon-2 front-end
used in H2O|A2O (Crelier's OP2).
VAL changes the type of the second parameter. VAL does not involve
any actual
computation but modify the compiler's type checking. For instance,
if c is an expression of
type LONGINT then VAL(SET,c) is interpreted as the corresponding
value of type SET.
This is a correspondance determined by the underlying system
and not by the
programming language itself. Therefore, using type transfer functions
requires familiarity
with the internal representation and storage allocation scheme
of the corresponding data
types. In contrast to Modula-2 where code is generated for transfers
from and to
SYSTEM's word types with different sizes (zero fill-in of most
significant bits), Oberon-2
simply takes the source expression or designator with the size
of the target type T.
SYSTEM.CAST (T, expression) defined as in ISO Modula-2 (minimum
of size of T or type
size of expression is taken).
Module SYSTEM offers some further facilities of the Oberon-2 language.
Most of them
are implementation dependent and/or refer to the given processor.
Facilities of that kind
are sometimes necessary for the so called "low level programming".
The module SYSTEM is known to the compiler because its exported
objects obey special
rules, that must be checked by the compiler. If a compilation
unit imports objects from
module SYSTEM, no symbol file has to be supplied for this module.
Objects exported from module SYSTEM are constants, types, procedures
and function
procedures. Module SYSTEM is defined in the Oberon-2 Report.
The following lists only
extensions and clarifications:
Constants exported from SYSTEM: none.
Types exported from SYSTEM:
BYTE (=LOC), SHORTWORD, WORD (=LONGWORD), QUADWORD, OCTAWORD
Objects of these types represent individually accessible storage
units (BYTE = one byte,
SHORTWORD = two bytes, WORD = four bytes, QUADWORD = eight bytes,
OCTAWORD = sixteen bytes). Only assignment is allowed for variables
of these types.
A parameter of type BYTE, SHORTWORD, WORD, QUADWORD or OCTAWORD
may
be substituted by an actual parameter of any type with the same
size or if the size of the
formal and actual parameter differs, up-to the size of the formal
paramter (maximum
WORD on VAX and QUADWORD on Alpha). The same holds for the substitution
of a
variable open array parameter with elements of type BYTE, SHORTWORD,
WORD,
QUADWORD or OCTAWORD by a value of a type which size is not an
integral multiple of
the open array element size.
PTR (Modula-2's ADDRESS) Objects of type PTR represent the byte
address of a
storage location.
F_FLOATING, D_FLOATING, G_FLOATING, S_FLOATING, T_FLOATING,
H_FLOATING
The Oberon-2 standard type REAL is implemented using the VAX-11
F_FLOATING data
type. The other VAX-11 floating point data types are made available
in the VAX-11
Oberon-2 compiler through export from module SYSTEM.
All operators defined in Oberon-2 for the type pervasive type
REAL are also defined for
the types F_FLOATING, D_FLOATING, G_FLOATING, S_FLOATING T_FLOATING
and
H_FLOATING.
With the /ieee/axp compilation option, the type of floating point
literals is S_FLOATING or
T_FLOATING, whereas /noieee sets the literal types to F_FLOATING
or D_FLOATING.
Constant expressions of foating point type are evaluated at compile
time.
The Oberon-2 compiler doesn't allow constants to be of type G_FLOATING
or
H_FLOATING.
Also, in contrast to Modula-2, different floating point types
can be mixed in expressions
(i.e., there is implicit conversion) except from G_ to D_ and
vice versa. The standard
procedures ENTIER and SYSTEM.LENTIER are applicable to all floating
point data types.
Functions exported from SYSTEM:
PROCEDURE ADR(designator): LONGINT;
Returns the storage address of the variable or string constant
argument. Clarification:
Constant strings are also allowed as argument of ADR. This is
not a language extension; it is
allowed by OP2.
Description of other functions is contained in the Oberon-2 Report.
PROCEDURE LENGTH (s: ARRAY OF CHAR): LONGINT;
Returns the length of a string as defined in ISO Modula-2. Restriction
for VAX only: The VAX
instruction LOCC is used and hence the return value must be in
the range between 0 and
65535. See also Appendix (Restrictions, extensions and clarifications).
PROCEDURE SYSTEM.LENTIER (t: SYSTEM.T_FLOATING): SYSTEM.SIGNED_64;
converts a floating point argument to 64 bit integer (A2O only)
with the semantics of the
pervasive function ENTIER. With /pointersize=64, SYSTEM.LENTIER
is synonymous with
the pervasive function procedure ENTIER.
Procedures exported from SYSTEM:
PROCEDURE SYSTEM.NEW (VAR p: SYSTEM.PTR; n: LONGINT);
allocates n bytes of storage on the heap. SYSTEM.NEW is the same
as pervasive
procedure NEW, except that no type descriptor is allocated for
p. With A2O, a type
descriptor (sysblock) is always generated (needed by Garbage
Collector).
Register access:
SYSTEM.GETREG(n, v)
n must be a constant expression. 0<= num <= 31; if num=31
is used, 0 is returned (R31/F31
is read-as-zero, RAZ).
SYSTEM.PUTREG(n, x)
n must be a constant expression. 0<= num <= 31; if num=31
is used, R31/F31 is not modified
(these registers are always zero).
The Alpha has two disjoint sets of integer and floating point
registers. The argument type of
the variable v and expression x in GETREG and PUTREG determines
whether an integer or
floating point register is used.
Exception handling support for OpenVMS Alpha (A2O only):
The way exception handling (LIB$ESTABLISH and LIB$REVERT) work
on OpenVMS
Alpha changed radically when compared to OpenVMS VAX, in that
these routines are no
longer available in the run-time system and in fact they can't
be implemented as routines.
Two functions procedures are exported from SYSTEM and they produce
in-line code. The
exception model chosen is dynamic. The declaration of the SYSTEM
functions
LIB$ESTABLISH and LIB$REVERT is
PROCEDURE SYSTEM.ESTABLISH (handle$I: HANDLER): HANDLER;
PROCEDURE SYSTEM.REVERT(): HANDLER;
The result type of both functions is of type HANDLER and the parameter
of ESTABLISH
should be structurally compatible with
HANDLER = PROCEDURE(VAR sigargs: SigArgs; mechArgs: MechArgs):
LONGINT;
but the compiler does not check this type; it requires a proc
type with LONGINT function
result. Note, the type HANDLER is not exported from SYSTEM. The
foreign interface
module VMS$Exceptions declares all types and procedures necessary
for exception
handling.
Module Test_Exceptions illustrates how to catch and process an
exception in Oberon-2 under OpenVMS Alpha.
H2O stand-alone programs: The storage management procedures ALLOCATE
and
DEALLOCATE which serve to dynamically obtain and return storage
space can be
imported from the library module Storage:
PROCEDURE ALLOCATE (VAR p: SYSTEM.PTR; size: SYSTEM.SIGNED_32);
PROCEDURE DEALLOCATE (VAR p: SYSTEM.PTR; size: SYSTEM.SIGNED_32);
The pervasive procedure NEW internally calls LIB$GET_VM from within
the Oberon-2
run-time system (MOD$MEMALLOC).
A2O stand-alone programs: The pervasive procedures NEW and SYSTEM.NEW
internally call
- Storage64.ALLOCATE_32 with /pointersize=32
- Storage64.ALLOCATE with /pointersize=64. Before the call of ALLOCATE[_32], the compiler generates code
to add the tag- and the
descriptor-size to the size to be allocated and rounds the total
size up to a multiple of 32
bytes.
Dispose is not featured by the Oberon-2 language. Normally a garbage
collector (GC)
retrieves unreachable memory blocks under certain conditions
at specific events when
running under control of an Oberon System. In contrast to AlphaOberon,
stand-alone
applications generated with A2O|H2O under OpenVMS don't have
a GC.
To dispose (recover) heap space which is no longer needed, explicit
calls are necessary
for stand-alone programs. Since module Storage calls procedure
LIB$GET_VM for ALLOCATE, its complement procedure Storage.DEALLOCATE could be
used in
stand-alone Oberon-2 to dispose storage. This feature must used
with utmost care. In
particular, disposal of a pointer shall also deallocate the type
descriptor. Module
Objects_Types (see 7.3.1) exports disposal procedures, which
allow to dispose objects
depending on their dynamic type.
Storage.ALLOCATE[_32] signals an OpenVMS exception whenever there
is not enough
free heap space (virtual memory limit).
When writing your own storage management procedures you should
care for an appropriate
declaration.
The following table summarizes the storage allocation and alignment
for variables of
unstructured and set type. Note that "word", "longword", "quadword",
and "octaword" are
DEC-terms. (A "*" marks Modula-2 types):
Variables of Modula-2 subrange type are allocated and aligned
in the same way as
variables of their base type.
An array is stored and aligned according to the type of its elements.
Every element is also
aligned according to its type.
Records are stored field by field. Each field is allocated according
to its type and aligned
on a byte boundary (see also /packed_record compilation qualifier).
The associated type
tag is allocated separately in a read-only program section (stand-alone
programs).
Local variables on the stack are always aligned on a 4 byte boundary,
(longword aligned on
VAX) and 8 byte boundary (quadword aligned on Alpha).
Module Objects_Types is a low level run-time system module written
in Oberon-2. It is
indirectly called by any module body during initialisation phase
to register all module
names. If a module declares any non-anonymous record types, their
type names are also
registered.
H2O only: The call to the Oberon-2 run-time-system procedure mod$storemodobjects
(which is part of the module ModRTS in library Modula.OLB) is
automatically peformed
after calling the initialisation part of any imported modules.
A2O only: The call to Objects_Types.StoreModObjects is automatically
peformed after
calling the initialisation part of any imported modules.
Objects_Types exports procedures for type-to-name, name-to-type
conversion,
allocation, cloning and disposal of objects. Module Objects_Types
is described in The ModulaTor, Vol. 3, Nr. 1 (Feb-1993).
Module Types is a low level run-time system module written in
Oberon-2. It accesses the
type information constructed during module loading
Types exports procedures for type-to-name, name-to-type conversion,
allocation, and
cloning of objects. Disposal of unreachable objects is the task
of the GC. The generic module Objects provides the so-called load/store-mechanism
for persistent
objects. There are two implementations:
- For stand-alone programs, Objects is based on the above module
Objects_Types and
ISO Modula-2 library modules IOChan and RawIO.
- For AlphaOberon, Objects is based on the above module Types
and Oberon System
modules Files and Modules
Module Objects is described in detail in Chap. 8 (persistent objects)
in OOPiO2 and in
The ModulaTor, Vol. 3, Nr. 1 (Feb-1993). The latter contains
full source code and an
application example illustrating so-called up-calls.
In order to provide the user with a first entry into the use of
the Oberon-2 Compiler, a
complete example how to compile, link and execute a Oberon-2
program that consists of
several modules is shown in the following. All inputs to be made
by the user are on lines
marked by the OpenVMS-"$"-prompt. Program output is printed in
Courier font.
Suppose you have two source files,
a module EXAMPLE.MOD,
APPENDIX C: RESTRICTIONS, EXTENSIONS and CLARIFICATIONS
Oberon-2 programmers developing stand-alone applications are encouraged
to use the
ISO Modula-2 Standard Library. The full set of their Oberon-2
interface modules are
provided with the A2O|H2O distribution kit.
The annotated interface definition modules have the file extension
.DEF; their associated
Oberon-2 interface definition modules have the extension .MOD.
The definition modules
for the ISO Modula-2 Standard Library are also listed in The
ModulaTor, Sep-1992.
When migrating from ModulaWare's Modula-2 to Oberon-2: The Oberon-2
interface
modules for the Modula-2 Uni* library are not part of the A2O|H2O
distribution kit. If
certain modules are needed when migrating from Modula-2 to Oberon-2,
their interfaces
must be converted manually.
D.4.1 Status Codes, Function Codes and other OpenVMS Constants
The following is a list of the foreign interface modules/file
names that are distributed with
the A2O|H2O distribution kit.
The module names are constructed out of the first two or three
or four characters of the
file name followed by "$" and the word "Definitions", and then
shortened to 9 characters.
For example the module contained in CLI$DEFIN.DEF is named CLI$Definitions.
The
definitions of this service was extracted from the $CLIDEF Macro.
All modules containing a "$"-sign in the module/file name are
foreign interface modules
without Modula-2 or Oberon-2 implementation.
Modules with the extension .DEF are Oberon-2 interface definitions
for the Modula-2
implementation module located in MOD$SYSTEM:Modula.OLB.
Modules with the extension .MOD are Oberon-2 source modules.
Modules with the extension .MOC are encrypted Oberon-2 source
modules.
ModulaWare developed a tool ForeignDefToO2 (written in Oberon-2),
which
semi-automatically converts Modula-2's foreign definition modules
and proper definition
modules to Oberon-2.
If you require further modules such as PPL or UIS (VWS) or if
you have special Modula-2
foreign interface modules, please contact ModulaWare.
Quality of generated:
When comparing the execution time of programs written in Oberon-2
and DEC Fortran77
or DEC Pascal one must take into account, that the Oberon Compiler
doesn't produce a
highly optimized code, except for
- Evaluation of constant expression at compile time.
- Boolean expression with one constant operand: (TRUE & x)
and (FALSE OR x) are
replaced by x.
- Dead code elimination: unreachable code due to a constant condition
in an
IF-ELSIF-ELSE statement is removed.
- Conversions: conversions are never applied to constants. LONG(LONG(shortint))
and
SHORT(SHORT(longint)) need only one conversion, SHORT(LONG(i))
needs no
conversion, LONG(SHORT(i)) needs two conversions because of range
check.
- Integer multiplication by a power of two are replaced by arithmetic
shifts. Note, that due
to an implementation restriction with DIV and MOD, integer divison
by a power of two can
not be replaced by arithmetic shift and modulus by a power of
two can not be replaced by
a bit mask operation.
- LEN(a[expr1, expr2, ... exprn], n) is replaced by LEN(a,m+n).
- currently for H2O only: Assignments with common destination
and source designator of
the form a := a mostDyadicOperator b; are optimized. This is
especially usefull for
common designators being indexed or pointers.
But otherwise no optimization are done that can be done by the
programmer, e.g.
common subexpression elimination, procedure in-lining, etc..
Comparing Benchmark Results:
When comparing performance with Fortran, make a fair comparison
by using only local
variables, not global ones and don't use nested procedures with
access to variables of
outer local scope. Use VAR parameters for arrays and records
to force
paramater-passing by reference (like Fortran), to avoid that
the values are copied to the
procedure's stack frame.
Also note, that Oberon-2 is a safe and powerful language that
provides you with pointer
initialisation, full type safety, minimal but powerful object-oriented
language extensions,
run-time type information for dynamic data types, multi-dimensional
open and dynamic
arrays together with Modula-2's proven separate modul concept.
It is a good idea to use /nocheck when comparing code quality
with compilers that don't
check anything.
Avoid large CASE label ranges. Each value of the label's range
will produce an entry in a
jump table. Use the IF-statement instead:
Avoid the declaration of large local arrays which contain pointers
or local arrays of record
type which (maybe indirectly) contain pointer fields. Code is
generated to clear each of
these pointers variables in the entry code of the procedure.
This is a safety aspect in
stand-alone programs and a garbage collector requirement in AlphaOberon.
Disclaimer: The banner advertisement
at the top of this page is dynamically inserted by the web-site hosting service;
The banner image content and the URL it refers to is outside the responsibility of .zel.org.
Contact gd@
http://www.zel.org/aos/
CONTENTS
CHAPTER 1 USING Oberon-2 UNDER OpenVMS
1.1 CREATING AND EXECUTING A PROGRAM (OVERVIEW)
1.2 FILE SPECIFICATIONS AND DEFAULTS
CHAPTER 2 COMPILING A MODULE
2.1 THE H2O COMMAND
2.2 Oberon-2 COMPILER QUALIFIERS
2.3 LOCAL CONTROL OF RUN-TIME CHECKS
2.4 SEARCH STRATEGIES
2.5 Source Code Analyser
2.6 Conditional Compilation
CHAPTER 3 LINKING A PROGRAM
3.1 The Link Command
3.2 Linker Command Qualifiers
3.2.1 Map File Qualifiers
3.2.2 Debugging and Traceback Qualifiers
3.3 Identification Checking
CHAPTER 4 EXECUTING A PROGRAM
4.1 STARTING A PROGRAM
4.2 DEBUGGING A PROGRAM
CHAPTER 5 INTERNAL REPRESENTATIONOF DATA
5.1 BASIC TYPES
5.2 STRUCTURED TYPES
5.3 SYSTEM DEPENDENT TYPES
5.4 SYSTEM DEPENDENT CONSTANTS
CHAPTER 6 PROCEDURE CALLINGCONVENTIONS
6.1 Parameter Passing Mechanisms
6.2 Function Return Values
6.3 Foreign Procedures
CHAPTER 7 SYSTEM DEPENDENTFACILITIES
7.1 Low Level Facilities (module SYSTEM)
7.2 Storage Management
7.2.1 The Module Storage
7.2.2 Storage Allocation
7.3 Persistent Objects Support
7.3.1 Module Objects_Types (stand-alone programs)
7.3.2 Module Types (for AlphaOberon)
7.3.3 Module Objects
APPENDIX A COMPLETE EXAMPLE
APPENDIX B Oberon-2 Language Report
APPENDIX C RESTRICTIONS, EXTENSIONS and CLARIFICATIONS
APPENDIX D LIBRARY AND INTERFACEMODULES
APPENDIX E -
APPENDIX F -
APPENDIX G OpenVMS Oberon-2 & Oberon-2 HELP FILE
APPENDIX H A2O|H2O DATA SHEET
APPENDIX I Programming Hints
Preface
Manual Objectives:
Product Development History:
Alpha Oberon Support:
Language Definition:
Related documents:
The ModulaTor,
Modula-2 and Oberon-2 TechJournal:
Alpha and VAX Processor Manuals:
CHAPTER 1:
USING Oberon-2 UNDER OpenVMS
1.1 CREATING AND EXECUTING A PROGRAM (OVERVIEW)
1.2 FILE SPECIFICATIONS AND DEFAULTS
Oberon-2 and Modula-2 compiler:
Linker:
OBJ and OBJ64 input
to linker (default .OBJ)
CHAPTER 2:
COMPILING A MODULE
2.1 THE A2O|H2O COMMAND
Foreign interface modules: Proper modules:
If an error is detected in phase 1, then phases 2 and 3 are skipped
and finally if the /list
compilation qualifier (see below) is active, phase 4 is executed.
If phase 2 exhibits an
error, phase 3 will be skipped too. If an error occurs in phase
3 (these are only
implementation restrictions and limitations), no object file
is generated.
1. front-end 1. front-end (syntax-, declaration-
and body-analysis)
2. symbol file export 2. symbol file export
3. - 3. back-end (code-generation)
4. listing generation (optional) 4. listing generation (optional)
2.2 Oberon-2 COMPILER QUALIFIERS
| /PointerSize=32 | /PointerSize=64
LIST A listing file is written. The qualifier has the general
form: /LIST[=file-spec-list] You
may include a file specification for the listing file. If no
specification is given a file of
type MOD_LIS with the name of the source file is created. The
file contains at least
the source text and the error messages, but further listings
are added by applying
CROSS_ REFERENCE and/or MACHINE_CODE.
/NoInteger | 8/16/32 | 8/16/64
/Integer | -/32/- | -/64/-
Qualifier Negative Form Default
/ANALYSE [=(Aopt)] /NOANALYSE /NOANALYSE (all)
/AXP /NOAXP /NOAXP (H2O only)
/AXP (A2O only)
/CHECK [=(Copt)] /NOCHECK /CHECK (all)
/COMPLEX /NOCOMPLEX /NOCOMPLEX
/CROSS_REFERENCE /NOCROSS_... /NOCROSS_REFERENCE
/DEBUG /NODEBUG /NODEBUG
/DUMP_SYMFILE /NODUMP_SYMFILE /NODUMP_SYMFILE
/FOREIGN_CODE /NOFOREIGN_CODE /NOFOREIGN_CODE
/EXTEND_SYMFILE /NOEXTEND_SYMFILE /NOEXTEND_SYMFILE
/FINE_GRAINED_SYMFI/NOFINE_GRAINED_SYMF/NOFINE_GRAINED_SYMFILE
/IEEE /NOIEEE /NOIEEE (A2O only)
/IEEE with /OBERON_LOADFILE
/ISO /NOISO /NOISO (currently ignored)
/INSTRUCTIONMODE /NOINSTRUCTIONMODE /NOINSTRUCTIONMODE
[=(Copt)]
/INTEGER /NOINTEGER /NOINTEGER
/LIST[=file-spec] /NOLIST /NOLIST (interact.)
/LIST (batch)
/LOG /NOLOG /NOLOG (interactive)
/LOG (batch)
/MACHINE_CODE /NOMACHINE_CODE /NOMACHINE_CODE
/OBERON_LOADFILE /NOOBERON_LOADFILE /NOOBERON_LOADFILE (A2O only)
/OBJECT[=file-spec]/NOOBJECT /OBJECT
/OMIT_MODULE_NAME /NOOMIT_MODULE_NAME /NOOMIT_MODULE_NAME
/OPTIMIZE[=(Oopt)] / /OPTIMIZE (A2O only)
=(rotateSratch)
/PACKED_RECORD /NOPACKED_RECORD /NOPACKED_RECORD (A2O only)
/POINTERSIZE - /POINTERSIZE=32 (A2O only,
=64 only with OpenVMS 7.0 or later)
/NAME_SEPARATOR='x'/NONAME_SEPARATOR /NAME_SEPARATOR='.' (H2O)
/NAME_SEPARATOR='_' (A2O)
/QUERY /NOQUERY /NOQUERY
/SYMFIL[=file-spec]/NOSYMFILE /SYMFILE
/TRANSFER_VECTOR /NOTRANSFER_VECTOR /TRANSFER_VECTOR (H2O only)
/NOTRANSFER_VECTOR (obsolete
with A2O; usage reserved)
Aopt=(intermediate_items, count_statements,redefine_methods,
used_before_set, var_parameters, exported_items)
Copt=(stackcheck, indexcheck,typecheck, overflowcheck,
rangecheck, pointerinit, asserteval, heapinit)
Iopt=(FptTrapB, ChoppedDECRounding,SoftwareDECTrap,
UnderflowDECTrap, OverflowDECTrap, ChoppedIEEERounding,
DynamicRounding, PlusInftyRounding, MinusInftyRounding,
InexactIEEETrap, SoftwareIEEETrap, UnderflowIEEETrap,
OverflowIEEETrap, IntTrapB, IntOverflow)
Oopt=(schedule, alignCheck, rotatePreserved,
rotateScratch, hiddenWriteLc, hiddenWriteInst)
2.3 LOCAL CONTROL OF RUN-TIME CHECKS
2.4 SEARCH STRATEGIES
2.5 Oberon-2 Source Code Analyser
2.6 Conditional Compilation
CHAPTER 3:
LINKING A PROGRAM
3.1 The Link Command
3.2 Linker Command Qualifiers
3.2.1 Map File Qualifiers
3.2.2 Debugging and Traceback Qualifiers
Qualifier Negative Form Default
/BRIEF None Not applicable
/CROSS_REFERENCE /NOCROSS_...
/NOCROSS_REFERENCE
/DEBUG /NODEBUG /NODEBUG
/FULL None Not applicable
/MAP[=file-spec] /NOMAP /NOMAP (interactive)
/MAP (batch)
/TRACEBACK /NOTRACEBACK /TRACEBACK
3.3 Identification Checking
CHAPTER 4:
EXECUTING A PROGRAM
4.1 STARTING A PROGRAM
4.2 DEBUGGING A PROGRAM
CHAPTER 5:
INTERNAL REPRESENTATION OF DATA
5.1 BASIC TYPES
5.2 STRUCTURED TYPES
5.3 SYSTEM DEPENDENT TYPES (module SYSTEM)
5.4 SYSTEM DEPENDENT CONSTANTS
MODULE X$;
PROCEDURE sys$optional* (x1: LONGINT);
END sys$optional;
END X$.
MODULE Y$;
PROCEDURE sys$optional* (x1: LONGINT; x2$O: LONGINT);
END sys$optional;
END Y$.
MODULE user;
IMPORT X:=X$, Y:=Y$;
VAR x1, x2: LONGINT;
BEGIN
X.sys$optional(x1);
(* 2nd param omitted *)
Y.sys$optional(x1,NIL); (* 2nd param omitted
*)
Y.sys$optional(x1,x2);
END user.
CHAPTER 6:
PROCEDURE CALLING CONVENTIONS
6.1 Parameter Passing Mechanisms
type | value parameter | reference (VAR)parameter
--------------+----------------------+--------------------------
BOOLEAN | |
CHAR | |
SHORTINT | |
INTEGER | |
LONGINT | |
POINTER | |
SET | |
LONGSET | |
BYTE | |
SHORTWORD | |
WORD | |
PTR | |
ADDRESS_32 | |
ADDRESS_64 | |
REAL | |
LONGREAL | |
COMPLEX | |
LONGCOMPLEX | |
F_FLOATING | |
D_FLOATING | |
G_FLOATING | by-reference | by-reference
S_FLOATING | |
T_FLOATING | |
H_FLOATING | |
F_COMPLEX | |
D_COMPLEX | |
G_COMPLEX | |
S_COMPLEX | |
T_COMPLEX | |
H_COMPLEX | |
QUADWORD | |
SIGNED_64 | |
UNSIGNED_64 | |
OCTAWORD | |
CARDINAL* | |
BITSET* | |
Enumeration* | |
Subrange* | |
PROCESS* | |
--------------+----------------------+---------------------------------
RECORD | by-reference | by-reference(tag by value and
| | record address by reference;
| | in Modula-2, the tag value is 0)
--------------+----------------------+---------------------------------
ARRAY | by-reference | by-reference
--------------+----------------------+---------------------------------
PROCEDURE | entry address by-reference(VAX)
| address of the procedure descriptor by reference (Alpha)
--------------+----------------------+----------------------------------
Open Arrays:
6.2 Function Return Values
type | return method
--------------+--------------------------------------------
BOOLEAN |
CHAR |
SHORTINT |
INTEGER |
LONGINT |
SET |
LONGSET |
POINTER |
BYTE |
SHORTWORD |
WORD | Register R0
LONGWORD |
PTR |
ADDRESS_32 |
ADDRESS_64 |
CARDINAL* |
BITSET* |
Enumeration* |
Subrange* |
PROCESS* |
--------------+--------------------------------------------
REAL |
F_FLOATING | Register R0 (VAX); F0 (Alpha)
S_FLOATING |
--------------+--------------------------------------------
QUADWORD |
SIGNED_64 | Registers R0,R1 (VAX); R0 (Alpha)
ADDRESS_64 |
--------------+--------------------------------------------
LONGREAL |
D_FLOATING | Registers R0,R1 (VAX); F0 (Alpha)
G_FLOATING |
T_FLOATING |
--------------+--------------------------------------------
COMPLEX | Registers R0,R1 (VAX); F0,F1 (Alpha)
F_COMPLEX |
--------------+--------------------------------------------
LONGCOMPLEX | hiddenfirst variable parameter (VAX),
D_COMPLEX | i.e.: by reference as the first
G_COMPLEX | parameter in the function's
S_COMPLEX | parameter list;
T_COMPLEX | F0,F1 (Alpha)
H_FLOATING |
--------------+--------------------------------------------
OCTAWORD | hidden first variable parameter
--------------+--------------------------------------------
6.3 Foreign Procedures/Foreign Interface Modules
MODULE CommandLangInterface$;
TYPE CARDINAL* = LONGINT;
PROCEDURE CLI$PRESENT*
( entityDesc$S: ARRAY OF CHAR): CARDINAL;
PROCEDURE CLI$GET_VALUE*
( entityDesc$S: ARRAY OF CHAR;
VAR retdesc$S: ARRAY OF CHAR;
VAR retlength: CARDINAL): CARDINAL;
...
END CommandLangInterface$.
In contrast to Modula-2 (MVR), the Oberon-2 solution is more powerful
in respect to
external procedure variables. If a variable is of procedure type,
then their parameters can
also contain parameter passing specifiers.
CHAPTER 7:
SYSTEM DEPENDENT FACILITIES
7.1 Low Level Facilities: The Module SYSTEM
7.1.1 SYSTEM.VAL type casting (Type Transfer Functions)
7.1.2. SYSTEM.CAST (reserved, but not yet implemented)
7.1.3. Other facilities of module SYSTEM
MODULE VMSExceptions;
(*
\251 (1996) Guenter Dotzel
hG/19-Jun-1996: Record declarations for VMS$Exceptions
*)
IMPORT SYSTEM;
TYPE
LONGINT = SYSTEM.SIGNED_32;
ADDRESS *= LONGINT;
ADDRESS64*= SYSTEM.SIGNED_64;
INTEGER64*= SYSTEM.SIGNED_64;
MechArgs *= POINTER TO RECORD
args *: LONGINT;
flags *: SET;
frame *: ADDRESS64;
depth *: LONGINT;
resvdf1 *: LONGINT;
dAddr *: ADDRESS64;
esfAddr *: ADDRESS64;
sigAddr *: ADDRESS64;
savR *: ARRAY15 OF SYSTEM.QUADWORD;(*use indices below for access*)
savF *: ARRAY23 OF SYSTEM.QUADWORD;(*use indices below for access*)
sig64Addr *: ADDRESS64;
END;
SigArgs64* = POINTER TO RECORD
noArgs*,
ss_signal64* :LONGINT; (* = SS$SIGNAL64 *)
args* :ARRAY 257 OF INTEGER64;
END;
CONST (* LIBICB$K_INVO_CONTEXT_BLK_SIZE: *)
LIBICB_K_INVO_CONTEXT_BLK_SIZE = 544;
TYPE
InnerInvoContext = RECORD
length *: LONGINT;
flags *: SET; (* upper 8 bits are version byte *)
procDesc *: ADDRESS64;
progCnt *: ADDRESS64;
procStatus*: SYSTEM.QUADWORD; (* 64 bit flagfield *)
iReg *: ARRAY 31 OF SYSTEM.SIGNED_64;
fReg *: ARRAY 31 OF SYSTEM.QUADWORD;
END;
InvoContext *= RECORD (InnerInvoContext)
system: ARRAY LIBICB_K_INVO_CONTEXT_BLK_SIZE- SIZE(InnerInvoContext)
OF SYSTEM.BYTE;
END;
END VMSExceptions.
MODULE VMS$Exceptions;
(*
\251 (1996-1997) Guenter Dotzel
A2O version of MaX's foreign definition module VMS_Exceptions
GD/18-Aug-1995, hG/22-Aug-1995: corrected for AXP
hG/19-Jun-1996: moved record type defs into VMSExceptions.def
*)
IMPORT SYSTEM, SS := SS$Definitions, PSL := PSL$Definitions,
EX := VMSExceptions;
TYPE
LONGINT = SYSTEM.SIGNED_32; (* PP *)
ADDRESS *= LONGINT;
ADDRESS64*= SYSTEM.SIGNED_64;
INTEGER64*= SYSTEM.SIGNED_64;
SigArgs *= ARRAY 257 OF LONGINT;
CONST
(* NB. the SIGARGS() macro starts at 1 for sigArgs, and2 for sigName.
* But these here are indixes for the array *)
sigArgs *= 0; (* n = Additional Longwords *)
sigName *= 1;
(*sigPC *= n-1*)
(*sigPSL*= n *)
TYPE
MechArgs *= EX.MechArgs;
SigArgs64*= EX.SigArgs64;
CONST
savR0 *=0; savR1 *=1; savR16*=2; savR17*=3;savR18*=4; savR19*=5;
savR20*=6; savR21*=7; savR22*=8; savR23*=9;savR24*=10; savR25*=11;
savR26*=12; savR27*=13; savR28*=14;
savF0 *=0; savF1 *=1; savF10*=2; savF11*=3; savF12*=4; savF13*=5;
savF14*=6; savF15*=7; savF16*=8; savF17*=9; savF18*=10; savF19*=11;
savF20*=12; savF21*=13; savF22*=14; savF23*=15; savF24*=16;savF25*=17;
savF26*=18; savF27*=19; savF28*=20; savF29*=21; savF30*=22;
(* todo: add Continue_64 and Resignal_64 *)
SS$_RESIGNAL * = SS.SS$_RESIGNAL;
SS$_CONTINUE * = SS.SS$_CONTINUE;
SS$_UNWIND * = SS.SS$_UNWIND;
SS$_SIGNAL64 * = SS.SS$_SIGNAL64;
SS$_RESIGNAL_64 * = SS.SS$_RESIGNAL_64;
SS$_CONTINUE_64 * = SS.SS$_CONTINUE_64;
PSL$C_USER *= PSL.PSL$C_USER;
TYPE
ExceptionHandler * = PROCEDURE(VAR sigargs: SigArgs; mechArgs$I:MechArgs): LONGINT;
(* Oberon does not allow to declare $I parameters in non-foreignprocedures *)
OberonExceptionHandler * = PROCEDURE(VAR sigargs: SigArgs;mechArgs: MechArgs): LONGINT;
(*--- call chain stuff ---*)
CONST
LIBICB$V_EXCEPTION_FRAME *= 0;
LIBICB$V_AST_FRAME *= 1;
LIBICB$V_BOTTOM_OF_STACK *= 2;
LIBICB$V_BASE_FRAME *= 3;
LIBICB$K_INVO_HANDLE_SIZE *= 4;
TYPE
InvoContext *= EX.InvoContext;
Invo_Context *= InvoContext; (* VMS style aliases *)
Invo_Context_Blk *= InvoContext;
HANDLE *= LONGINT; (* invocationhandle, 4 Bytes *)
InvoHandle *= HANDLE;
Invo_Handle *= HANDLE;
CONST
LIB$K_INVO_HANDLE_NULL *= 0;
PROCEDURE LIB$GET_INVO_CONTEXT *(
invoHandle$I: InvoHandle;
VAR invoContext$N: InvoContext): BOOLEAN;
END LIB$GET_INVO_CONTEXT;
PROCEDURE LIB$GET_CURRENT_INVO_CONTEXT *(
VAR invoContext$N: InvoContext);
END LIB$GET_CURRENT_INVO_CONTEXT;
PROCEDURE LIB$GET_PREV_INVO_CONTEXT *(
VAR invoContext$N: InvoContext): LONGINT;
END LIB$GET_PREV_INVO_CONTEXT;
PROCEDURE LIB$GET_INVO_HANDLE *(
invoContext: InvoContext): InvoHandle;
END LIB$GET_INVO_HANDLE;
PROCEDURE LIB$GET_PREV_INVO_HANDLE *(
invoHandle$I: InvoHandle): InvoHandle;
END LIB$GET_PREV_INVO_HANDLE;
PROCEDURE LIB$SIG_TO_RET* (
VAR sigargs: SigArgs;
mechArgs: MechArgs): LONGINT;
END LIB$SIG_TO_RET;
PROCEDURE LIB$SIGNAL* (signal$I: LONGINT);
END LIB$SIGNAL;
PROCEDURE SYS$UNWIND* (
depadr$O: LONGINT;
newpc$I: ADDRESS): LONGINT;
END SYS$UNWIND;
PROCEDURE SYS$GOTO_UNWIND* (
targetInvo: InvoHandle;
targetPC$O: ADDRESS;
newR0$O,
newR1$O: INTEGER64): LONGINT;
END SYS$GOTO_UNWIND;
PROCEDURE SYS$PUTMSG* (
msgvec$I: ADDRESS64;
actrtn$I: ADDRESS64;
facnam$S: ARRAY OF CHAR; (* 32 or 64Bit Stringdescriptor*)
actprm$I: LONGINT): LONGINT;
END SYS$PUTMSG;
PROCEDURE SYS$SETEXV* (
vector$I: LONGINT;
newhnd$I: ExceptionHandler;
acmode$I: LONGINT;
VAR prvhnd$O: ExceptionHandler): LONGINT;
END SYS$SETEXV;
END VMS$Exceptions.
MODULE Test_Exceptions;
(* ModulaWare.com
Exception handling example for A2O Oberon-2 for OpenVMSAXP
DW/20-Jul-1994
GD/18-Aug-1995: transpiled into Oberon-2 for A2O
*)
IMPORT S:=SYSTEM, EX:=VMS$Exceptions, STextIO, SWholeIO;
VAR old: LONGINT; (*PROC;*)
i: LONGINT;
PROCEDURE MyHandler (VAR x: EX.SigArgs; y: EX.MechArgs): LONGINT;
VAR s: LONGINT;
BEGIN (* Convert exception to return condition value *)
(*DEC(x[EX.sigArgs],2);
s := EX.SYS$PUTMSG(S.ADR(x), 0, NIL, 0);
*)
RETURN EX.LIB$SIG_TO_RET(x, y);
END MyHandler;
PROCEDURE DivByZeroTry1():LONGINT;
VAR x,y: REAL;
BEGIN
old := S.ESTABLISH(EX.LIB$SIG_TO_RET);
y := 0.0;
x := 5.0 / y;
RETURN ENTIER(x);
END DivByZeroTry1;
PROCEDURE DivByZeroTry2():LONGINT;
VAR x,y: REAL;
BEGIN
old := S.ESTABLISH(MyHandler);
y := 0.0;
x := 5.0 / y;
RETURN ENTIER(x);
END DivByZeroTry2;
BEGIN
old := S.REVERT(); (* A NoOp - because LIB$ESTABLISH *)
i := 0;
(* has not been called yet *)
i := DivByZeroTry2();
IF ~ ODD(i) THEN
SWholeIO.WriteInt(i, 12);
STextIO.WriteString(" Arithmetic error in DivByZeroTry2");
STextIO.WriteLn;
END;
i := 0;
i := DivByZeroTry1();
IF ~ ODD(i) THEN
SWholeIO.WriteInt(i, 12);
STextIO.WriteString(" Arithmetic error in DivByZeroTry1");
STextIO.WriteLn;
EX.LIB$SIGNAL(i);
(* Re-raise exception *)
END;
END Test_Exceptions.
7.2 Storage Management
7.2.1 The Module Storage
MODULE Storage64;
(* Oberon-2 module for H2O by hG/18-Aug-1996
ALLOCATE, DEALLOCATE -> 64 bit pointers
ALLOCATE_32, DEALLOCATE_32 -> 32 bit pointers
GD/11-Oct-1997: ADDRESS_32, ADDRESS_64 eliminated
32 bit and 64 bit Storage module
[DE]ALLOCATE: 64 bit (VLM) with /pointersize=64
[DE]ALLOCATE: 32 bit with /pointersize=32
File Storage64.Mod
Copyright (1999) Guenter Dotzel, http://www.modulaware.com/
hG/19-Dec-1997: 64-bit version
GD/27-Jan-1999: automatic detection of VLM.
Uses LIB$GET_/LIB$FREE_VM instead of LIB$GET_/LIB$FREE_VM_64
when operating system version is pre V7.0 or /pointersize=32
*)
IMPORT SYSTEM,
lib := LIB$,
vms:=VMS$,
syi := SYI$Definitions;
TYPE
ADDRESS_32 = SYSTEM.SIGNED_32;
ADDRESS_64 = SYSTEM.SIGNED_64;
VAR os64: BOOLEAN;
PROCEDURE ALLOCATE_32 * (VAR v: SYSTEM.SIGNED_32; n: SYSTEM.SIGNED_32);
VAR Result: lib.CARDINAL;
BEGIN
Result := lib.LIB$GET_VM (n, v);
IF ~ ODD(Result) THEN lib.LIB$SIGNAL(Result) END;
END ALLOCATE_32;
PROCEDURE DEALLOCATE_32 * (VAR v: SYSTEM.SIGNED_32; n: SYSTEM.SIGNED_32);
VAR Result: lib.CARDINAL;
BEGIN
Result := lib.LIB$FREE_VM (n, v);
IF ~ ODD(Result) THEN lib.LIB$SIGNAL(Result) END;
v := SYSTEM.VAL(SYSTEM.SIGNED_32, NIL);
END DEALLOCATE_32;
PROCEDURE ALLOCATE * (VAR v: SYSTEM.SIGNED_64; n: SYSTEM.SIGNED_64);
VAR Result: lib.CARDINAL; addr32: ADDRESS_32; addr64: ADDRESS_64;
BEGIN
IF os64 THEN
Result := lib.LIB$GET_VM_64 (n, addr64);
v := addr64;
ELSE
Result := lib.LIB$GET_VM (SYSTEM.SHORT(n), addr32);
v := addr32;
END;
IF ~ ODD(Result) THEN lib.LIB$SIGNAL(Result) END;
END ALLOCATE;
PROCEDURE DEALLOCATE * (VAR v: SYSTEM.SIGNED_64; n: SYSTEM.SIGNED_64);
VAR Result: lib.CARDINAL; addr: ADDRESS_32;
BEGIN
IF os64 THEN
Result := lib.LIB$FREE_VM_64 (n, v);
ELSE
addr := SYSTEM.SHORT(v);
Result := lib.LIB$FREE_VM (SYSTEM.SHORT(n), addr);
END;
IF ~ ODD(Result) THEN lib.LIB$SIGNAL(Result) END;
v := SYSTEM.VAL(SYSTEM.SIGNED_64, NIL);
END DEALLOCATE;
PROCEDURE Adr32 (VAR s :ARRAY OF SYSTEM.BYTE):SYSTEM.SIGNED_32;
VAR i :SYSTEM.SIGNED_64;
BEGIN
i := SYSTEM.ADR(s);
RETURN SYSTEM.SHORT(i)
END Adr32;
PROCEDURE Init;
VAR iList :ARRAY 2 OF vms.item_desc;
str :ARRAY 9 OF CHAR;
cs,
cv,
len :SYSTEM.SIGNED_32;
BEGIN
len := 8;
iList[0].buff_len := SYSTEM.VAL(SYSTEM.SHORTWORD, 8);
iList[0].item_code := SYSTEM.VAL(SYSTEM.SHORTWORD, syi.SYI$_VERSION);
iList[0].buff_addr := Adr32(str);
iList[0].len_addr := Adr32(len);
iList[1].buff_len := SYSTEM.VAL(SYSTEM.SHORTWORD, 0); iList[1].item_code := iList[1].buff_len;
cv := vms.SYS$GETSYIW(0, 0, NIL, iList, 0, 0, 0);
ASSERT (ODD(cv) & (len >= 0) & (len < 9));
str[len] := 0X;
ASSERT (str[2]="."); (* now "V7.1 ", but what if we get to V10.0? *)
os64 := (SIZE(LONGINT)=8) & ((ORD(str[1]) - ORD("0")) > 6);
END Init;
BEGIN
Init
END Storage64.
7.2.2 Storage Allocation
type | storage allocation | alignment boundary
-----------+-----------------------+-----------------------
BOOLEAN | |
CHAR | |
BYTE | 8 bits (1 byte) | byte
SHORTINT | |
SIGNED_8 | |
-----------+-----------------------+-----------------------
SHORTWORD | |
INTEGER | 16 bits (1 word) | word /NoInteger
SIGNED_16 | |
-----------+-----------------------+-----------------------
SET | |
BITSET* | |
INTEGER | |
LONGINT | | /Integer
SIGNED_32 | |
CARDINAL* | |
REAL | 32 bits(1 longword) | longword
F_FLOATING | |
S_FLOATING | |
WORD | |
POINTER | | /pointersize=32
PTR | | /pointersize=32
ADDRESS_32 | |
-----------+-----------------------+-----------------------
LONGSET | |
LONGINT | | /pointersize=64
SIGNED_64 | |
LONGREAL | |
D_FLOATING | |
G_FLOATING | }
T_FLOATING | |
COMPLEX | 64 bits (1 quadword) | longword (VAX)
F_COMPLEX | | quadword (Alpha)
S_COMPLEX | |
QUADWORD | |
POINTER | | /pointersize=64
PTR | | /pointersize=64
ADDRESS_64 | |
-----------+-----------------------+-----------------------
H_FLOATING | |
LONGCOMPLEX| | quadword (Alpha)
D_COMPLEX | 128 bits (1 octaword) | longword (VAX)
G_COMPLEX | |
T_COMPLEX | |
OCTAWORD | |
-----------+-----------------------+-----------------------
Enumeration| 8 bits (1 byte) if | byte
*| type contains 256 or |
| less elements; |
| 16 bits (1 word) | word
| if type contains more|
| then 256 elements |
-----------+-----------------------+-----------------------
SET OF* | 8 bits (1 byte), | byte
| 16 bits (1 word), or | word
| 32 bits (1 longword),| longword
| 64 bits (1 quadword),| quadword
| 128 bits (1 octaword),| quadword
| 256 bits(2 octawords),| quadword
| according to |
| cardinality of base |
| type |
7.3 Persistent Objects Support
7.3.1 The Module Objects_Types (for stand-alone programs)
DEFINITION Objects_Types;
CONST
QuadwordSize = 8;
adrSize = 8;
maxIdentLen = 32;
tagSize = 8;
TYPE
ADDRESS_64 = SYSTEM.SIGNED_64;
Name = ARRAY 32 OF CHAR;
NamePtr = POINTER TO RECORD
name: Name;
END ;
Object = POINTER TO ObjectDesc;
ObjectDesc = RECORD END ;
Size = SYSTEM.SIGNED_64;
Tag = SYSTEM.SIGNED_64;
Type = POINTER TO TypeDesc;
TypeDesc = RECORD
module: NamePtr;
name: Name;
END ;
VAR
Modules-: ARRAY 256 OF ModEntryDesc;
PROCEDURE DisposeArray (VAR o: SYSTEM.ADDRESS_64);
PROCEDURE DisposeObj (VAR o: Object);
PROCEDURE NewObj (VAR o: Object; t: Type);
PROCEDURE SizeOf (o: Object): SYSTEM.SIGNED_64;
PROCEDURE StoreModObjects (typeDescBase: TypesArray);
PROCEDURE This (module, name: ARRAY OF CHAR): Type;
PROCEDURE TypeName (typ: Type; VAR module, name: ARRAY OF CHAR);
PROCEDURE TypeOf (o: Object): Type;
END Objects_Types.
7.3.2 The Module Types (for AlphaOberon)
DEFINITION Types;
IMPORT Modules, A2OLayout;
TYPE
Module = Modules.Module;
Name = A2OLayout.Name;
Object = SYSTEM.ADDRESS_64;
Type = POINTER TO TypeDesc;
PROCEDURE BaseOf (t: Type; lev: INTEGER): Type;
PROCEDURE LevelOf (t: Type): INTEGER;
PROCEDURE NewObj (VAR o: SYSTEM.ADDRESS_64; typ: Type);
PROCEDURE SizeOf (o: SYSTEM.ADDRESS_64): SYSTEM.SIGNED_64;
PROCEDURE This (m: Modules.Module; name: ARRAY OF CHAR): Type;
PROCEDURE TypeName (typ: Type; VAR module, name: ARRAY OF CHAR);
PROCEDURE TypeOf (o: SYSTEM.ADDRESS_64): Type;
END Types.
7.3.3 The Module Objects
DEFINITION Objects;
IMPORT A2OLayout, Files;
CONST
maxIdentLen = 32;
TYPE
ModuleTypeName = RECORD
module, type: A2OLayout.Name;
END ;
Object = POINTER TO ObjectDesc;
ObjectDesc = RECORD
PROCEDURE (o: Object) Load (VAR stream: Stream);
PROCEDURE (o: Object) Store (VAR stream: Stream);
END ;
Stream = RECORD (Files.Rider)
PROCEDURE (VAR r: Stream) ReadString (VAR s: A2OLayout.Name);
PROCEDURE (VAR r: Stream) WriteString (s: A2OLayout.Name);
END ;
TypeName = A2OLayout.Name;
PROCEDURE CopyObj (orig: Object; VAR copy: Object);
PROCEDURE DisposeObj (VAR o: Object);
PROCEDURE InitStream (VAR r: Stream);
PROCEDURE NameToObj (name: ModuleTypeName; VAR o: Object);
PROCEDURE ObjToName (o: Object; VAR name: ModuleTypeName);
PROCEDURE ReadObj (VAR r: Stream; VAR x: Object);
PROCEDURE WriteObj (VAR r: Stream; x: Object);
END Objects.
APPENDIX A:
COMPLETE EXAMPLE
MODULE Example;
. . .
END Example.
and a module MAIN.MOD
MODULE Main;
IMPORT Example;
. . .
END Main.
The dialog to run the complete program might look as follows:
$ A2O EXAMPLE/log/list <return>
| modules to be used must be compiled
| prior to their import.
| Compiles EXAMPLEDB.MOD and
| produces a source listing.
| LOG is enabled:
OpenVMS Oberon-2 V3.0 by ModulaWare
compiling SYS$USER:[H2OTST]EXAMPLE.MOD;1
Example: SYS$USER:[H2OTST]EXAMPLE.SYN;1
new symbol file generated.
$ A2O MAIN/log <return>
OpenVMS Oberon-2 V3.0 by ModulaWare
compiling SYS$USER:[H2OTST]MAIN.MOD;1
Example: SYS$USER:[H2OTST]EXAMPLE.SYN;1
| standard search strategy
Main: SYS$USER:[H2OTST]MAIN.SYN;1
new symbol file generated.
$ LINK MAIN,EXAMPLE <return>
| links MAIN.OBJ and EXAMPLE.OBJ
$ RUN MAIN <return>
| executes MAIN.EXE and uses
APPENDIX B: Oberon-2 Language Report
APPENDIX D: LIBRARY AND INTERFACE MODULES
D.1 ISO Modula-2 Standard Library
D.3 The Uni* library modules
D.4 Definitions of the OpenVMS-specific Foreign Modules
CIN$DEFIN.DEF
CLI$DEFIN.DEF
DC$DEFINI.DEF
DEV$DEFIN.DEF
DSC$DEFIN.DEF
DTIF$DEFI.DEF
DVI$DEFIN.DEF
HLP$DEFIN.DEF
IO$DEFINI.DEF
JPI$DEFIN.DEF
LBR$DEFIN.DEF
LCK$DEFIN.DEF
LIB$DEFIN.DEF
LNM$DEFIN.DEF
MNT$DEFIN.DEF
MOD$DEFIN.DEF
MTH$DEFIN.DEF
NMA$DEFIN.DEF
OBJ$DEFIN.DEF
OTS$DEFIN.DEF
PQL$DEFIN.DEF
PRC$DEFIN.DEF
PRV$DEFIN.DEF
PSL$DEFIN.DEF
QUI$DEFIN.DEF
RMS$DEFIN.DEF
SEC$DEFIN.DEF
SMG$DEFIN.DEF
SMG$MSGDE.DEF
SS$DEFINI.DEF
STR$DEFIN.DEF
SYI$DEFIN.DEF
TT$DEFINI.DEF
TT2$DEFIN.DEF
D.4.2 OpenVMS Operating System Services and Run-Time Library Interface
CONVERSIO.DEF number string conversions (decimal, hex, octal),
number type conversions between Byte, ShortWord,
LongWord (Integer, Cardinal), F_,D_,G_,H_FLOATING.
(.obj in Modula.olb)
Grapical User Interfaces:
DECW$XLIBDEF.DEF XWindow declarations and procedures
DECW$XLIBMSG.DEF XWindow message declarations
DECW$MOTIF.DEF OSF/Motif declarations and procedures
OpenVMS Layered Products Support
FDV$DEF.DEF FMS Forms Management System
GKS$DEFS.DEF GKS$ declarations and procedures
GKS$MSGS.DEF GKS$ message number definitions
LIB$.DEF
LIB$ routines
MTH$.DEF
MTH$ routines
NUMBER$CO.DEF MTH$ number conversion routines
OTS$.DEF 32 bit and 64 bit signed and unsigned modulus and division
OUTPUT$CO.DEF selection of FOR$, OTS$ routines
OpenVMS Record Management System:
RMS$.DEF
RMS$ Oberon-2 data structures and declarations
RMS$FILES.DEF RMS$FilesSignal, procedure LIB$SIGNAL for RMSAccess
RMSAccess.MOD RMS Oberon-2 procedures (combination of Modula-2's
RMS and RMSFiles modules, with Oberon-2 implementation)
SMG$.DEF
SMG$ Screen Management procedures
SMG$MSGDE.DEF SMG$ Screen Management
messages
STR$.DEF
STR$ and LIB$ String handling procedures
STRINGS.MOC Alternate ISO Modula-2 Std Lib implementation module
for string handling.
The Modula-2 implementation is in Modula.OLB
Unfortunately, there is different module
with the same name in AlphaOberon, which leads
to version conflicts, when recompiled.
VIR$.DEF
SYS$ OpenVMS virtual memory and event-flag procedures
VMS$.DEF
SYS$ OpenVMS Systems services procedures
APPENDIX E: - (Empty)
APPENDIX F: - (Empty)
APPENDIX G:
OpenVMS Oberon-2 Help File
The layout of the following text is in the format suited for
the OpenVMS help facility. The
ascii text is contained in file H2O.HLP on the distribution kit.
H2O
Invokes the OpenVMS Alpha|VAX Oberon-2 compiler to compile an
Oberon-2
compilation unit. This command is described in detail in the
OpenVMS Alpha|VAX Oberon-2 User's Guide (H2OUM).
Format:
A2O file-spec
H2O file-spec
2 Parameters file-spec
Specifies one Oberon-2 source program file to be compiled.
If you do not specify a file type, the default file type MOD is used.
For default a Oberon-2 program module is compiled.
2 Qualifiers
/ANALYSE[=(AoptionList)]
/NOANALYSE (D)
Source code analyser to be used only in combination with the qualifiers
NoObject, NoMachine_Code, NoSymFile, NoCross_Reference.
optionList=(intermediate_items, count_statements, redefine_methods,
used_before_set, var_parameters, exported_items)
(This feature of A2O|H2O is unsupported).
See H2O User's Guide for a detailed description of the analyser.
/AXP (D; Alpha/A2O only)
/NOAXP (D; VAX/H2O only)
Determines whether code is generated for Alpha or VAX.
/CHECK[=(CoptionList)] (D)
/NOCHECK
Indicates whether the compiler should generate additional code
to perform run-time checks, clear local pointers and heap memory
or assertion evaluation.
CoptionList=(stackcheck, indexcheck, typecheck, overflowcheck,
rangecheck, pointerinit, asserteval, heapinit)
(a) array index bound (indexcheck),
(b) case label for case without else-clause (indexcheck),
(c) set element index in IN relation, set constructor, and
predeclared procedures INCL and EXCL(rangecheck),
(d) when evaluating an integer expressions with operators
+, -, negation, *, MOD, and DIV (overflowcheck),
(e) using predeclared function ABS, and ASH (overflowcheck),
(f) using predeclared procedures INC and DEC procedures (overflowcheck),
(g) integer to integer conversion with SHORT (overflowcheck),
(h) integer to character conversion with CHR (overflowcheck), and
(i) real to integer conversion with ENTIER (overflowcheck),
(j) for 0 < dimensions and total size < 2^31 in NEW for dynamic arrays
(rangecheck),
(k) for dynamic pointer type-tag test (typecheck),
(l) to clear all localy declared pointer variables at procedure entry
(pointerinit),
(m) to clear the heap allocated with NEW or SYSTEM.NEW (heapinit),
(o) to evaluate the expression in ASSERT procedure (asserteval).
(p) to check the stack at procedure entry (stackcheck).
Stackcheck is only required if any procedure of the compilation
unit may be called from a (Modula-2) coroutine.
/COMPLEX
/NOCOMPLEX (D)
Controls whether the compiler knows the data type COMPLEX and
LONGCOMPLEX, the pervasive functions CMPLX, RE and IM and the associated
operations of ISO Modula-2.
Note that Oberon-2 allows redeclaration of any pervasive type name.
/CROSS_REFERENCE
/NOCROSS_REFERENCE (D)
Controls whether the compiler creates a cross-reference listing
as part of the listing file.
The default is /NOCROSS_REFERENCE, which does not create
a cross-reference listing.
The cross-reference listing generation may fail if the source is not
free of syntactical errors.
This qualifier is ignored if no listing file is being generated.
/DEBUG
/NODEBUG (D)
Controls whether the compiler makes local symbol table and
traceback information available to the VAX/VMS Symbolic Debugger
and the run-time error-reporting mechanism. The default is
NODEBUG, which produces only traceback information.
/DUMP_SYMFILE
/NODUMPSYMFILE (D)
Produces a modestly readable form of the symbol file being produced
on SYS$OUTPUT (unsupported; reserved for use by ModulaWare only)
/EXTEND_SYMFILE
/NOEXTEND_SYMFILE (D)
This qualifier allows to extend a fine-grained symbol file
(object model) and is only applicable in combination
with /FINE_GRAINED_SYMFILE.
/FINE_GRAINED_SYMFILE
/NOFINE_GRAINED_SYMFILE (D)
This qualifier enables the so-called object model, which
allows to export additional constants, types, variables,
procedures and as long as the clients don't use SIZE(recordType),
it is allowed to extend record types with additional
exported and hidden fields. Object model symbol-files
contain a so-called finger-print per exported item,
whereas the non-object model symbol-files contain a single
module-key.
All inconsistencies with existing clients will be detected at
load-time in AlphaOberon.
/Fine_Grained_SymFile can only be used in combination with
/Oberon_Loadfile and /PointerSize=64.
Symbol- and object-file extensions:
/PointerSize=32 | /fine_grained_symfile /NOfine_grained_symfile
/ Oberon_LoadFile | -disallowed- -disallowed-
/NOOberon | -disallowed- .syn, .obj
/PointerSize=64 | /fine_grained_symfile /NOfine_grained_symfile
/ Oberon_LoadFile | .syo, .olf .syn64, .olf64
/NOOberon | -disallowed- .syn64, .obj64
When symbol files with the extension .syn64 is not found,
the compiler tries .syn.
/FOREIGN_CODE (D on Alpha)
/NOFOREIGN_CODE (D on VAX)
Use this qualifier only if Oberon-2 or Modula-2 procedures may
also be called by other languages than Oberon-2 or Modula-2.
It is not needed if procedures written in languages other than
Oberon-2 are called by the Oberon-2 program. Remember that
procedures can be exported via explicit export or via assignment to
procedure variables or procedure parameters or via ADR).
Note, this affects only the code generation
and has nothing to do with so-called foreign interface modules
(those with a "$"-sign in the module name) whose only purpose is
to generate a dummy symbol file.
NOTE: The FOREIGN_CODE qualifier is only needed if a procedure
of the module is called from within a coroutine and
if a stack-check is enabled; see /optimize.
/INTEGER_type_match_pointerSize
/NOINTEGER_type_match_pointerSize (D)
For default (/NoInteger), the pervasive data type SHORTINT is a 8 Bit,
INTEGER is a 16 Bit and LONGINT is a 32 Bit signed number. If /Integer
is selected, the pervasive type INTEGER is a signed number with bits,
where x is the qualifier value of /pointersize (default 32).
Using /Integer makes the pervasive type INTEGER compatible (identical)
to the pervasive type LONGINT of a module which was compiled with /NoInteger.
Attention, symbol file will change when objects of type INTEGER are exported
when this qualifier is swapped at recompilation.
If /Integer is selected, the pervasive types SHORTINT and LONGINT are not
known. The types SYSTEM.SIGNED_(8,16,32,64) are allways available.
Don't use these new system types if avoidable; this is a feature
of the A2O|H2O implementation; they are not available in other Oberon-2
compilers and hence are not portable.
/IEEE (Alpha only)
/NOIEEE (D)
Determines the pervasive type REAL and LONGREAL. With IEEE, they
are synonymous for F_ and D_FLOATING, with NOIEEE, they are
synonymous for S_ and T_FLOATING. The type of real number literals
depends on the actual type of REAL and LONGREAL.
/INSTRUCTIONMODE[=IoptionList] (Alpha only)
/NOINSTRUCTIONMODE (D)
IoptionList = (FptTrapB,
ChoppedDECRounding, SoftwareDECTrap, UnderflowDECTrap,
OverflowDECTrap, ChoppedIEEERounding, DynamicRounding,
PlusInftyRounding, MinusInftyRounding, InexactIEEETrap,
SoftwareIEEETrap, UnderflowIEEETrap, OverflowIEEETrap,
IntTrapB, IntOverflow)
These options enable the corresponding Alpha instruction qualifiers as
explained in the DEC Alpha architecture reference manual. If precise trap
delivery is required, enable FptTrapB together with the SoftwareIEEETrap
and SoftwareDECTrap. This slows down execution of floating point
arithmetic.
/ISO
/NOISO (D)
Controls whether the compiler accepts certain language extensions
and modifications. Reserved; not yet used.
/LIST[=file-spec]
/NOLIST (D)
Controls whether the compiler creates a listing file.
If you issue the H2O command from interactive mode, the
compiler, by default, does not produce a listing file. However,
if the H2O command is executed from batch mode, /LIST is the
default. In either case, the listing file is not automatically
printed. You must use the PRINT command to obtain a line printer
copy of the Oberon-2 listing file.
Note that the /LIST qualifier permits you to include a
file specification for the listing file. If you omit the file
specification, the compiler defaults to the name of the input
source file, the default directory, and a file type of LIS.
/LOG
/NOLOG (D)
Specifies whether the compiler displays information on its
running version, the succession of the different compiler
passes and the symbol files read.
/NOLOG is the default for interactive mode, /LOG is the default
for batch.
/MACHINE_CODE
/NOMACHINE_CODE (D)
Specifies whether the listing file should include a
representation of the machine code generated by the compiler. If
no listing file is being generated, this qualifier is ignored.
No machine code is generated if errors are detected in the source
program.
The default is /NOMACHINE_CODE.
/NAME_SEPARATOR="_" (D; Alpha)
/NAME_SEPARATOR="." (D; VAX)
/NONAME_SEPARATOR
Specifies the separator character between module and procedure
name. Only the first character of the string given is evaluated.
The string may be empty. /NONAME_SEPARATOR defaults to the Oberon-2
standard separator which is the same as the default value. See also
/OMIT_MODULE_NAME to get rid of the module name plus separator.
/Oberon_LoadFile (Alpha only)
/NOOberon_LoadFile (D)
Generates an .OLF[64] file instead of an .OBJ[64] file.
The .OLF files can only be activated from within AlphaOberon (AOS).
The generation of .OBJ[64] files can be suppressed by using /OBJECT=NL:
/OBJECT[=file-spec] (D)
/NOOBJECT
Controls whether the compiler creates an object module. The
/NOOBJECT qualifier is useful when you want to test the source
program for compilation errors.
By default, /OBJECT is enabled; the compiler produces an object
module with the same file name as source file name, but with
the file extension OBJ[64] or OLF[64] (see /Fine_Grained_SymFile).
/OMIT_MODULE_NAME
/NOOMIT_MODULE_NAME (D)
Controls whether the procedure entries of the object file are pre-
fixed with the module name and a separator (see also
/NAME_SEPARATOR which is used to alter the separator character).
The qualifier /OMIT_MODULE_NAME only influences the symbols to be
resolved by the linker and is only used to generate object modules
with procedure names that are callable by programs written in
another languages than Oberon-2
This option may be used with or without the /FOREIGN_CODE
qualifier. When compiling a foreign interface module, this option
enables generation an object file which is otherwise suppressed
(unsupported feature).
By default all procedure names are prefixed e.g. by the string "X_"
if the name of module is "X" ("_" being the separator character
determined by the option /NAME_SEPARATOR="_").
Only those procedures and functions marked for export by an "*"
in addition to the module body (module initialisation part)
which is a parameterless procedure with the name
of the module, are visible to the outside. Exported and hidden
method entries are also visible but only for the linker to fill in the
method references of the type descriptors. Although possible,
methods should not be called from foreign languages (the receiver is
the first parameter in the parameter list and is treated
like any other parameter).
/OPTIMIZE[=OoptionList] (D; list=(rotateScratch, stackCheck); Alpha only)
/NOOPTIMIZE
OoptionList = (schedule, alignCheck, rotatePreserved,
rotateScratch, stackCheck, eliminateUnreachableCode)
Schedule allows the Alpha instruction scheduler to run during code
generation. Using this option could improve the execution speed of a
program. This option is not recommended when you plan to use the
symbolic debugger with the module compiled, since instructions are
moved around within so-called basic scheduling blocks to avoid instruction
latencies and to take advantage of the Alpha's feature to execute multiple
instruction in the same cycle. For more details see Alpha architecture
manual.
NOTE: When using /OBERON_LOADFILE, one must use /NODEBUG, in order to use
the Alpha instruction scheduler.
This because the Oberon System Runtime Debugger can not work
on instruction scheduled programms.
Aligncheck tells the compiler to generate code to check pointer and
variable parameter addresses for alignment before accessing the data.
Code is only generated in circumstances where the compiler can not know
whether the data is aligned or not. The start address of global and local
variables is always aligned. Using this option is called "pessimistic
approach" because there is an overhead even if the addresses are
already naturally aligned.
NoAlignCheck is the optimistic approach and improves the speed of an
application program when using properly aligned data fields (see also
/PACKED_RECORDS). If an alignment trap occurs in this case, the access
trap must be handled by the operating system which could significantly
slow down the performance of the application program, especially if the
trap occurs in the inner loop of an application program.
The rotate register options tells the code generator to use different
registers when allocating registers. This allows the scheduler to rearrange
more instructions. There is no penalty when allowing the rotation of
scratch registers. However, when allowing the rotation of preserved
registers, the entry code of each procedure gets larger because more
registers have to be saved and restored for the caller. Rotating preserved
registers is only recommended if the procedures in the compiled module
are not called in the inner loop of an application program or if the
procedures themselves contain CPU-bound processing loops.
Stackcheck is enabled by default and should be turned off only if it is
guaranteed that procedures of the module compiled are not called from
a coroutine. You may also turn it off if you know that there is
always going to be enough coroutine workspace and you like to live
dangerously.
EliminateUnreachableCode allows the suppression of so-called
dead-code, such as the ... statement sequence in IF FALSE THEN ...
END.
/PARSE_TREE
/NOPARSE_TREE (D)
Display the front-end parse tree on SYS$OUTPUT
(unsupported; reserved for use by ModulaWare only)
/POINTERSIZE=x (A2O only)
/POINTERSIZE=32 (D)
With x=32, pointers, addresses and LONGINT have 32 bit size.
SYSTEM.PTR is identical to SYSTEM.ADDRESS_32.
The object file extension is .OBJ with /NoOberon_LoadFile.
With x=64, pointers, addresses and LONGINT have 64 bit size.
SYSTEM.PTR is identical to SYSTEM.ADDRESS_64.
The object file extension is .OBJ64 with /NoOberon_LoadFile
otherwise it is either .OLF64 (/noFine_Grained_SymFile) or
else .OLF.
The option value x=64 requires at least OpenVMS V7.1.
/PACKED_RECORDS (D on VAX and Alpha)
/NOPACKED_RECORDS (D on Alpha if /Oberon_LoadFile is used)
This qualifier controls the storage alignment and allocation of record fields.
Fields of records are aligned to a byte address if PACKED_RECORDS or
are naturally aligned with NOPACKED_RECORDS. In the latter case,
the memory allocated for fields could be larger than the field's type size.
This qualifier affects only record type declarations, i.e. variable
declaration use the record type option which was in effect when compiling
the record type declaration. This option should be used consistently in
applications and application specific libraries because otherwise the
record type size of structural equivalent record types could be different. All
stand-alone library modules supplied by ModulaWare are compiled using packed
records. For AlphaOberon, record fields should always be naturally aligned
otherwise the garbage collector is not able to find local pointer variables.
/QUERY
/NOQUERY (D)
Specifies whether the compiler explicitly asks for the symbol
files to be read in.
By default, the compiler uses a standard strategy to lookup the
necessary symbol files.
/SYMFILE[=file-spec] (D)
/NOSYMFILE
Controls whether the compiler creates a symbol file.
By default, the compiler produces a symbol file each time the
exported objects change in number or type structure. This applies
to hidden method headers which are also stored in the symbol file.
To be able to check the new versus the old symbol file, the version
limit of the working directory (directories in case of the default
directory being a search list) should have a minimum of two.
The file name of the imported modules are always constructed from the
module names. This qualifier optionally specifies the output file name
with the default file type of SYN or with /PointerSize=64,
SYN64 or SYO (see /Fine_Grained_SymFile).
/TRANSFER_VECTOR (D; VAX only)
/NOTRANSFER_VECTOR (D; Alpha only; don't change)
H2O only: Controls whether the compiler generates a transfer vector
section in the object file. This feature may be helpful when working with
shared images (see OpenVMS-linker reference) with modules written
in Oberon-2. For standard linking and generation of executables
this option has no effect.
By default, the compiler produces transfer vectors.
With A2O, transfer vectors in the form of procedure descriptors are always
generated (OpenVMS Alpha requirement). Hence a special provision for
shareable images is not required. With MaX, this option is now used for
special purposes during installation time.
APPENDIX H: DATA SHEET
APPENDIX I: PROGRAMMING HINTS
I.1. Benchmarks with Oberon-2
I.2. Case Statement
IF (-32000<=i) & (i<=-1) THEN ...
ELSIF i=0 THEN ...
ELSIF (1<=i) & (i<=32000) THEN ...
END;
Don't write:
CASE i OF
-32000..-1: ...
| 0: ...
| 1..32000: ...
END;
I.3. Local pointer variables in procedures
This is end of the A2O User's Guide. Hope you enjoyed reading it.
Send any comments to gd@
.zel.org
Website Navigator
Oberon Webring Navigator
[ Previous
| SkipPrevious
| SkipNext
| Next
| Next5
| ListSites
| Random
| Join ]
OpenVMS Webring Navigator
[ Previous
| SkipPrevious
| SkipNext
| Next
| Next5
| ListSites
| Random
| Join ]
Copyright (1999) www.zel.org
First published 27-Apr-1999, last revised 09-May-2003, gd@