Modula-2 (на английском языке) (1161147), страница 6
Текст из файла (страница 6)
In extended syntax mode you can pass any array variable to the HIGH function.
You can access all dimensions of an array with more than one dimension by passing the appropriate array dimension to HIGH. For example, to get the high bound of the second dimension of an array type with two or more dimensions you would subscript the array variable with one index, thus leaving the second dimension. The value used to index the array is not used since you are not accessing an array element but are informing the compiler which array HIGH dimension to retrieve. Typically you would use the value 0 for the subscript.
Example:
PROCEDURE test(arr : ARRAY OF ARRAY OF REAL);
.
.
.
FOR i := 0 TO HIGH(arr) DO (* first dimension )
FOR j := 0 TO HIGH(arr[0]) DO ( second dimension *)
INC
PROCEDURE INC(VAR v : type);
PROCEDURE INC(VAR v : type; amount : CARDINAL);
Increases the value of variable v by one or by a specified amount. If an amount is not passed a value of one is assumed for amount. The variable can be of any signed or unsigned integer type, any character type, any boolean type or any enumeration type. The amount must be assignable to CARDINAL.
INCL
PROCEDURE INCL(SetVar : SetType; Element : ElementType);
Includes an element in a SET or PACKEDSET variable. SetVar must be a variable of a set type, and Element must be an expression resulting in a value of the element type of the set. The specified element is added to the value of the set variable.
INT
PROCEDURE INT(Val : ValType) : INTEGER;
Converts Val to INTEGER. Val can be any signed or unsigned integer type, any character type, a boolean type or any enumeration type. For character, boolean and enumeration types, the returned value is the ordinal value of the parameter.
MAX
PROCEDURE MAX(ScalarType) : ScalarType;
Returns the maximum value of a scalar type. The parameter is a type name, which must be a signed or unsigned integer type, a real type, a character type, a boolean type, a subrange, or an enumeration type. The type returned by MAX is the same as the type of the parameter.
MIN
PROCEDURE MIN(ScalarType) : ScalarType;
Returns the minimum value of a scalar type. The parameter is a type name, which must be signed or unsigned integer type, a real type, a character type, a boolean type, a subrange, or an enumeration type. The type returned by MIN is the same as the type of the parameter.
NEW
PROCEDURE NEW(VAR P : PointerType {;tag : tagtype});
PROCEDURE NEW(VAR P : DynamicArrayType; highBounds : CARDINAL
{; highBounds : CARDINAL});
The optional tag expressions are the tags of variant parts in a record that is being allocated. Each tag expression must be a compile-time constant. The values of the tags determine how much storage is allocated.
For dynamic arrays you must specify a high bound for each array dimension declared in the dynamic array declaration. Remember that you are specifying the high bound for the dimension, and the lower bound is assumed to be zero, and therefore the size of each dimension is the highbound+1.
Example:
PROCEDURE AllocateMatrix(VAR m : Matrix; order : CARDINAL);
BEGIN
(* order is the number of element in each dimension )
( therefore the high bound is one less than this )
( square matrix *)
NEW(Matrix, order-1, order-1);
END AllocateMatrix;
A call to NEW is translated to a call to ALLOCATE. In order to use NEW, you must define the procedure ALLOCATE. Usually, you import ALLOCATE from the ISO module Storage. You can, however, define the procedure yourself.
ODD
PROCEDURE ODD(Val : ValType) : BOOLEAN;
Returns TRUE if Val is ODD and FALSE otherwise. Val can be any signed or unsigned integer type.
ORD
PROCEDURE ORD(Val : ValType) : CARDINAL;
Converts Val to CARDINAL. Val can be INTEGER, LONGINT, LONGCARD, CHAR, BOOLEAN, or any enumeration type. For CHAR, BOOLEAN and enumeration types, the returned value is the ordinal value of the parameter.
RE
PROCEDURE RE(Val : COMPLEX) : REAL;
PROCEDURE RE(Val : LONGCOMPLEX) : LONGREAL;
Returns the real part of a complex type.
IM
PROCEDURE IM(Val : COMPLEX) : REAL;
PROCEDURE IM(Val : LONGCOMPLEX) : LONGREAL;
Returns the imaginary part of a complex type.
CMPLX
PROCEDURE CMPLX(realPart, imaginaryPart : REAL) : COMPLEX;
PROCEDURE CMPLX(realPart, imaginaryPart : LONGREAL) : LONGCOMPLEX;
Returns a complex type where realPart and imaginaryPart compose the complex type. Note that this is the same syntax used to compose a complex constant. If realPart and imaginaryPart are constants then CMPLX returns a complex constant compatible with a complex types. If realPart or imaginaryPart are not compile time constants then CMPLX can only be used in a statement.
SIZE
PROCEDURE SIZE(item) : IntConst;
Returns the number of bytes of storage occupied by item. item can be either a variable or a type name. Variables can be fully qualified with subscripts or record field references. The type returned by this procedure is compatible with signed and unsigned integer types.
TRUNC
PROCEDURE TRUNC(RealVal : RealType) : CARDINAL;
Converts a REAL or LONGREAL value to CARDINAL by truncation; the fractional part of the real number is discarded. The result is undefined if RealVal is out of the range of CARDINAL.
VAL
PROCEDURE VAL(ConvertToType; Value : AnyPervasiveType) : Type;
Converts a value from one type to another. This function can convert any predefined pervasive type to any other pervasive type. With the following exceptions.
-
You cannot convert an enumeration type to a real or complex type. Remember that boolean and character types are defined as enumeration types.
-
You cannot convert a real type to a complex type.
-
You cannot convert a complex type to a real type.
The following are TRUE:
INT(...) = VAL(INTEGER, ...);
ORD(...) = VAL(CARDINAL, ...);
FLOAT(...) = VAL(REAL, ...);
LFLOAT(...) = VAL(LONGREAL, ...);
TRUNC(...) = VAL(CARDINAL, ...);
Modules
Modules are the unit of program decomposition. Modula-2 supports both separately compiled modules and local modules within a compilation unit.
Definition Modules
A definition module is defined by:
DEFINITION MODULE ModuleName;
{Import}
{Declaration}
END ModuleName.
Import is:
[FROM ModuleName] IMPORT
identifier {,identifier};
Each declaration in a definition module is available to other modules that import the definition module.
For compatibility with earlier versions of Modula-2, an export list can follow the imports in a definition module. Stony Brook Modula-2 ignores the export list for definition modules.
Procedures in definition modules
Procedure declarations in definition modules can specify only the procedure header, which consists of the name of the procedure, the parameters, the value type, and the procedure attributes. Any local declarations and the code of the procedure are in the implementation module.
Opaque types
Definition modules can contain type declarations of the following form:
TYPE name;
This is called an opaque type declaration because the actual type is not visible to the user of the module. The type name can be used in other declarations within the definition module.
The corresponding implementation module must contain a full type declaration for any opaque types declared in the definition module. The full type declaration must define a pointer type.
A module importing an opaque type can declare objects of that type, do assignments of objects of that type, compare two objects of the same opaque type, and pass objects of the type as parameters only. The importing module cannot allocate, deallocate or dereference the type since it has no knowledge of the type to which it points.
Opaque types are used to hide information from the user of a module. They let the user perform only the minimum operations on a data type, for two reasons:
-
The integrity of the data structure is ensured because operations on the actual data can be performed only by the implementation module itself.
-
The user cannot be aware of the actual implementation of the data type. If the implementor decides to change the data structure, users of the data type are not affected.
Implementation Modules
Implementation modules take the following form:
IMPLEMENTATION MODULE ModName [[Protection]];
{Import}
{Declaration}
[ BEGIN
ListOfStatements
[EXCEPT
ListOfStatements]
[
FINALLY
ListOfStatements
EXCEPT
ListOfStatements
]
]
END ModName.
An implementation module with the same module name must exist for each definition module. The implementation module contains the actual code for the procedures defined in the definition modules. It also allocates the space for variables declared in the definition module.
Each procedure declared as a header in the definition module must be fully declared in the implementation module. The types of parameters, type of return value, public name, and procedure attributes must be identical to the declaration in the definition module, since that is where other modules get the information about the procedure.
Variables, types, and constants declared in the definition module must not be redeclared in the implementation module, with the exception of opaque type declarations. These symbols are all made visible in the implementation module automatically by the compiler.
The implementation module can also contain its own declarations that are not contained in the definition module. These declarations are not visible anywhere else but the implementation module.
Program Modules
A program module contains the main program of a Modula-2 program. Program modules take the following form:
MODULE ModName [[Protection]];
{Import}
{Declaration}
BEGIN
ListOfStatements
[EXCEPT
ListOfStatements]
END ModName.
The ListOfStatements is the code for the main program. Every Modula-2 program must have a program to define where execution starts. Similarly, you cannot have two program modules linked together in a single program.
Import Declarations
The import declaration is a special declaration that makes symbols from another module available. If you are going to use symbols declared in another module, they must be mentioned in an import declaration.
The import declaration takes either of the following forms:
IMPORT IdList;
or
FROM ModName IMPORT IdList;
Where IdList is:
identifier {,identifier}
In the first form of the import declaration, IdList specifies a list of modules that are imported.
The symbols defined in the definition module of the imported module are not directly visible in the importing module. A qualified reference is required to refer to those symbols.
A qualified reference takes the following form:
ModName.identifier
You can refer to all identifiers from the imported definition module in this way.
The second form of the import declaration imports specific symbols from a module. When this form is used, the symbols named in the IdList are made visible without qualification. Only the symbols named in the IdList are made available by this form of import.
You can use both forms of import to import the same module if you want some of the symbols to be visible without qualification and others only with qualification. You might need to do this to avoid double declarations when two modules you import both define the same name.