This is Info file m3.info, produced by Makeinfo-1.55 from the input file m3.texi. This file documents the DEC SRC Modula-3 compiler, release 3.3. Copyright (C) 1995 Stephen Schaub Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled "Copying" and "GNU General Public License" are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: m3.info, Node: Top, Next: Writing Programs, Prev: (dir), Up: (dir) SRC Modula-3 ************ This document provides an overview of the Modula-3 language as implemented by the DEC Systems Research Center, version 3.3. The full distribution includes several libraries, most of which are not described here. This is not intended to provide an exhaustive or even completely accurate coverage; it is to serve as a quick on-line reference only. For complete and up-to-date details, see the Modula-3 home page at `http://www.research.digital.com/SRC/modula-3/html/home.html'. Please mail comments or corrections to schaub@cs.unt.edu. * Menu: * Writing Programs:: Main module, m3makefile, user modules * Language Elements:: Language features & syntax * Compiling & Running:: Using m3makefiles and m3build * Standard Library:: Strings, I/O, miscellaneous routines -- The Detailed Node Listing -- Writing Programs * Main Module:: * Makefile:: The Makefile * Simple Makefile:: A simple example of an m3makefile * Basic Makefile Commands:: What goes in an m3makefile * Other Makefile Commands:: More of what goes in an m3makefile Language Elements * Modules:: Interfaces and modules * Declarations:: Types, constants, variables, procedures... * Statements:: Selection, looping, error control * Expressions:: Identifiers, arithmetic, logic, etc. * Pragmas:: Compiler directives: <* INLINE *>, etc. Modules * Interface:: Interface layout and example * Implementation:: Module layout and example * Imports:: Using modules in programs Imports * IMPORT Stmt:: Declarations * Decl Examples:: Examples of common declarations * Constants:: CONST "=" ";" * Types:: TYPE "=" ";" * Variables:: VAR [ ":" ] [ ":=" ] ";" * Procedures:: PROCEDURE "=" ";" * Exceptions:: EXCEPTION [ "(" ")" ] ";" Types * Ordinal Types:: INTEGER, CARDINAL, BOOLEAN, CHAR, ... * Array Types:: ARRAY OF * Record Types:: RECORD END * Object Types:: OBJECT-METHODS-OVERRIDES-END * Set Types:: SET OF * Reference Types:: REF * Procedure Types:: PROCEDURE () { : } Statements * Assignment Stmts:: INC, DEC, and := * Call and Return Stmts:: Calling and returning from procedures * Selection Stmts:: IF-THEN, CASE, TYPECASE * Looping Stmts:: FOR, WHILE, REPEAT, LOOP, EXIT * Compound Stmts:: BEGIN/END, WITH * Error Stmts:: RAISE, TRY-EXCEPT, TRY-FINALLY Selection Statements * IF Stmt:: IF-THEN-ELSIF-ELSE-END * CASE Stmt:: CASE OF END * TYPECASE Stmt:: TYPECASE OF END Looping Statements * FOR Stmt:: FOR ":=" TO [ BY ] END * WHILE Stmt:: WHILE DO END * REPEAT Stmt:: REPEAT UNTIL * LOOP Stmt:: LOOP END * EXIT Stmt:: EXIT Compound Statements * Block Stmt:: * WITH Stmt:: WITH "=" DO END Error Handling Statements * RAISE Stmt:: RAISE [ "(" ")" ] * TRY-EXCEPT Stmt:: TRY EXCEPT END * TRY-FINALLY Stmt:: TRY FINALLY END Expressions * Expr Build Blocks:: Format of identifiers and literals * Arithmetic Expressions:: a + b, MAX(x,y), ABS(x), ... * Logical Expressions:: a AND b, NOT c, ... * Relational Expressions:: a = b, a <= c, c IN charSet, ... * Constructors:: * Precedence:: Operator precedence chart Constructors * Set Constructor:: * Array Constructor:: * Record Constructor:: Pragmas * INLINE Pragma:: * ASSERT Pragma:: * TRACE Pragma:: * FATAL Pragma:: * UNUSED Pragma:: * OBSOLETE Pragma:: * NOWARN Pragma:: Compiling and Running Programs * Simple Compile Example:: How to organize and compile a simple program * Multiple-Package Example:: Managing larger programs * m3build Options:: Command-line options for m3build Standard Library * String Routines:: * I/O Routines:: * Misc Routines:: String Routines * Text Interface:: Compare strings, get length of string, etc. * Fmt Interface:: Convert INTEGER/REAL/BOOLEAN to TEXT * Scan Interface:: Convert TEXT values to INTEGER/REAL/BOOLEAN I/O Routines * I/O Examples:: * IO Interface:: * Rd Interface:: * Wr Interface:: * Lex Interface:: Misc Routines * Params Interface:: Access command-line parameters * Env Interface:: Access environment variables * Word Interface :: Unsigned integer datatype, bitwise logical operations  File: m3.info, Node: Writing Programs, Next: Language Elements, Prev: Top, Up: Top Writing Programs **************** Modula-3 programs are composed of one or more module files, along with a makefile that tells the compiler how to put everything together. All of these files must be located in a subdirectory called `src'. IMPORTANT: Case is significant in Modula-3 programs. This means that * All keywords and reserved words must be in uppercase letters. * Identifiers such as variables, constants, and procedure names must always appear in the same case as the one used in the definition. For example, `Main' and `main' are two different identifiers. * Menu: * Main Module:: * Makefile::  File: m3.info, Node: Main Module, Next: Makefile, Prev: Writing Programs, Up: Writing Programs The Main Module =============== Every Modula-3 program must have a single main module. For small programs, the main module may be the only module. Here is a short example. MODULE Main; IMPORT IO; (* So we can print things *) VAR name: TEXT; (* a string called `name' *) BEGIN IO.Put("Enter your name: "); IO.GetLine(name); IO.Put("Your name is: " & name & "\n"); END Main.  File: m3.info, Node: Makefile, Prev: Main Module, Up: Writing Programs The Makefile ============ An SRC Modula-3 makefile (named `m3makefile') contains instructions (one per line) that instruct the compiler how to build a program or library. A makefile instruction is followed by one or more arguments in parenthesis, like a procedure call. Each instruction generally specifies a library, interface, or module to be included as part of the final library or program. Comments are denoted by `%'. * Menu: * Simple Makefile:: A simple example of an m3makefile * Basic Makefile Commands:: What goes in an m3makefile * Other Makefile Commands:: More of what goes in an m3makefile  File: m3.info, Node: Simple Makefile, Next: Basic Makefile Commands, Prev: Makefile, Up: Makefile A Simple Makefile ----------------- Here is a simple m3makefile: % Makefile for Modula-3 program 'myprog' import(libm3) implementation(main) program(myprog) The first line is a comment. Text after `%' is ignored by the compiler in m3makefiles. The `import' command tells the compiler that the program uses routines in the library `libm3'. This command is present in most m3makefiles. If you use routines from other libraries, you must include other `import' commands that tell the compiler which libraries to include. There must be one `implementation' command for each .m3 file in your program. In this case, there was only one such file: `main.m3'. Finally, the `program' command tells the compiler what to name the resulting executable file. The compiler will name this program's executable `myprog'.  File: m3.info, Node: Basic Makefile Commands, Next: Other Makefile Commands, Prev: Simple Makefile, Up: Makefile Basic Makefile Commands ----------------------- The following are some of the commands that may be used in an m3makefile. They declare their arguments as private: visible only within the current package. To declare an interface or module as public, use the capitalized version (e.g., Interface(), Implementation(), etc.). interface(X) / generic_interface(X) Declares that the file X.i3 (or X.ig for generics) contains an interface. All interface files that you create must appear in interface commands. Leave the .i3/.ig extension off. implementation(X) / generic_implementation(X) Declares that the file X.m3 (or X.mg for generics) contains a module. All module files that you create must appear in implementation commands. Leave the .m3/.mg extension off. module(X) / generic_module(X) Declares X.i3 and X.m3 with one command (X.ig and X.mg for generics). program() An m3makefile generally has one program command. This specifies what to name the program executable. library() If the m3makefile describes a collection of interfaces and modules that are designed to be a library instead of a program, use this command instead of program(). import() This command specifies packages to be imported. The `libm3' package must be included in all Modula-3 programs with the import command.  File: m3.info, Node: Other Makefile Commands, Prev: Basic Makefile Commands, Up: Makefile Other Makefile Commands ----------------------- override(P, D) Look in directory D/P for the package P instead of in the public repository. Use this command in conjunction with the import(P) command when you want to build and use your own private libraries. c_source(X) Declares that the file X.c contains C source code. import_lib(X, P) If P/libX.a is a library, includes -LP -lX in the final link command. Otherwise, includes -lX in the final link command. import_obj(X) Include X in the final link command. m3_option(X) / remove_m3_option(X) Add or remove option X to/from list of compiler options. X should be a string (enclosed in "") containing one of the following: -why Explain why each compilation is needed (default). -commands Print the compilation commands as they are started. -verbose Print what happens to each file. -times Print a breakdown of elapsed time. -g Generate debugging symbols (default). -O Optimize code. -a Turn off <*ASSERT*> checking. -keep Preserve intermediate files. -once Don't recompile modules with new opaque info.  File: m3.info, Node: Language Elements, Next: Compiling & Running, Prev: Writing Programs, Up: Top Language Elements ***************** Modula-3 programs include declarations, statements, expressions, and pragmas. * Menu: * Modules:: Interfaces and modules * Declarations:: Types, constants, variables, procedures... * Statements:: Selection, looping, error control * Expressions:: Identifiers, arithmetic, logic, etc. * Pragmas:: Compiler directives: <* INLINE *>, etc.  File: m3.info, Node: Modules, Next: Declarations, Prev: Language Elements, Up: Language Elements Modules ======= Modules are the basic building blocks of Modula-3 programs. A "module" is a named collection of declarations, including constants, types, variables, and procedures. A module can make its facilities available to other modules, called clients. Modules are composed of two pieces: one public, the other private. The public part is called an "interface" and gives only the types and procedure interfaces that are needed for clients to use the module. The private section, called the "implementation" or "module", fills in the details with procedure definitions and other private declarations that are hidden from clients. * Menu: * Interface:: Interface layout and example * Implementation:: Module layout and example * Imports:: Using modules in programs  File: m3.info, Node: Interface, Next: Implementation, Prev: Modules, Up: Modules Interface --------- The interface is the public portion of a module. All declarations in the interface are visible to clients of the module. Interface files have the name of the module with an `.i3' extension, and have the following format: INTERFACE ; {Imports} (* *Note Imports:: *) {Declarations} (* *Note Declarations:: *) END . Generally, is the same as the name of the corresponding module. Here is an example of an interface for a module `MyModule' which is in a file called `MyModule.i3': INTERFACE MyModule; CONST MaxEntries = 53; TYPE Thing = RECORD name: TEXT; size: INTEGER END; PROCEDURE PrintThing(READONLY r: Thing); PROCEDURE MakeThing(n: TEXT; s: INTEGER): Thing; END MyModule.  File: m3.info, Node: Implementation, Next: Imports, Prev: Interface, Up: Modules Implementation -------------- The implementation is the private portion of a module. Implementation files have the name of the module with an `.m3' extension, and have the following format: MODULE [ EXPORTS { "," ... } ]; {Imports} (* *Note Imports:: *) {Declarations} (* *Note Declarations:: *) BEGIN (* Optional Module startup code; BEGIN required *) END . Generally, is the same as the name of the interface being implemented, but if not, the EXPORTS clause can be used to specify which interface(s) are being implemented. Here is an example of an implementation file MyModule.m3 that implements MyModule: MODULE MyModule; IMPORT IO; PROCEDURE PrintThing(READONLY r: Thing) = BEGIN IO.Put(r.name&"\t"); IO.PutInt(r.size); IO.Put("\n"); END PrintThing; PROCEDURE MakeThing(n: TEXT; s: INTEGER): Thing = BEGIN RETURN Thing{n, s}; END MakeThing; END MyModule.  File: m3.info, Node: Imports, Prev: Implementation, Up: Modules Imports ------- Modules gain access to declarations in other modules via the "import" mechanism. For example, a main module cannot use types or procedures defined in the IO Interface until it explicitly imports the definitions using the IMPORT statement like this: IMPORT IO; Once a module's declarations are imported, they are referenced by prefixing their names with the name of the module and a period (.) like this: IO.Put("Hello, world."); * Menu: * IMPORT Stmt::  File: m3.info, Node: IMPORT Stmt, Prev: Imports, Up: Imports IMPORT Statement ................ IMPORT [ AS ] { "," ... } ";" or FROM IMPORT { "," ...} ";" The "IMPORT" statement allows a module to see declarations such as procedures and types that appear in another module's interface. IMPORT statements must appear after the MODULE or INTERFACE statement and before any declarations. When using declarations imported from another module, the nonlocal declaration name must be qualified with the name of the module it was imported from unless the second form of the IMPORT statement is used. For example: INTERFACE Box; CONST Size = 30; END Box; (* Client Module *) MODULE Toys; IMPORT Box; VAR boxSize := Box.Size; (* Nonlocal declaration `Size' qualified by module name `Box' *) END Toys. (* Another Client Module *) MODULE Toys2; FROM Box IMPORT Size; VAR boxSize := Size; (* Nonlocal reference `Size' not qualified *) END Toys2;  File: m3.info, Node: Declarations, Next: Statements, Prev: Modules, Up: Language Elements Declarations ============ "Declarations" bind names with values or types. They appear in the outermost level of module interfaces and implementations after the IMPORT statement, as well as at the beginning of blocks. Kinds of declarations include constants, types, variables, procedures, and exceptions. They can appear in any order. * Menu: * Decl Examples:: Examples of common declarations * Constants:: CONST "=" ";" * Types:: TYPE "=" ";" * Variables:: VAR [ ":" ] [ ":=" ] ";" * Procedures:: PROCEDURE "=" ";" * Exceptions:: EXCEPTION [ "(" ")" ] ";"  File: m3.info, Node: Decl Examples, Next: Constants, Prev: Declarations, Up: Declarations Declarations Examples --------------------- CONST Pi = 3.14; (* REAL *) Maxsize = 30; (* INTEGER *) Space = ' '; (* CHAR *) TYPE Index = [1..Maxsize]; (* Subrange *) Letters = ['a'..'z']; (* Subrange *) Colors = {Red, Green, Blue, Yellow}; (* Enumerated *) ArrType = ARRAY Colors OF INTEGER; (* ARRAY *) ArrType2 = ARRAY [1..5] OF CHAR; (* ARRAY *) SetType = SET OF Letters; (* SET *) Ptr = REF Student; (* Pointer *) Student = RECORD (* RECORD *) name : TEXT; id : INTEGER; gpa : REAL; next : Ptr; END; VAR n : INTEGER := -15; (* INTEGER *) nonneg : CARDINAL := 5; (* CARDINAL *) x : REAL := 3.0; (* REAL *) ch : CHAR := 'Q'; (* CHAR *) done : BOOLEAN := TRUE; (* BOOLEAN *) str : TEXT := "Test"; (* TEXT *) arr : ArrType := ArrType{0,1,2,3}; (* ARRAY *) arr2 : ArrType2 := ArrType2{' ', ..}; (* ARRAY *) inFile : Rd.T; (* Reader *) outFile : Wr.T; (* Writer *) ltrSet : SetType := SetType{'a'..'d','z'}; (* SET *) head : Ptr := NIL (* Pointer *) st : Student (* RECORD *) := Student{"Joe", 15426, 3.35, NIL}; PROCEDURE One(y: REAL; VAR c: ArrType; x: INTEGER := 5) = (* Sample procedure definition. y is a value parameter; c is a variable parameter; x is a value parameter with a default value *) VAR i: INTEGER; (* local var *) BEGIN (* procedure body *) ; . . . ; END One; PROCEDURE Max(a, b: INTEGER): INTEGER = (* Sample function definition. *) VAR max: INTEGER; BEGIN max := a; IF a < b THEN max := b END; RETURN max; END Max;  File: m3.info, Node: Constants, Next: Types, Prev: Decl Examples, Up: Declarations Constants --------- CONST [ ":" ] "=" ";" Constant declarations are used to give names to values that can be computed at compile time. Here are some examples: CONST MaxValue: INTEGER = 5 * (25 - 3); (* INTEGER *) MinValue = 2; (* INTEGER *) RangeValue = MaxValue - MinValue + 1; (* INTEGER *) Name = "Arnie Shoestring"; (* TEXT *) Caps = SET OF CHARACTER{'A'..'Z'}; (* SET OF CHARACTER *)  File: m3.info, Node: Types, Next: Variables, Prev: Constants, Up: Declarations Types ----- TYPE "=" ";" It is convenient to be able to give names to types, and the TYPE declaration allows you to do this. may be one of the following: * Ordinal: INTEGER, CARDINAL, BOOLEAN, CHAR, subrange, enumerated * Floating point: REAL, LONGREAL, EXTENDED * Array: a structure containing a fixed number of elements of the same type * Record: a structure containing a fixed number of elements * Object: a record paired with a method suite * Set: a collection of ordinal values * Reference: a pointer to something * Procedure: a procedure signature * Menu: * Ordinal Types:: INTEGER, CARDINAL, BOOLEAN, CHAR, ... * Array Types:: ARRAY OF * Record Types:: RECORD END * Object Types:: OBJECT-METHODS-OVERRIDES-END * Set Types:: SET OF * Reference Types:: REF * Procedure Types:: PROCEDURE () { : }  File: m3.info, Node: Ordinal Types, Next: Array Types, Prev: Types, Up: Types Ordinal Types ............. INTEGER | CARDINAL | BOOLEAN | CHAR (* Built-in *) "{" "," "," ... "}" ";" (* Enumerated types *) "[" .. "]" ";" (* Subrange types *) "Ordinal" types denote sets of values in which each value has a unique successor. INTEGER The set of 32-bit signed integers (positive and negative). CARDINAL A synonym for the subrange [0..LAST(INTEGER)] BOOLEAN The enumeration {FALSE, TRUE} CHAR The set of ISO-Latin-1 characters (an extension of ASCII) Enumerated An enumerated type is an ordered set of values whose names are specified by the user, as follows: TYPE Day = {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; Values of an enumeration are specified as .: for example, `Day.Sunday' rather than just `Sunday'. Thus, you should keep enumeration type names short. Subrange A subrange is a subset of the values of the base type specified by the range ... and must both be values of the same ordinal type. Integer subranges are the most common: TYPE Digit = [0 .. 9]; (* subrange of INTEGER *) WeekDay = [Day.Monday .. Day.Friday]; (* subrange of Day *)  File: m3.info, Node: Array Types, Next: Record Types, Prev: Ordinal Types, Up: Types Array Types ........... ARRAY { "," ... } OF ";" `' must be an ordinal type (*note Ordinal Types::.). The common case is an integer subrange such as [1..numslots], but Modula-3 programs frequently use user-defined enumerations as well. `' can be any Modula-3 type, even another array. Here are some examples of array types: TYPE OneDimArray = ARRAY [1..20] OF REAL; OneDimArray2 = ARRAY ['A'..'Z'] OF INTEGER; TwoDimArray = ARRAY [1..20], [1..40] OF BOOLEAN; TwoDimArray2 = ARRAY [1..20] OF ARRAY [1..40] OF BOOLEAN; The built-in functions `FIRST', `LAST', and `NUMBER' can be used with array types and variables to return the index of the first and last slot and number of slots, respectively. For example, `FIRST(OneDimArray)' = 1; `NUMBER(OneDimArray2)' = 26.  File: m3.info, Node: Record Types, Next: Object Types, Prev: Array Types, Up: Types Record Types ............ RECORD { ";" ... } END ";" where = [ ":" ] [ ":=" ] Record types group related data items together in a unified data structure. Each data item, or field, has a name, a type, and an optional constant initializer. If you supply the constant initializer, you can omit the type; it will be inferred from the constant. Here are some examples: TYPE (* Record type with uninitialized fields *) Rec1 = RECORD x, y: INTEGER; name: TEXT END; (* Record type with initialized fields *) Rec2 = RECORD x, y := 0; (* Type is INTEGER *) name := "" (* Type is TEXT *) END;  File: m3.info, Node: Object Types, Next: Set Types, Prev: Record Types, Up: Types Object Types ............ [ ] OBJECT [ METHODS ] [ OVERRIDES ] END An object is a record paired with a "method suite": a collection of procedures that operate on the object. The fields of an object are specified just like those of records (*note Record Types::.). Methods are fields that hold procedure values. They are specified as follows: = { ";" ... } where = [ ":=" ] A method signature is a procedure signature (*note Procedure Types::.). If a procedure identifier is given, it must refer to a procedure which takes as its first parameter the object being defined, and other parameters as specified by the signature . Overrides specify new procedures for methods of the supertype: = { ";" ... } where = ":="  File: m3.info, Node: Set Types, Next: Reference Types, Prev: Object Types, Up: Types Set Types ......... SET OF can be any ordinal type (*note Ordinal Types::.) with a "reasonable" number of elements. For example, CHAR has 256 elements, a reasonable number, but a (32-bit) INTEGER has over 4 billion, an unreasonable number. So SET OF INTEGER is not possible, but SET OF [-100..100] is legal.  File: m3.info, Node: Reference Types, Next: Procedure Types, Prev: Set Types, Up: Types Reference Types ............... REF can be any type, even a reference type. This specifies a reference (pointer) to a value of type . For example: TYPE IntPtrType = REF INTEGER; (* A pointer to an integer *) ArrPtrType = REF ARRAY [1..5] OF CHAR; (* A pointer to an array *)  File: m3.info, Node: Procedure Types, Prev: Reference Types, Up: Types Procedure Types ............... PROCEDURE where = "(" { ";" ... } ")" [ ":" ] [ RAISES ( ANY | "{" { "," ... } "}" ) ] = [ VAR | READONLY | VALUE ] { "," ... } [ ":" ] [ ":=" ] If a result type for the procedure is specified, then the procedure must return a value of that type. If a constant expression is supplied as a default value for a formal parameter, the type may be omitted, and when the procedure is called, if an argument is not supplied for a formal with a default value, the default value is used to initialize the formal. The RAISES section specifies which exceptions the procedure is allowed to raise. Any exceptions that occur in the procedure, possibly as the result of a call to another procedure, that are not handled by the procedure and that do not appear in the RAISES clause cause a checked run-time error. If the RAISES section is omitted, then any exceptions raised cause a checked run-time error. The VAR, VALUE, and READONLY parameter modes determine how the actual argument is associated with the formal parameter: *VALUE This is the default mode, and means "call by value." The formal parameter contains a copy of the value of the actual argument. Changes to the formal parameter do not affect the actual argument. *VAR This means "call by reference." The formal parameter is linked to the actual argument. Changes to the formal parameter are reflected in the actual argument. In general, the actual argument must be a variable. No default value may be specified. *READONLY This means generally "call by reference," but the procedure may not modify the formal parameter. This provides the protection of call by value with the efficiency of call by reference, and should be used when large arrays or records need to be passed as parameters but should not be changed.  File: m3.info, Node: Variables, Next: Procedures, Prev: Types, Up: Declarations Variables --------- VAR { "," ... } [ ":" ] [ ":=" ] ";" Declaring variables in Modula-3 is much like Pascal, except that the type can be omitted if an initialization expression is provided. The initialization expression need not be constant. Here are some examples: VAR x: INTEGER; s := "Hello"; (* type TEXT is implied *) chars := SET OF CHAR{'a'..'z'}; (* type SET OF CHAR is implied *) y, z := 0; (* both y and z are INTEGER initialized to 0 *)  File: m3.info, Node: Procedures, Next: Exceptions, Prev: Variables, Up: Declarations Procedures ---------- PROCEDURE "=" BEGIN END ";" A procedure declaration is composed of an identifier, a signature (*note Procedure Types::.), optional local declarations, and statements. The identifier at the end of the procedure must match the id at the beginning. Declarations made in a procedure are local to the procedure: they exist only while the procedure is executing. If the procedure signature specifies a result type, the procedure is called a function procedure, and it must include a RETURN statement which returns an expression of the specified type. It is a checked runtime error for a function procedure to fail to return a result.  File: m3.info, Node: Exceptions, Prev: Procedures, Up: Declarations Exceptions ---------- EXCEPTION [ "(" ")" ] ";" Exceptions can only be declared at the top-level of a module or interface. If they will take an argument, a parameter type must be specified in parentheses. EXCEPTION UserAbort(TEXT); EndOfFile;  File: m3.info, Node: Statements, Next: Expressions, Prev: Declarations, Up: Language Elements Statements ========== Statements appear in procedures and in a module's top-level block. The statement terminator is the semicolon, which may be omitted after the last statement in a sequence (in which case it is a "statement separator"). Constructs such as FOR, WHILE, REPEAT, WITH, etc. can contain multiple statements and must be terminated by END. In general, whenever a Modula-3 language construct requires an END, it can contain zero, one, or more elements. * Menu: * Assignment Stmts:: INC, DEC, and := * Call and Return Stmts:: Calling and returning from procedures * Selection Stmts:: IF-THEN, CASE, TYPECASE * Looping Stmts:: FOR, WHILE, REPEAT, LOOP, EXIT * Compound Stmts:: BEGIN/END, WITH * Error Stmts:: RAISE, TRY-EXCEPT, TRY-FINALLY  File: m3.info, Node: Assignment Stmts, Next: Call and Return Stmts, Prev: Statements, Up: Statements Assignment Statements --------------------- ":=" Sets to the value of . must be a writable designator (generally, a variable or non-READONLY procedure parameter). INC "(" x { "," n} ")" DEC "(" x { "," n} ")" These are shortcuts for `x := x + n' and `x := x - n', respectively. If omitted, `n' defaults to 1. `x' must be an ordinal value (INTEGER, CHAR, or enumerated value). `n' must be an integer expression. Some examples are in order; intvar := 53; DEC(intvar); (* intvar = 52 *) charvar := 'a'; INC(charvar, 3); (* charvar = 'd' *)  File: m3.info, Node: Call and Return Stmts, Next: Selection Stmts, Prev: Assignment Stmts, Up: Statements Procedure Call and Return Statements ------------------------------------ To call a procedure, use one of the following two forms: 1) "(" { "," ... } ")" where = [ ":=" ] 2) EVAL The first form is used to call a "proper procedure" (one that does not specify a return type and thus has no return value). The second is used to call a function procedure when you want to throw away the return value. For example: IO.Put("Hello"); (* Call a proper procedure *) EVAL IO.EOF(); (* Call a function procedure and throw away result *) To return from a procedure, use the following statement: RETURN [ ] The RETURN statement is used inside procedures only to return control to the caller. A return value must be supplied if the procedure is a function procedure, but may not appear if the procedure is a proper procedure.  File: m3.info, Node: Selection Stmts, Next: Looping Stmts, Prev: Call and Return Stmts, Up: Statements Selection Statements -------------------- * Menu: * IF Stmt:: IF-THEN-ELSIF-ELSE-END * CASE Stmt:: CASE OF END * TYPECASE Stmt:: TYPECASE OF END  File: m3.info, Node: IF Stmt, Next: CASE Stmt, Prev: Selection Stmts, Up: Selection Stmts IF Statement ............ IF THEN { ELSIF THEN ... } [ ELSE ] END must be a boolean-valued expression. Here is an example: IF Text.Equal(txt,"Strawberry") THEN IO.Put("Not bad") ELSIF Text.Equal(txt,"Avacado") THEN IO.Put("Yuck!") ELSIF Text.Equal(txt,"Chocolate") THEN IO.Put("Yum") ELSE IO.Put("Nah.") END  File: m3.info, Node: CASE Stmt, Next: TYPECASE Stmt, Prev: IF Stmt, Up: Selection Stmts CASE Statement .............. CASE OF { "|" ... } [ ELSE ] END where = {