Modula-2 Reloaded

A Modern Typesafe & Literate Programming Notation

Site Menu

Project

Specification

Implementation

Recommendations

Reference

Needs Updating

Work in Progress

Wastebasket

Wiki Manual

edit SideBar

Language Report

Spec.LanguageReport History

Hide minor edits - Show changes to markup

2015-10-09 22:33 by trijezdci -
Changed line 704 from:

The target type of the opaque pointer is declared in the library's corresponding implementation part and it is therefore inaccessible to clients. It is declared using the PPOINTER TO type constructor.

to:

The target type of the opaque pointer is declared in the library's corresponding implementation part and it is therefore inaccessible to clients. It is declared using the POINTER TO type constructor.

2015-10-09 22:05 by trijezdci -
Changed line 224 from:

A blueprint defines constraints and requirements which libraries may be declared to meet. A library that promises to meet the constraints and requirements of a blueprint is said to declare conformance to the blueprint. When a library declares conformance to a blueprint, its actual conformance is compiler enforced. Certain language features such as binding procedures and functions to operators and built-in syntax are only available to libraries that declare conformance to certain blueprints.

to:

A blueprint defines constraints and requirements which libraries may be required to meet. A library that is required to meet the constraints and requirements of a blueprint is said to declare conformance to the blueprint. When a library declares conformance to a blueprint, its actual conformance is compiler enforced. Certain language features such as binding procedures and functions to operators and built-in syntax are only available to libraries that declare conformance to certain blueprints.

2015-10-08 18:53 by trijezdci -
Changed line 260 from:
 DEFINITION MODULE Foo Bar Baz?;
to:
 DEFINITION MODULE FooBarBaz;
Changed line 262 from:
to:
 END FooBarBaz.
Changed line 264 from:
 IMPORT Foo Bar Baz?; (* equivalent to: IMPORT Foo, Bar, Baz; *)
to:
 IMPORT FooBarBaz; (* equivalent to: IMPORT Foo, Bar, Baz; *)
2015-10-08 18:52 by trijezdci -
Changed lines 254-257 from:

Unqualified Aliasing

An IMPORT directive for single library may be followed by an ALIAS list. The ALIAS list contains one or more unqualified identifiers of the imported library. Imported identifiers whose unqualified names appear in an ALIAS list may then also be referenced by their unqualified identifiers within the importing module. This is called unqualified aliasing and it may cause name conflicts when aliasing identically named identifiers of different libraries. In the event of a name conflict a compile time error shall occur.

to:

Import Aggregation

A library that imports other libraries for the sole purpose of re-exporting them is called an import aggregator. This facility is useful for importing a collection of libraries or a library framework with a single import statement.

Changed lines 260-261 from:
 IMPORT FileIO ALIAS Status;
 VAR status : Status; (* unqualified alias for FileIO.Status *)
to:
 DEFINITION MODULE Foo Bar Baz?;
 IMPORT Foo+, Bar+, Baz+;
 END Foo Bar Baz?.
 MODULE Client;
 IMPORT Foo Bar Baz?; (* equivalent to: IMPORT Foo, Bar, Baz; *)
Deleted lines 266-271:

Import Aggregation

to do

Added lines 281-289:

Unqualified Aliasing

An IMPORT directive for single library may be followed by an ALIAS list. The ALIAS list contains one or more unqualified identifiers of the imported library. Imported identifiers whose unqualified names appear in an ALIAS list may then also be referenced by their unqualified identifiers within the importing module. This is called unqualified aliasing and it may cause name conflicts when aliasing identically named identifiers of different libraries. In the event of a name conflict a compile time error shall occur.

Example:

 IMPORT FileIO ALIAS Status;
 VAR status : Status; (* unqualified alias for FileIO.Status *)
2015-10-08 18:44 by trijezdci -
Changed lines 245-247 from:

An imported library may be re-exported by marking it with a re-export tag. Such a re-export tag is denoted by a plus sign trailing the module identifier in an IMPORT directive.

to:

A library being imported within a definition part of another library may be re-exported by marking it with a re-export tag. Such a re-export tag is denoted by a plus sign trailing the module identifier in an IMPORT directive.

When a library M3 imports another library M2 that re-exports another library M1, both M1 and M2 will be imported into M3.

2015-10-08 18:34 by trijezdci -
Added lines 239-249:

Import With Re-Export

By default, an imported library is not re-exported. That is, a library M1 imported in the definition part of a library M2 is only available within the definition and implementation parts of M2, but not within any client module M3 that imports M2.

An imported library may be re-exported by marking it with a re-export tag. Such a re-export tag is denoted by a plus sign trailing the module identifier in an IMPORT directive.

Example:

 IMPORT Foo+, Bar+, Baz+; (* import and re-export Foo, Bar and Baz *)
2015-10-08 14:07 by trijezdci -
Changed line 206 from:

Additionally, library modules may use entities provided by other library modules. In order to use the entities provided by a library module, the use of the library must be explicitly announced. A library whose use is so announced is said to be imported.

to:

Additionally, library modules may use entities provided by other library modules. In order to use the entities provided by a library module, the use of the library must be explicitly declared. A library whose use is so declared is said to be imported.

2015-10-08 14:04 by trijezdci -
Changed lines 220-222 from:

Blueprints

A blueprint represents a specification to enforce the consistency and integrity of libraries.

to:

Library Blueprints

A library blueprint represents a specification to enforce the consistency and integrity of libraries.

2015-10-08 14:03 by trijezdci -
Changed line 218 from:

Any entities defined or declared in a library's definition part are automatically visible and available in its implementation part without import. Entities declared only within the implementation part are not visible outside the implementation part. Such entities are said to be encapsulated.

to:

Any entities defined or declared in a library's definition part are automatically visible and available in its implementation part without import. By contrast, entities declared only within the implementation part are not visible outside the implementation part. Such entities are said to be encapsulated.

2015-10-08 14:01 by trijezdci -
Added lines 196-224:

Program Modules

A program module represents the topmost level of a Modula-2 program.

At minimum it will consist of a body that contains one or more statements that will be executed when the program is run. Additionally, it may define or declare constants, types, variables and procedures and function procedures of its own, or it may use such entities provided by one or more library modules. It does not provide any such entities to other modules.

Library Modules

Library modules represent repositories of constants, types, variables and procedures and function procedures for use by program modules and other library modules. Entities so provided are said to be exported by the library module.

Additionally, library modules may use entities provided by other library modules. In order to use the entities provided by a library module, the use of the library must be explicitly announced. A library whose use is so announced is said to be imported.

The Definition Part of Library Modules

The definition part of a library module represents the public interface of the library module.

Any entities defined or declared in the public interface of a library module are automatically exported.

The Implementation Part of Library Modules

The implementation part of a library module represents the implementation of the entities defined in its public interface.

Any entities defined or declared in a library's definition part are automatically visible and available in its implementation part without import. Entities declared only within the implementation part are not visible outside the implementation part. Such entities are said to be encapsulated.

Blueprints

A blueprint represents a specification to enforce the consistency and integrity of libraries.

A blueprint defines constraints and requirements which libraries may be declared to meet. A library that promises to meet the constraints and requirements of a blueprint is said to declare conformance to the blueprint. When a library declares conformance to a blueprint, its actual conformance is compiler enforced. Certain language features such as binding procedures and functions to operators and built-in syntax are only available to libraries that declare conformance to certain blueprints.

2015-10-08 09:26 by trijezdci -
Changed line 2617 from:

Pragma ENCODING specifies the encoding of the source file in which it appears. The pragma controls whether in addition to the characters that are permitted by the grammar, any further printable characters are permitted within quoted literals and comments. Semantics are given below.

to:

Pragma ENCODING specifies the encoding of the source file in which it appears. The pragma controls whether in addition to the characters that are permitted by the grammar, any further printable characters are permitted within quoted literals and comments. Any source file that is not strictly 7-bit ASCII encoded must contain an ENCODING pragma to specify its encoding. Semantics are given below.

2015-10-08 09:19 by trijezdci -
Changed line 2621 from:
No BOMno encoding pragma in sourceonly printable 7-bit ASCII characters as per grammar
to:
No BOMno encoding pragma in sourceonly printable 7-bit ASCII characters as per grammar
Changed lines 2623-2624 from:
with specifier "UTF8"any printable character that is encodable in UTF8
to:
with specifier "UTF8"any printable character encodable in UTF8
with implementation defined specifierany printable character encodable in specified encoding
Changed lines 2627-2628 from:
with specifier "UTF8"any printable character that is encodable in UTF8
Any other BOMpragma that matches BOM is mandatoryany printable characters encodable in specified encoding
to:
with specifier "UTF8"any printable character encodable in UTF8
Any other BOMuse of pragma is mandatoryany printable character encodable in specified encoding
2015-10-08 09:15 by trijezdci -
Changed line 2622 from:
with specifier "ASCII" 
to:
with specifier "ASCII"
Changed line 2625 from:
with specifier "ASCII" 
to:
with specifier "ASCII"
Changed line 2627 from:
Any other BOMimplementation definedUse of pragma is mandatory; BOM and specifier must match
to:
Any other BOMpragma that matches BOM is mandatoryany printable characters encodable in specified encoding
2015-10-08 09:11 by trijezdci -
Changed line 2622 from:
with specifier "ASCII"
to:
with specifier "ASCII" 
Changed line 2625 from:
with specifier "ASCII"
to:
with specifier "ASCII" 
Changed line 2627 from:
Any other BOM  
to:
Any other BOMimplementation definedUse of pragma is mandatory; BOM and specifier must match
2015-10-08 09:07 by trijezdci -
Changed lines 2621-2626 from:
No BOM  
  
  
UTF8 BOM  
  
  
to:
No BOMno encoding pragma in sourceonly printable 7-bit ASCII characters as per grammar
with specifier "ASCII"
with specifier "UTF8"any printable character that is encodable in UTF8
UTF8 BOMno encoding pragma in sourceonly printable 7-bit ASCII characters as per grammar
with specifier "ASCII"
with specifier "UTF8"any printable character that is encodable in UTF8
2015-10-08 09:01 by trijezdci -
Changed lines 2621-2622 from:
No BOM  
UTF8 BOM  
to:
No BOM  
  
  
UTF8 BOM  
  
  
2015-10-08 08:57 by trijezdci -
Changed lines 2621-2622 from:
   
to:
No BOM  
UTF8 BOM  
Any other BOM  
Deleted lines 2636-2638:

to do

2015-10-08 08:43 by trijezdci -
Changed line 2544 from:

Scenarios where pragma INLINE represents a mandate are procedures with a single statement, such as procedures with a single assignment and functions with a single RETURN statement. This inline guarantee exists to promote the use of data encapsulation. Mutators and accessors tagged with an INLINE pragma shall always be inlined.

to:

Scenarios where pragma INLINE represents a mandate to inline are procedures with a single statement, such as procedures with a single assignment and functions with a single RETURN statement. This inline guarantee exists to promote the use of data encapsulation. Mutators and accessors tagged with an INLINE pragma shall always be inlined.

2015-10-08 08:42 by trijezdci -
Changed line 2544 from:

Scenarios where the pragma represents a mandate are mutators and accessors, also known as setter procedures and getter functions. A mutator is a procedure whose only purpose is to store a value in an encapsulated variable or record field. An accessor is a function whose only purpose is to return the value of an encapsulated variable or record field.

to:

Scenarios where pragma INLINE represents a mandate are procedures with a single statement, such as procedures with a single assignment and functions with a single RETURN statement. This inline guarantee exists to promote the use of data encapsulation. Mutators and accessors tagged with an INLINE pragma shall always be inlined.

2015-10-08 08:32 by trijezdci -
Changed lines 2544-2545 from:

Scenarios where the pragma represents a mandate are mutators and accessors, also known as setter procedures and getter functions. A mutator is a procedure whose only purpose is to store a value in an encapsulated variable or record field. An accessor is a function whose only purpose is to return the value of an encapsulated variable or record field.

to:

Scenarios where the pragma represents a mandate are mutators and accessors, also known as setter procedures and getter functions. A mutator is a procedure whose only purpose is to store a value in an encapsulated variable or record field. An accessor is a function whose only purpose is to return the value of an encapsulated variable or record field.

Changed line 2551 from:
   foo := value (* hidden variable *)
to:
   hiddenFoo := value
Changed line 2557 from:
   RETURN foo (* hidden variable *)
to:
   RETURN hiddenFoo
2015-10-08 08:28 by trijezdci -
Changed lines 2537-2538 from:

Pragma INLINE represents a suggestion that inlining of a procedure is desirable. It shall appear both in the definition and implementation of the procedure. An informational message shall be emitted if the suggestion is not followed.

to:

Pragma INLINE represents a suggestion that inlining of a procedure is desirable except for certain scenarios where it is specifically mandated. It shall appear both in the definition and implementation of the procedure. An informational message shall be emitted if the suggestion is not followed.

Added lines 2544-2559:

Scenarios where the pragma represents a mandate are mutators and accessors, also known as setter procedures and getter functions. A mutator is a procedure whose only purpose is to store a value in an encapsulated variable or record field. An accessor is a function whose only purpose is to return the value of an encapsulated variable or record field.

Examples:

 (* Mutator with Inline Mandate *)
 PROCEDURE setFoo ( value : Foo ) <*INLINE*>;
 BEGIN
   foo := value (* hidden variable *)
 END setFoo;

 (* Accessor with Inline Mandate *)
 PROCEDURE foo : Foo <*INLINE*>;
 BEGIN
   RETURN foo (* hidden variable *)
 END foo;
2015-10-08 08:15 by trijezdci -
Changed line 2770 from:
 <*FORWARD TYPE List Node?*>
to:
 <*FORWARD TYPE ListNode*>
2015-10-08 08:15 by trijezdci -
Changed lines 2771-2772 from:
 TYPE List Node Ptr? = POINTER TO List Node?;
 TYPE List Node? = RECORD data : Foo; nextNode : List Node Ptr? END;
to:
 TYPE ListNodePtr = POINTER TO ListNode;
 TYPE ListNode = RECORD data : Foo; nextNode : ListNodePtr END;
2015-10-08 08:14 by trijezdci -
Changed lines 2766-2773 from:

to do

to:

Pragma FORWARD shall be the only means of forward declaration in a single-pass compiler. Multi-pass compilers shall silently ignore any occurrences of pragma FORWARD without analysis of its contents. Two kinds of forward declarations may be embedded in the pragma: Type and procedure declarations.

Example:

 <*FORWARD TYPE List Node?*>
 TYPE List Node Ptr? = POINTER TO List Node?;
 TYPE List Node? = RECORD data : Foo; nextNode : List Node Ptr? END;
2015-10-08 08:00 by trijezdci -
Changed lines 2-3 from:

Status: 2015-09-25 (update in progress)

to:

Status: 2015-10-08 (update in progress)

Added lines 2824-2831:

Incorrect Pragma Use and Unrecognised Pragmas

A pragma is incorrectly used if it is malformed, misplaced or any other rule for its use is not met. Any incorrect use of a mandatory pragma or a supported optional pragma shall cause a compile time error. Use of an unsafe pragma that is not supported or has not been enabled shall cause a compile time error.

Use of a safe optional pragma that is not supported shall cause a promotable soft compile time warning. An unsupported or unrecognised encoding specifier in pragma ENCODING shall cause a fatal compile time error. A code point sample list within pragma ENCODING shall be ignored if encoding verification is not supported. If a code point sample list or any excess samples are ignored a soft compile time warning shall be emitted. An unsupported or unrecognised language specifier in pragma FFI shall cause a compile time error.

An unrecognised implementation defined pragma shall be treated as specified by its default clause. An implementation defined pragma without a default clause is malformed and shall cause a compile time error.

2015-10-07 17:04 by trijezdci -
Changed line 230 from:

If the interface of a module defines a type that has the same name as the module then the type is referenced unqualified. This facility is useful in the construction of abstract data types as library modules.

to:

A type defined in the definition part of a library with the same name as the library is called a module type. When a library with a module type is imported, an unqualified alias for the module type is automatically defined in the importing module. This facility is useful in the construction of abstract data types as library modules.

2015-10-07 16:55 by trijezdci -
Changed line 251 from:

Unqualified aliasing of a qualified identifier that has already been aliased within the same module scope is permissible. Only the first aliasing is significant. Any subsequent aliasing is redundant. Redundant aliasing has no effect but shall cause a soft compile time warning.

to:

Aliasing of a qualified identifier that has already been aliased within the same module scope is permissible. Only the first aliasing is significant. Any subsequent aliasing is redundant. Redundant aliasing has no effect but shall cause a soft compile time warning.

2015-10-07 16:53 by trijezdci -
2015-10-07 16:52 by trijezdci -
Changed line 251 from:

Unqualified aliasing of an identifier that has already been aliased within the same module scope is permissible. Only the first aliasing is significant. Any subsequent aliasing is redundant. Redundant aliasing has no effect but shall cause a soft compile time warning.

to:

Unqualified aliasing of a qualified identifier that has already been aliased within the same module scope is permissible. Only the first aliasing is significant. Any subsequent aliasing is redundant. Redundant aliasing has no effect but shall cause a soft compile time warning.

2015-10-07 16:50 by trijezdci -
Added line 227:
Changed lines 242-255 from:

Unqualified Import

When an identifier is imported by unqualified import, it is made available in the importing module as is. This facility is intended predominantly for import from pseudo-modules and in cases where its use will reduce clutter and improve readability. If two identically named identifiers from different modules are imported unqualified, a name conflict occurs and a compile time error shall be emitted.

Example:

 FROM COMPILER IMPORT DEBUG;
 IF DEBUG THEN ... END; (* DEBUG instead of COMPILER.DEBUG *)

Wildcard Import

to do

to:
Changed lines 245-259 from:
Qualified Import of an Already Imported Module

Qualified import of a module that has already been imported by qualified import into the same module scope is permissible. Only the first import is significant. Any subsequent imports are redundant. A redundant import has no effect but shall cause a soft compile time warning.

Unqualified Import of an Already Imported Identifier

Unqualified import of an identifier that has already been imported unqualified from the same origin into the same module scope is permissible. Only the first import is significant. Any subsequent imports are redundant. A redundant import has no effect but shall cause a soft compile time warning.

Qualified and Unqualified Import of an Identifier

Unqualified import of an identifier that is also imported qualified into the same module scope is permissible. The imported entity may then be referenced both qualified and unqualified. No compile time warning shall be emitted.

Unqualified Import from an Already Imported ADT Library Module

Unqualified import of the type identifier of an ADT whole library module is also imported qualified into the same module scope results in a name conflict and shall cause a compile time error. However, unqualified import of any other identifier from an already imported ADT library module is permissible.

to:
Import of an Already Imported Module

Import of a module that has already been imported into the same module scope is permissible. Only the first import is significant. Any subsequent imports are redundant. A redundant import has no effect but shall cause a soft compile time warning.

Unqualified Aliasing of an Already Aliased Identifier

Unqualified aliasing of an identifier that has already been aliased within the same module scope is permissible. Only the first aliasing is significant. Any subsequent aliasing is redundant. Redundant aliasing has no effect but shall cause a soft compile time warning.

2015-10-07 16:38 by trijezdci -
Changed lines 198-199 from:

Import of Identifiers

to:

Importing Libraries

Qualified Import

Changed lines 212-214 from:

An IMPORT directive for single library may be followed by an ALIAS list. The ALIAS list contains one or more unqualified identifiers of the imported library. Imported identifiers whose unqualified names appear in an ALIAS list may then also be referenced by their unqualified identifiers within the importing module. This is called unqualified aliasing and it may cause name conflicts when aliasing identically named identifiers of different libraries.

to:

Unqualified Aliasing

An IMPORT directive for single library may be followed by an ALIAS list. The ALIAS list contains one or more unqualified identifiers of the imported library. Imported identifiers whose unqualified names appear in an ALIAS list may then also be referenced by their unqualified identifiers within the importing module. This is called unqualified aliasing and it may cause name conflicts when aliasing identically named identifiers of different libraries. In the event of a name conflict a compile time error shall occur.

2015-10-07 16:34 by trijezdci -
Changed lines 202-210 from:

Identifiers defined in the interface of a library module may be imported by other modules using an import directive. There are two kinds.

  • qualified import
  • unqualified import

Qualified Import

When an identifier is imported by qualified import, it must be qualified with the exporting module's module identifier when it is referenced in the importing module. This avoids name conflicts when importing identically named identifiers from different modules.

to:

Identifiers defined in the interface of a library module may be imported by other modules using an IMPORT directive. The import brings all exported identifiers into the scope of the importing module. Imported identifiers must be qualified with the exporting module's identifier when it is referenced in the importing module. This is called qualified import and it avoids name conflicts when importing identically named identifiers from different libraries.

Changed lines 206-207 from:
 IMPORT FileIO; (* qualified import of module FileIO *)
 VAR status : FileIO.Status; (* qualified identifier for Status *)
to:
 IMPORT FileIO; (* import of module FileIO *)
 VAR status : FileIO.Status; (* qualified identifier *)
Added lines 210-218:

An IMPORT directive for single library may be followed by an ALIAS list. The ALIAS list contains one or more unqualified identifiers of the imported library. Imported identifiers whose unqualified names appear in an ALIAS list may then also be referenced by their unqualified identifiers within the importing module. This is called unqualified aliasing and it may cause name conflicts when aliasing identically named identifiers of different libraries.

Example:

 IMPORT FileIO ALIAS Status;
 VAR status : Status; (* unqualified alias for FileIO.Status *)
Changed line 2632 from:
 <*ENCODING="UTF8" : "é"=0uE9, "©"=0uA9, "€"=0u20AC*>
to:
 <*ENCODING="UTF8" : "é"=0uE9, "©"=0uA9, "€"=0u20AC*>
2015-10-07 07:10 by trijezdci -
Changed line 147 from:
to:
2015-10-07 07:09 by trijezdci -
Changed lines 2442-2444 from:
to:

Mandatory Pragmas

Changed lines 2636-2637 from:
to:

Optional Pragmas

2015-10-07 07:06 by trijezdci -
Added lines 148-149:
Added lines 160-161:
Changed lines 174-176 from:
to:
Added line 2442:
Added line 2635:
2015-10-07 06:39 by trijezdci -
Deleted line 157:
Added line 166:
2015-10-07 06:38 by trijezdci -
Changed line 170 from:
to:
2015-10-07 06:35 by trijezdci -
Changed line 2822 from:
 <*G M2.Unroll Loops?=TRUE|WARN*> (* turn loop-unrolling on, ignore but warn if unknown *)
to:
 <*GM2.UnrollLoops=TRUE|WARN*> (* turn loop-unrolling on, ignore but warn if unknown *)
Added lines 2824-2825:

The default clause specifies how the pragma shall be treated by implementations that do not recognise it. Modes INFO and WARN mandate it shall be ignored with an informational or warning message respectively. Modes ERROR and FATAL mandate it shall cause a compile time or fatal compile time error respectively.

2015-10-07 06:33 by trijezdci -
Added lines 2809-2822:

Implementation Defined Pragmas

EBNF | Syntax Diagram

Implementation defined pragmas are compiler specific and generally non-portable.

An implementation defined pragma starts with a pragma symbol, which may be followed by a value assignment. The pragma ends with a mandatory default clause. The pragma symbol is an implementation defined name which shall be all-lowercase or mixed case. It may be qualified with an implementation prefix, indicating the name of the compiler. The value assignment follows if and only if the pragma is defined to hold a value. Such a value may be either a boolean value or a whole number.

Example:

 <*G M2.Unroll Loops?=TRUE|WARN*> (* turn loop-unrolling on, ignore but warn if unknown *)
2015-10-06 17:04 by trijezdci -
Changed line 2697 from:

Pragma PURITY marks a procedure with an intended purity level:

to:

Pragma PURITY marks a procedure with an intended purity level:

Changed lines 2714-2723 from:
to:

Pragma SINGLEASSIGN marks a variable as a single-assignment variable.

Such a variable should be assigned to only once in every possible runtime scenario. An implementation shall issue a promotable soft compile time warning for any single-assignment violation it may detect.

Example:

 VAR foo : INTEGER <*SINGLEASSIGN*>;
Changed lines 2729-2737 from:
to:

Pragma LOWLATENCY marks a local variable as latency-critical.

Marking a variable latency-critical represents a suggestion that mapping the variable to a machine register is desirable. An informational message shall be emitted if the suggestion is not followed.

Example:

 VAR foo : INTEGER <*LOWLATENCY*>;
Changed lines 2743-2751 from:
to:

Pragma VOLATILE marks a global variable as volatile.

By marking a variable volatile the author states that its value may change during the life time of a program even if no write access can be deduced from source code analysis. An implementation shall neither eliminate any variable so marked, nor shall it emit any unused variable warning for any variable so marked.

Example:

 VAR foo : INTEGER <*VOLATILE*>;
Changed lines 2757-2763 from:
to:

Pragma DEPRECATED marks a constant, variable, type or procedure as deprecated. A promotable soft com- pile time warning shall occur whenever an identifier of a deprecated entity is encountered.

Example:

 PROCEDURE foo ( bar : Baz ) <*DEPRECATED*>;
Changed lines 2769-2770 from:
to:

to do

Changed lines 2776-2783 from:
to:

Pragma ADDR maps a procedure or a global variable to a fixed memory address.

Examples:

 PROCEDURE Reset <*ADDR=0x12*>;
 VAR memoryMappedPort : CARDINAL <*ADDR=0x100*>;
Changed lines 2789-2797 from:
to:

Pragma FFI marks a Modula-2 definition part as the Modula-2 interface to a library implemented in another language. Procedure definitions and type declarations in the definition part shall follow the calling convention of the specified language environment for the current target. Predefined foreign interface specifiers are “C”, “Fortran”, “CLR” and “JVM”. If pragma FFI is provided, at least one foreign interface shall be supported. CLR or JVM support is recommended for implementations that target the CLR or JVM, respectively.

Example:

 DEFINITION MODULE stdio <*FFI=“C”*>;
 FROM UNSAFE IMPORT FFI, VARGLIST;
 PROCEDURE printf ( CONST format : ARRAY OF CHAR; arglist : VARGLIST );
Changed lines 2803-2809 from:
to:

Pragma FFIDENT maps a Modula-2 identifier of a foreign procedure or variable definition to its respective identifier in the foreign library. It shall be used when the foreign identifier conflicts with Modula-2 reserved words or reserved identifiers. The pragma may only be used within a foreign function interface module.

Examples:

 PROCEDURE Length ( s : ARRAY OF CHAR ) : INTEGER <*FFIDENT=”LENGTH”*>;
 VAR rwMode : [0..3] OF CARDINAL <*VOLATILE*> <*FFIDENT=”foobarlib_rw_mode”*>;
2015-10-06 16:51 by trijezdci -
Changed lines 2685-2691 from:
to:

Pragma NORETURN marks a regular procedure with a promise never to return in any runtime scenario. A soft compile time warning shall occur if the compiler cannot prove that the promise is kept.

Example:

 PROCEDURE Reboot System? <*NORETURN*>;
Added lines 2697-2707:

Pragma PURITY marks a procedure with an intended purity level:
• level 0 : may read and modify global state, may call procedures of any level (Default)
• level 1 : may read but not modify global state, may only call level 1 and level 3 procedures
• level 2 : may not read but modify global state, may only call level 2 and level 3 procedures
• level 3 : pure procedure, may not read nor modify global state, may only call level 3 procedures
An implementation shall emit a promotable soft compile time warning for any purity level violation.

Example:

 PROCEDURE Foo ( bar : Bar) : Baz <*PURITY=3*>; (* pure and side-effect free *)
2015-10-06 16:47 by trijezdci -
Changed line 2674 from:
 <*PADBITS=2*>            (* unused 2 bits *)
to:
 <*PADBITS=2*>           (* unused 2 bits *)
2015-10-06 16:46 by trijezdci -
Added lines 2668-2678:

Pragma PADBITS inserts a specified number of padding bits into a packed record type declaration. The maximum permitted value is 256 bits. The pragma is only permitted where alignment is set to zero.

Example:

 TYPE Packed = RECORD <*ALIGN=0*>
   oneBit    : [0..1] OF OCTET; (* 1 bit *)
 <*PADBITS=2*>            (* unused 2 bits *)
   twoBits   : [0..3] OF OCTET; (* 2 bits *)
   threeBits : [0..7] OF OCTET; (* 3 bits *)
 END; (* Packed *)
2015-10-04 16:00 by trijezdci -
Changed line 1236 from:
Addition, Set Unioninfixbinaryleft2
to:
Subtractioninfixbinaryleft2
2015-10-04 15:59 by trijezdci -
Changed lines 1234-1235 from:
+ Arithmetic Identityprefixunarynone2
to:
+ Addition, Set Unioninfixbinaryleft2
- Sign Inversionprefixunarynone2
Deleted lines 1236-1237:
- Sign Inversionprefixunarynone2
Addition, Set Unioninfixbinaryleft2
Changed lines 1363-1380 from:

Symbol + denotes a multi-purpose operator. There are two variants:

  • unary plus
  • binary plus
The Unary Plus Operator

The unary plus operator is non-associative and requires one operand. The operator precedes its operand.

Example:

 n := +42; (* arithmetic identity *)

The operator always represents the arithmetic identity operation. Its operands must be of a numeric type. Its result type is the operand type. Any use of the operator with an operand that is not a numeric type shall cause a compile time error. The unary plus operator is not bindable.

The Binary Plus Operator

The binary plus operator is left-associative and requires two operands.

to:

Symbol + denotes a multi-purpose operator. It is left associative and requires two operands.

2015-10-03 15:37 by trijezdci -
Added lines 2654-2679:

When the pragma is placed in a module header, it has module scope and determines the default alignment within the module. Permitted alignment values range from one to 32 octets.

Example:

 DEFINITION MODULE Foolib <*ALIGN=TSIZE(CARDINAL)*>; (* module scope *)

When the pragma is placed at the end of an array type declaration, it has array scope and determines the alignment of array components. Permitted alignment values range from one to 32 octets.

Example:

 TYPE Array = ARRAY 10 OF OCTET <*ALIGN=4*>; (* array scope *)

When the pragma is placed in the body of a record type declaration, it has field list scope and determines the alignment of record fields following the pragma. Permitted alignment values range from zero to 32 octets.

Example:

 TYPE Aligned = RECORD
 <*ALIGN=2*>  foo, bar : INTEGER;  (* 16 bit aligned *)
 <*ALIGN=4*>  baz, bam : INTEGER;  (* 32 bit aligned *)
 <*ALIGN=0*>  bits, bobs : [0..15] OF OCTET  (* packed *)
 END; (* Aligned *)

A value of zero specifies packing. When packing is specified, the allocation size of a field of an anonymous subrange of type OCTET, CARDINAL and LONGCARD is reduced to the smallest bit width required to encode its value range. Fields of any other type are aligned on octet boundaries when packing is specified.

2015-10-03 15:28 by trijezdci -
Deleted line 2416:
FORWARDForward declaration for single-pass compilersPragmaoptionalsafe
Added line 2425:
FORWARDForward declaration for single-pass compilersPragmaoptionalsafe
Added lines 2596-2597:
Added lines 2609-2610:
Added lines 2622-2623:
Changed lines 2644-2650 from:

Optional Pragma FORWARD

to:

to do

Optional Pragma ALIGN

EBNF | Syntax Diagram

Pragma ALIGN controls memory alignment. Alignment is specified in octets.

Changed lines 2658-2660 from:
to:
Changed lines 2664-2666 from:
to:
Changed lines 2670-2672 from:
to:
Changed lines 2676-2678 from:
to:
Changed lines 2682-2690 from:
to:

EBNF | Syntax Diagram

Optional Pragma VOLATILE

EBNF | Syntax Diagram

Changed lines 2694-2702 from:
to:

EBNF | Syntax Diagram

Optional Pragma FORWARD

EBNF | Syntax Diagram

Changed lines 2706-2708 from:
to:
Changed lines 2712-2714 from:
to:
Added lines 2717-2718:
2015-10-03 15:10 by trijezdci -
Changed line 2624 from:

An implementation that supports ASII only shall recognise encoding specifier "ASCII". It shall ignore any UTF8 BOM but reject any non-ASCII characters in the source file. An implementation that supports UTF8 shall recognise specifiers "ASCII" and "UTF8". Support for other encodings is implementation defined. Only one encoding pragma per source file is permitted.

to:

An implementation that supports ASCII only shall recognise encoding specifier "ASCII". It shall ignore any UTF8 BOM but reject any non-ASCII characters in the source file. An implementation that supports UTF8 shall recognise specifiers "ASCII" and "UTF8". Support for other encodings is implementation defined. Only one encoding pragma per source file is permitted.

2015-10-03 14:51 by trijezdci -
Changed line 2628 from:

As an option, pragma ENCODING may provide encoding verification. If supported, a list of arbitrary samples with pairs of quoted characters and their respective code point values may follow the encoding specifier.

to:

As an option, pragma ENCODING may provide encoding verification. If supported, a list of arbitrary samples with pairs of quoted characters and their respective code point values may follow the encoding specifier.

2015-10-03 14:50 by trijezdci -
Changed lines 2630-2631 from:

If a sample list is specified within the pragma body, a verification is carried out by matching the quoted liter- als in the sample list against their respective code points. Any mismatching pair in the sample list shall cause a fatal compilation error and compilation to abort immediately. The maximum number of code point samples is implementation defined. A maximum of at least 16 is recommended. Excess samples shall be ignored.

to:

If a sample list is specified within the pragma body, a verification is carried out by matching the quoted literals in the sample list against their respective code points. Any mismatching pair in the sample list shall cause a fatal compilation error and compilation to abort immediately. The maximum number of code point samples is implementation defined. A maximum of at least 16 is recommended. Excess samples shall be ignored.

Changed line 2634 from:
 <*ENCODING=”UTF 8?” : “é”=0uE9, “©”=0uA9, “€”=0u20AC*>
to:
 <*ENCODING="UTF8" : "é"=0uE9, "©"=0uA9, "€"=0u20AC*>
2015-10-03 14:48 by trijezdci -
Changed lines 2618-2640 from:
to:

Pragma ENCODING specifies the encoding of the source file in which it appears. The pragma controls whether in addition to the characters that are permitted by the grammar, any further printable characters are permitted within quoted literals and comments. Semantics are given below.

BOMEncoding PragmaCharacters Permitted in Quoted Literals and Comments
   

An implementation that supports ASII only shall recognise encoding specifier "ASCII". It shall ignore any UTF8 BOM but reject any non-ASCII characters in the source file. An implementation that supports UTF8 shall recognise specifiers "ASCII" and "UTF8". Support for other encodings is implementation defined. Only one encoding pragma per source file is permitted.

Encoding Verification

As an option, pragma ENCODING may provide encoding verification. If supported, a list of arbitrary samples with pairs of quoted characters and their respective code point values may follow the encoding specifier.

If a sample list is specified within the pragma body, a verification is carried out by matching the quoted liter- als in the sample list against their respective code points. Any mismatching pair in the sample list shall cause a fatal compilation error and compilation to abort immediately. The maximum number of code point samples is implementation defined. A maximum of at least 16 is recommended. Excess samples shall be ignored.

Example:

 <*ENCODING=”UTF 8?” : “é”=0uE9, “©”=0uA9, “€”=0u20AC*>
Changed line 2642 from:

Pragma FORWARD

to:

Optional Pragma FORWARD

2015-10-03 14:37 by trijezdci -
Changed line 2596 from:

Pragma OUT marks a formal VAR parameter p in the header of a procedure P with a promise to write. The promise is kept if it can be proven that p is written to within the body of P in every possible runtime scenario, either by assignment or by passing p to an OUT marked VAR paramter in a procedure call other than via a variable of a procedure type. A promotable soft compile time warning shall occur if the promise is not kept.

to:

Pragma OUT marks a formal VAR parameter p in the header of a procedure P with a promise to write. The promise is kept if it can be proven at compile time that p is written to within the body of P in every possible runtime scenario, either by assignment or by passing p to an OUT marked VAR paramter in a procedure call. A promotable soft compile time warning shall occur if the promise is not kept.

2015-10-03 14:35 by trijezdci -
Changed line 2607 from:

Pragma GENERATED encodes the name of the template a library was generated from and the date and time when it was last generated. The pragma is inserted into the source by the Modula-2 template engine. An im- plementation shall use the information recorded in the pragma to avoid unnecessary regeneration of libraries.

to:

Pragma GENERATED encodes the name of the template a library was generated from and the date and time when it was last generated. The pragma is inserted into the source by the Modula-2 template engine. A conforming implementation shall use the information recorded in the pragma to avoid unnecessary regeneration of libraries.

2015-10-03 14:34 by trijezdci -
Changed line 2611 from:
 <*GENERATED FROM Assoc Arrays?, 2014-12-31, 23:59:59+0100*>
to:
 <*GENERATED FROM AssocArrays, 2014-12-31, 23:59:59+0100*>
2015-10-03 14:33 by trijezdci -
Added lines 2606-2612:

Pragma GENERATED encodes the name of the template a library was generated from and the date and time when it was last generated. The pragma is inserted into the source by the Modula-2 template engine. An im- plementation shall use the information recorded in the pragma to avoid unnecessary regeneration of libraries.

Example:

 <*GENERATED FROM Assoc Arrays?, 2014-12-31, 23:59:59+0100*>
2015-10-03 14:29 by trijezdci -
Changed line 2585 from:

Pragma BLOCKING marks a procedure as blocking to indicate that it invokes a procedure or API that may cause it to wait for an event or availability of a shared resource. If a procedure not marked as blocking calls a procedure that is marked as blocking, a promotable compile time warning shall occur.

to:

Pragma BLOCKING marks a procedure as blocking to indicate that it invokes a procedure or API that may cause it to wait for an event or availability of a shared resource or the completion of an IO operation. If a procedure not marked as blocking calls a procedure that is marked as blocking, a promotable compile time warning shall occur.

2015-10-03 14:26 by trijezdci -
Changed line 2585 from:

Pragma BLOCKING marks a procedure as blocking to indicate that may invokes a procedure or API that may cause it to be suspended to wait for an event or availability of a shared resource. If a procedure not marked as blocking calls a procedure that is marked as blocking, a promotable compile time warning shall occur.

to:

Pragma BLOCKING marks a procedure as blocking to indicate that it invokes a procedure or API that may cause it to wait for an event or availability of a shared resource. If a procedure not marked as blocking calls a procedure that is marked as blocking, a promotable compile time warning shall occur.

2015-10-03 14:25 by trijezdci -
Changed lines 2585-2590 from:

Pragma BLOCKING marks a procedure as blocking.

to:

Pragma BLOCKING marks a procedure as blocking to indicate that may invokes a procedure or API that may cause it to be suspended to wait for an event or availability of a shared resource. If a procedure not marked as blocking calls a procedure that is marked as blocking, a promotable compile time warning shall occur.

Example:

 PROCEDURE Read ( f : File; VAR ch : CHAR ) <*BLOCKING*>;
2015-10-03 14:11 by trijezdci -
Added lines 2558-2559:
Added lines 2571-2572:
Added lines 2579-2585:

Pragma BLOCKING

EBNF | Syntax Diagram

Pragma BLOCKING marks a procedure as blocking.

2015-10-03 13:56 by trijezdci -
Changed lines 2558-2565 from:
to:

Pragma INLINE represents a suggestion that inlining of a procedure is desirable. It shall appear both in the definition and implementation of the procedure. An informational message shall be emitted if the suggestion is not followed.

Example:

 PROCEDURE Foo ( bar : Baz ) <*INLINE*>;
Changed lines 2569-2576 from:
to:

Pragma NOINLINE represents a mandate that a procedure shall not be inlined. It shall appear both in the definition and implementation of the procedure. The use of pragmas INLINE and NOINLINE is mutually exclusive.

Example:

 PROCEDURE Foo ( bar : Baz ) <*NOINLINE*>;
Added lines 2579-2585:

Pragma OUT marks a formal VAR parameter p in the header of a procedure P with a promise to write. The promise is kept if it can be proven that p is written to within the body of P in every possible runtime scenario, either by assignment or by passing p to an OUT marked VAR paramter in a procedure call other than via a variable of a procedure type. A promotable soft compile time warning shall occur if the promise is not kept.

Example:

 PROCEDURE init ( VAR n : OCTET <*OUT*> );
2015-10-03 13:48 by trijezdci -
Changed lines 2524-2526 from:
 <*IF (TSIZE(INTEGER)=2)*> CONST Model = TypeModel.small;
 <*ELSIF (TSIZE(INTEGER)=4)*> CONST Model = TypeModel.medium;
 <*ELSIF (TSIZE(INTEGER)=8)*> CONST Model = TypeModel.large;
to:
 <*IF (TSIZE(INTEGER)=2)*>
 CONST Model = TypeModel.small;
 <*ELSIF (TSIZE(INTEGER)=4)*>
 CONST Model = TypeModel.medium;
 <*ELSIF (TSIZE(INTEGER)=8)*>
 CONST Model = TypeModel.large;
2015-10-03 13:46 by trijezdci -
Added lines 2533-2549:
Pragma IF

Pragma IF denoted the start of the initial branch of a conditional compilation section. The source text within the initial branch is only processed if the condition specified in the pragma is true, otherwise it is ignored.

Pragma ELSIF

Pragma ELSIF denotes the start of an alternative branch in a conditional compilation section. The source text within an alternative branch is only processed if the condition specified in the pragma is true and the conditions specified for the corresponding initial branch and all preceding alternative branches of the same nesting level are false, otherwise it is ignored.

Pragma ELSE

Pragma ELSE denotes the start of a default branch within a conditional compilation section. The source text within the default branch is only processed if the conditions specified for the initial branch and all preceding alternative branches of the same nesting level are false, otherwise it is ignored.

Pragma END

Pragma END denotes the end of a conditional compilation section.

2015-10-03 13:36 by trijezdci -
Changed lines 2524-2526 from:
 <*IF (TSIZE(INTEGER)=2)*> CONST Model = Type Model?.small;
 <*ELSIF (TSIZE(INTEGER)=4)*> CONST Model = Type Model?.medium;
 <*ELSIF (TSIZE(INTEGER)=8)*> CONST Model = Type Model?.large;
to:
 <*IF (TSIZE(INTEGER)=2)*> CONST Model = TypeModel.small;
 <*ELSIF (TSIZE(INTEGER)=4)*> CONST Model = TypeModel.medium;
 <*ELSIF (TSIZE(INTEGER)=8)*> CONST Model = TypeModel.large;
Changed line 2528 from:
to:
 UNSAFE.HALT(Errors.UnsupportedTypeModel);
Changed line 2532 from:

Conditional compilation sections may be nested up to a maximum nesting level of ten including the outermost conditional compilation section. A fatal compile time error shall occur if this value is exceeded. Pragma IF increments the current nesting level, ELSIF and ELSE leave it unchanged and END decrements it.

to:

Conditional compilation sections may be nested up to a maximum nesting level of ten including the outermost conditional compilation section. A fatal compile time error shall occur if this value is exceeded. Pragma IF increments the current nesting level, Pragmas ELSIF and ELSE leave it unchanged and Pragma END decrements it.

2015-10-03 13:35 by trijezdci -
Added lines 2515-2532:

EBNF | Syntax Diagram

Conditional compilation pragmas are used to denote conditional compilation sections. A conditional compilation section is an arbitrary portion of source text that is either compiled or ignored, depending on whether or not a given condition in form of a boolean compile time expression within the pragma is met.

A conditional compilation section consists of an initial conditional compilation branch denoted by pragma IF, followed by zero or more alternative branches denoted by pragma ELSIF, followed by an optional default branch denoted by pragma ELSE, followed by closing pragma END.

Example:

 <*IF (TSIZE(INTEGER)=2)*> CONST Model = Type Model?.small;
 <*ELSIF (TSIZE(INTEGER)=4)*> CONST Model = Type Model?.medium;
 <*ELSIF (TSIZE(INTEGER)=8)*> CONST Model = Type Model?.large;
 <*ELSE*> <*MSG=FATAL : "unsupported type model."*>
 UNSAFE.HALT(Errors.Unsupported Type Model?);
 <*END*>

Conditional compilation sections may be nested up to a maximum nesting level of ten including the outermost conditional compilation section. A fatal compile time error shall occur if this value is exceeded. Pragma IF increments the current nesting level, ELSIF and ELSE leave it unchanged and END decrements it.

2015-10-03 13:22 by trijezdci -
Changed line 2479 from:
 <*MSG=INFO : "Library documentation is available at `http://foolib.com"*>
to:
 <*MSG=INFO : "Library documentation is available at http://foolib.com"*>
2015-10-03 13:20 by trijezdci -
Changed line 2479 from:
 <*MSG=INFO : "Library documentation is available at http://foolib.com"*>
to:
 <*MSG=INFO : "Library documentation is available at `http://foolib.com"*>
2015-10-03 13:19 by trijezdci -
Added lines 2471-2510:
Message Mode INFO

Message mode selector INFO is used to emit user defined information during comilation. Emitting an informational message does not change the warning or error count of the current compilation run and it does not cause comilation to fail or abort. A compiler switch may be provided to silence informational messages.

Example:

 <*MSG=INFO : "Library documentation is available at http://foolib.com"*>
Message Mode WARN

Message mode selector WARN is used to emit user defined warnings during compilation. Emitting a warning message increments the warning count of the current compilation run but it does not cause compilation to fail or abort. Warnings emitted via pragma MSG are always hard compile time warnings.

Example:

 <*MSG=WARN : "foo exceeds maximum value. A default of 100 will be used."*>
Message Mode ERROR

Message mode selector ERROR is used to emit user defined error messages during compilation. Emitting an error message increments the error count of the current compilation run and will ultimately cause compilation to fail but it does not cause an immediate abort. User defined error messages may not be silenced.

Example:

 <*MSG=ERROR : "Value of foo is outside of its legal range of [1..100]."*>
Message Mode FATAL

Message mode selector FATAL is used to emit user defined fatal error messages during compilation. Emitting a fatal error message increments the error count of the current compilation run and causes compilation to fail and abort immediately. User defined fatal error messages may not be silenced. Abort may not be avoided.

Example:

 <*MSG=ABORT : "Unsupported target architecture."*>
2015-10-03 13:08 by trijezdci -
Added line 2398:

Added line 2455:

Added lines 2471-2535:

Pragmas For Conditional Compilation

Pragma INLINE

Pragma NOINLINE

Pragma OUT

Pragma GENERATED

Pragma ENCODING

Pragma FORWARD

Optional Pragma PADBITS

Optional Pragma NORETURN

Optional Pragma PURITY

Optional Pragma SINGLEASSIGN

Optional Pragma LOWLATENCY

Optional Pragma DEPRECATED

Optional Pragma ADDR

Optional Pragma FFI

Optional Pragma FFIDENT

2015-10-03 12:50 by trijezdci -
Changed line 2415 from:
Global Varglobal variable declarationbetween variablde declaration and its trailing semicolon
to:
Global Varglobal variable declarationbetween variable declaration and its trailing semicolon
Added lines 2419-2443:

Pragma Safety

A pragma is safe if it provides a safe facility. It is unsafe if it provides an unsafe facility. The use of an unsafe pragma must be enabled by unqualified import of its identically named enabler. Pragma enablers of supported unsafe pragmas shall be provided by pseudo-module UNSAFE.

Language Defined Pragmas In Detail

Pragma MSG

EBNF | Syntax Diagram

Pragma MSG emits four different types of user definable console messages during compilation: informational messages, compilation warnings, compilation error messages and fatal compilation error messages. The type of a message is determined by a message mode selector. Console messages consist of a quoted string literal, the value of a compile time constant or pragma or a comma separated list of these components.

The value of a pragma that represents a compile time setting is denoted by the pragma symbol prefixed with a question mark. Language defined pragmas that represent compile settings are ALIGN and ENCODING.

Examples:

 <*MSG=INFO : "The current alignment is: ", ?ALIGN*> (* emits alignment value *)
 <*MSG=INFO : "The current encoding is: ", ?ENCODING*> (* emits encoding name *)

Only pragmas that represent compile time settings may be queried in this way.

2015-10-03 12:38 by trijezdci -
Changed lines 2388-2389 from:
GENERATEDDate/time stamp of library generationModule headermandatorysafe
ENCODINGSpecify source text character encodingModule headermandatorysafe
to:
GENERATEDDate/time stamp of library generationFilemandatorysafe
ENCODINGSpecify source text character encodingFilemandatorysafe
Changed lines 2391-2392 from:
ALIGNSpecify memory alignmentModule, Type, Fieldlistoptionalsafe
PADBITSInsert padding bits into packed recordsFieldlistoptionalsafe
to:
ALIGNSpecify memory alignmentModule, Type, Recordoptionalsafe
PADBITSInsert padding bits into packed recordsRecordoptionalsafe
Changed lines 2395-2397 from:
SINGLEASSIGNMark single-assignment variableVAR declarationoptionalsafe
LOWLATENCYMark latency-critical variablelocal VAR declarationoptionalsafe
VOLATILEMark volatile variableglobal VAR declarationoptionalsafe
to:
SINGLEASSIGNMark single-assignment variableGlobal and Local Varoptionalsafe
LOWLATENCYMark latency-critical variableLocal Vsroptionalsafe
VOLATILEMark volatile variableGlobal Varoptionalsafe
Changed lines 2400-2401 from:
FFISpecify foreign function interfaceModule headeroptionalunsafe
FFIDENTMap identifier to foreign identifierVAR, PROCEDUREoptionalunsafe
to:
FFISpecify foreign function interfaceModuleoptionalunsafe
FFIDENTMap identifier to foreign identifierGlobal Var, Procedureoptionalunsafe

Pragma Scope And Positioning

The position where a pragma may appear in the source text depends on its scope.

ScopeApplies toInsertion Point
Fileentire fileat the beginning of a file or immediately after a BOM
Moduleentire modulebetween module header and its trailing semicolon
Pragmapragma itselfanywhere a block comment may appear
Typearray or procedure type declarationbetween type declaration and its trailing semicolon
Recordinsertion point forwardanywhere a fieldlist may appear within a record
Global Varglobal variable declarationbetween variablde declaration and its trailing semicolon
Procedureprocedure declarationbetween procedure header and its trailing semicolon
Formal Parameterformal parameter declarationimmediately after the formal type of the parameter
Local Varlocal variable declarationbetween variable declaration and its trailing semicolon
2015-10-02 17:52 by trijezdci -
Changed line 2381 from:
IFConditional compilation, if-branchPragmamandatorysafe
to:
IFConditional compilation, if-branchPragmamandatorysafe
2015-10-02 17:50 by trijezdci -
Changed lines 2399-2401 from:
ADDRMap procedure or variable to fixed addressDefinition, Declarationoptionalsafe
FFISpecify foreign function interfaceModule headeroptionalsafe
FFIDENTMap identifier to foreign identifierVAR, PROCEDUREoptionalsafe
to:
ADDRMap procedure or variable to fixed addressDefinition, Declarationoptionalunsafe
FFISpecify foreign function interfaceModule headeroptionalunsafe
FFIDENTMap identifier to foreign identifierVAR, PROCEDUREoptionalunsafe
2015-10-02 17:49 by trijezdci -
Changed lines 2376-2401 from:

to do

to:

Pragmas are directives to the compiler, used to control or influence the compilation process, but they do not change the meaning of a program. Language defined pragmas and their properties are listed below:

PragmaPurposeScopeAvailabilitySafety
MSGEmit compile time console messagesPragmamandatorysafe
IFConditional compilation, if-branchPragmamandatorysafe
ELSIFConditional compilation, elsif-branchPragmamandatorysafe
ELSEConditional compilation, else-branchPragmamandatorysafe
ENDConditional compilation, terminatorPragmamandatorysafe
INLINESuggest procedure inliningProceduremandatorysafe
NOINLINEInhibit procedure inliningProceduremandatorysafe
OUTPromise to write to a VAR parameterFormal parametermandatorysafe
GENERATEDDate/time stamp of library generationModule headermandatorysafe
ENCODINGSpecify source text character encodingModule headermandatorysafe
FORWARDForward declaration for single-pass compilersPragmaoptionalsafe
ALIGNSpecify memory alignmentModule, Type, Fieldlistoptionalsafe
PADBITSInsert padding bits into packed recordsFieldlistoptionalsafe
NORETURNPromise never to returnRegular procedureoptionalsafe
PURITYSpecify procedure purity levelProcedure, Typeoptionalsafe
SINGLEASSIGNMark single-assignment variableVAR declarationoptionalsafe
LOWLATENCYMark latency-critical variablelocal VAR declarationoptionalsafe
VOLATILEMark volatile variableglobal VAR declarationoptionalsafe
DEPRECATEDMark deprecated entityDefinition, Declarationoptionalsafe
ADDRMap procedure or variable to fixed addressDefinition, Declarationoptionalsafe
FFISpecify foreign function interfaceModule headeroptionalsafe
FFIDENTMap identifier to foreign identifierVAR, PROCEDUREoptionalsafe
2015-10-01 17:55 by trijezdci -
Changed line 1181 from:
The Array Slice Selector
to:
The Record Field Selector
2015-09-29 19:11 by trijezdci -
Changed line 243 from:

A definition module represents the definition part of a library, that is, its public interface. Any identifier defined in the definition part is available for use without export in the corresponding implementation part of the library and it is automatically exported, that is, it is available for import by other modules.

to:

A definition module represents the definition part of a library, that is, its public interface. Any identifier defined in the definition part is available for use without import in the corresponding implementation part of the library and it is automatically exported, that is, it is available for import by other modules.

2015-09-29 19:10 by trijezdci -
Changed lines 248-249 from:
 PROCEDURE Letter Count? ( str : ARRAY OF CHAR ) : CARDINAL;
 PROCEDURE Digit Count? ( str : ARRAY OF CHAR ) : CARDINAL;
to:
 PROCEDURE LetterCount ( str : ARRAY OF CHAR ) : CARDINAL;
 PROCEDURE DigitCount ( str : ARRAY OF CHAR ) : CARDINAL;
2015-09-29 19:10 by trijezdci -
Changed lines 243-253 from:

to do

to:

A definition module represents the definition part of a library, that is, its public interface. Any identifier defined in the definition part is available for use without export in the corresponding implementation part of the library and it is automatically exported, that is, it is available for import by other modules.

Example:

 DEFINITION MODULE Counting;
 PROCEDURE Letter Count? ( str : ARRAY OF CHAR ) : CARDINAL;
 PROCEDURE Digit Count? ( str : ARRAY OF CHAR ) : CARDINAL;
 END Counting.
2015-09-29 19:01 by trijezdci -
Changed lines 208-212 from:

example to paste

to:

Example:

 FROM COMPILER IMPORT DEBUG;
 IF DEBUG THEN ... END; (* DEBUG instead of COMPILER.DEBUG *)
2015-09-28 23:59 by trijezdci -
Changed lines 1083-1084 from:

Runtime and Compile Time Expressions

to:

Evaluation Time

2015-09-28 23:56 by trijezdci -
Changed line 1081 from:

An expression is a computational formula that evaluates to a value. An expression consists of operands, operators and optional punctuation.

to:

An expression is a computational formula that evaluates to a value. An expression may consist of one of more sub-expressions. Sub-expressions consists of operands, operators and optional punctuation.

2015-09-28 16:31 by trijezdci -
Changed lines 182-183 from:
 IMPORT File IO; (* qualified import of module File IO *)
 VAR status : File IO.Status; (* qualified identifier for Status *)
to:
 IMPORT FileIO; (* qualified import of module FileIO *)
 VAR status : FileIO.Status; (* qualified identifier for Status *)
Added lines 218-219:

Qualified import of a module that has already been imported by qualified import into the same module scope is permissible. Only the first import is significant. Any subsequent imports are redundant. A redundant import has no effect but shall cause a soft compile time warning.

Added lines 222-223:

Unqualified import of an identifier that has already been imported unqualified from the same origin into the same module scope is permissible. Only the first import is significant. Any subsequent imports are redundant. A redundant import has no effect but shall cause a soft compile time warning.

Added lines 226-227:

Unqualified import of an identifier that is also imported qualified into the same module scope is permissible. The imported entity may then be referenced both qualified and unqualified. No compile time warning shall be emitted.

Added line 230:

Unqualified import of the type identifier of an ADT whole library module is also imported qualified into the same module scope results in a name conflict and shall cause a compile time error. However, unqualified import of any other identifier from an already imported ADT library module is permissible.

2015-09-28 16:25 by trijezdci -
Added lines 171-187:

Identifiers defined in the interface of a library module may be imported by other modules using an import directive. There are two kinds.

  • qualified import
  • unqualified import

Qualified Import

When an identifier is imported by qualified import, it must be qualified with the exporting module's module identifier when it is referenced in the importing module. This avoids name conflicts when importing identically named identifiers from different modules.

Example:

 IMPORT File IO; (* qualified import of module File IO *)
 VAR status : File IO.Status; (* qualified identifier for Status *)

Import Aggregation

Added lines 189-223:

Importing Modules as Types

If the interface of a module defines a type that has the same name as the module then the type is referenced unqualified. This facility is useful in the construction of abstract data types as library modules.

Example:

 DEFINITION MODULE Colour;
 TYPE Colour = ( red, green, blue );
 (* public interface *)
 END Colour.
 IMPORT Colour; (* import module Colour *)
 VAR colour : Colour; (* type referenced as Colour instead of Colour.Colour *)

Unqualified Import

When an identifier is imported by unqualified import, it is made available in the importing module as is. This facility is intended predominantly for import from pseudo-modules and in cases where its use will reduce clutter and improve readability. If two identically named identifiers from different modules are imported unqualified, a name conflict occurs and a compile time error shall be emitted.

example to paste

Wildcard Import

to do

Repeat Import

Qualified Import of an Already Imported Module
Unqualified Import of an Already Imported Identifier
Qualified and Unqualified Import of an Identifier
Unqualified Import from an Already Imported ADT Library Module
2015-09-28 15:36 by trijezdci -
Added line 158:
  • a program module
Changed lines 161-162 from:
  • a program module
  • a blueprint
to:
  • a library blueprint
2015-09-28 15:34 by trijezdci -
Changed lines 156-164 from:

to do

to:

A compilation unit is a sequence of source code that can be independently compiled. There are four kinds.

  • the definition part of a library module
  • the implementation part of a library module
  • a program module
  • a blueprint

Any Modula-2 program consists of exactly one program module and zero or more library modules and blueprints.

2015-09-28 15:26 by trijezdci -
Changed line 203 from:

A variable declared in the top level of a library module's definition part is always exported immutable. It may be assigned to within the library module's implementation part but it may not be assigned to within modules that import it. A pointer variable declared in the top level of a definition part shall cause a promotable compile time warning unless it is of an opaque type or a POINTER TO CONST type.

to:

A variable declared in the top level of a library module's definition part is always exported immutable. It may be assigned to within the library module's implementation part but it may not be assigned to within modules that import it. A pointer variable declared in the top level of a definition part shall cause a promotable compile time warning unless it is of an opaque type or a POINTER TO CONST type.

2015-09-28 15:26 by trijezdci -
Added lines 198-207:

Global Variables

A variable declared in the top level of a module has a global life span. It exists throughout the runtime of the program. However, it does not have global scope. It is only visible within the module where it is declared, and it it is exported, within modules that import it.

A variable declared in the top level of a library module's definition part is always exported immutable. It may be assigned to within the library module's implementation part but it may not be assigned to within modules that import it. A pointer variable declared in the top level of a definition part shall cause a promotable compile time warning unless it is of an opaque type or a POINTER TO CONST type.

Local Variables

A variable declared within a procedure has local life span and local scope. It only exists during the lifetime of the procedure and it is only visible within the procedure where it is declared and procedures local to the procedure where it is declared.

2015-09-28 14:58 by trijezdci -
Changed line 192 from:

A variable is a container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is specified in its definition. Its definition is immutable. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

to:

A variable is a container for a mutable value. A variable is always associated with a type and it can only hold values of its type. Its type is specified in its definition. Its definition is immutable. The value of a variable is undetermined when it is allocated. A value may be assigned at runtime. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

2015-09-28 14:55 by trijezdci -
Changed line 192 from:

A variable is a container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is set at compile time and cannot be changed. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

to:

A variable is a container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is specified in its definition. Its definition is immutable. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

2015-09-28 14:51 by trijezdci -
Changed line 192 from:

A variable is an container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is set at compile time and cannot be changed. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

to:

A variable is a container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is set at compile time and cannot be changed. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

2015-09-28 13:42 by trijezdci -
Changed lines 181-182 from:

A constant is an immutable value determined at compile time. A constant may be defined as an alias of another constant, but not as an alias of a module, a variable, a type or procedure.

to:

A constant is an immutable value determined at compile time. Its value is specified by a constant expression in its definition. A constant may not be defined as an alias of a module, a variable, a type or a procedure.

Changed line 185 from:
 CONST zero = 0; maxInt = TMAX(INTEGER); buffSize = MAX(fooLen, barLen, bazLen);
to:
 CONST zero = 0; maxInt = TMAX(INTEGER); buffSize = 100 * TSIZE(INTEGER) + 42; 
Changed lines 192-197 from:

to do

to:

A variable is an container for a value determined at runtime. A variable is always associated with a type and it can only hold values of its type. Its type is set at compile time and cannot be changed. The value of a variable is undetermined when it is allocated. However, variables of pointer types are automatically intialised to hold the invalid pointer value NIL.

Examples:

 VAR ch : CHAR; n, m : CARDINAL; i, j : INTEGER; x, y, z : REAL; 
2015-09-28 12:01 by trijezdci -
Changed lines 181-187 from:

to do

to:

A constant is an immutable value determined at compile time. A constant may be defined as an alias of another constant, but not as an alias of a module, a variable, a type or procedure.

Examples:

 CONST zero = 0; maxInt = TMAX(INTEGER); buffSize = MAX(fooLen, barLen, bazLen);
2015-09-28 11:48 by trijezdci -
Changed line 1091 from:

Operators are special symbols or reserved words that represent an operation within an expression. An operator may be unary or binary. Unary operators are prefix or postfix, binary operators are always infix. An operator may be either left-associative or non-associative and it has a precedence level between one and six, where six represents the highest level. Arity, associativity and precedence determine the order of evaluations in expressions that consist of multiple sub-expressions and may contain different operators.

to:

Operators are special symbols or reserved words that represent an operation within an expression. An operator may be unary or binary. Unary operators are prefix or postfix, binary operators are always infix. An operator may be either left-associative or non-associative and it has a precedence level between one and six, where six represents the highest level. Arity, associativity and precedence determine the order of evaluation in expressions that consist of multiple sub-expressions and may contain different operators.

2015-09-28 11:43 by trijezdci -
Changed lines 1010-1012 from:

Grammar rule expression represents evaluation level one. Its operands are simple expressions. Its operators are the relational operators and the identity operator. Level one has the lowest precedence.

to:

Expressions are evaluated at precedence level one. Its sub-expressions are simple expressions. Its operators are the relational operators and the identity operator. Level one has the lowest precedence.

Changed lines 1018-1019 from:

Grammar rule simple expression represents evaluation level two. Its operands are terms. Its operators are the plus and minus operators and the OR operator.

to:

Simple expressions are evaluated at precedence level one. Its sub-expressions are terms. Its operators are the plus and minus operators and the OR operator.

Changed lines 1025-1026 from:

Grammar rule term represents evaluation level three. Its operands are simple terms. Its operators are the asterisk, solidus, DIV, MOD, AND operators and the set difference operator.

to:

Terms are evaluated at precedence level three. Its sub-expressions are simple terms. Its operators are the asterisk, solidus, DIV, MOD, AND operators and the set difference operator.

Changed lines 1032-1033 from:

Grammar rule simple term represents evaluation level four. Its operand is a factor and its operator is the NOT operator.

to:

Simple terms are evaluated at precedence level four. Its sub-expressions are factors and its operator is the NOT operator.

Changed lines 1039-1040 from:

Grammar rule factor represents evaluation level five. Its operand is a simple factor and its operator is the type conversion operator.

to:

Factors are evaluated at precedence level five. Its sub-expressions are simple factors and its operator is the type conversion operator.

Changed line 1046 from:

Grammar rule simple factor represents evaluation level six. It consists of literals, structured values, expressions in parentheses, designators and function calls. Its pseudo-operators are the parentheses of parenthesised expressions and the selectors of designators. Level six has the highest precedence.

to:

Simple factors are evaluated at precedence level six. Its sub-expressions are literals, structured values, expressions in parentheses, designators and function calls. Its pseudo-operators are the parentheses of parenthesised expressions and the selectors of designators. Level six has the highest precedence.

2015-09-28 11:38 by trijezdci -
Added lines 1008-1009:
Added lines 1016-1017:
Added lines 1023-1024:
Added lines 1030-1031:
Added lines 1037-1038:
Added lines 1043-1044:
2015-09-28 11:24 by trijezdci -
Changed lines 1008-1009 from:

to do

to:

Grammar rule expression represents evaluation level one. Its operands are simple expressions. Its operators are the relational operators and the identity operator. Level one has the lowest precedence.

Changed lines 1014-1015 from:

to do

to:

Grammar rule simple expression represents evaluation level two. Its operands are terms. Its operators are the plus and minus operators and the OR operator.

Changed lines 1019-1020 from:

to do

to:

Grammar rule term represents evaluation level three. Its operands are simple terms. Its operators are the asterisk, solidus, DIV, MOD, AND operators and the set difference operator.

Changed lines 1024-1025 from:

to do

to:

Grammar rule simple term represents evaluation level four. Its operand is a factor and its operator is the NOT operator.

Changed lines 1029-1030 from:

to do

to:

Grammar rule factor represents evaluation level five. Its operand is a simple factor and its operator is the type conversion operator.

Changed line 1034 from:

to do

to:

Grammar rule simple factor represents evaluation level six. It consists of literals, structured values, expressions in parentheses, designators and function calls. Its pseudo-operators are the parentheses of parenthesised expressions and the selectors of designators. Level six has the highest precedence.

2015-09-28 10:59 by trijezdci -
Changed line 1053 from:
  • pointer target selecto
to:
  • pointer target selector
2015-09-28 10:58 by trijezdci -
Changed lines 1048-1049 from:

A selector is a syntactical entity to select one or more components from a value. There are four kinds.

to:

A selector is a suffix to select one or more components from a value. There are four kinds.

2015-09-28 10:54 by trijezdci -
Added lines 1008-1009:

to do

Added lines 1013-1014:

to do

Added lines 1018-1019:

to do

Added lines 1023-1024:

to do

Added lines 1028-1029:

to do

Changed lines 1033-1072 from:
to:

to do

Operands

An operand may be a literal, a designator or a sub-expression. Whether any given operand may legally occur at a given position within an expression is determined by expression compatibility. Expression compatibility of operands is dependent on the operator of an expression or sub-expression as each operator defines what operand types it can accept.

Designators

A designator consists of an identifier that refers to a constant, a variable or a function call, followed by an optional designator tail that consists of one or more selectors. The identifier component of a designator may be a qualified identifier.

Selectors

A selector is a syntactical entity to select one or more components from a value. There are four kinds.

  • subscript selector
  • array slice selector
  • record field selector
  • pointer target selecto

The Subscript Selector

to do

The Array Slice Selector

to do

The Array Slice Selector

to do

The Pointer Target Selector

to do

2015-09-28 09:13 by trijezdci -
Changed lines 993-1023 from:

to do

to:

An expression is a computational formula that evaluates to a value. An expression consists of operands, operators and optional punctuation.

Runtime and Compile Time Expressions

Expressions are classified according to their time of evaluation. An expression that may only be evaluated at runtime is called a runtime expression. An expression that is evaluated at compile time is called a compile time expression or constant expression. Constant expressions consist only of operands whose values are known at compile time and only invoke built-in functions or macros that may be evaluated at compile time.

Evaluation Order

The evaluation order of expressions is determined by operator precedence and punctuation. There are five levels of operator precedence. However, sub-expressions enclosed in parentheses, designators and function calls always take precedence over the evaluation order defined by operator precedence. This constitutes an implicit sixth level of expression evaluation.

Evaluation Level 1

Evaluation Level 2

Evaluation Level 3

Evaluation Level 4

Evaluation Level 5

Evaluation Level 6
2015-09-28 07:28 by trijezdci -
Changed lines 862-865 from:

The FOR statement is used to iterate over an iterable entity and execute a statement or statement sequence during each iteration cycle. It consists of a loop header and a loop body. The loop header consists of one or two loop variants, an optional iteration order, and the iterable entity. The loop body consists of a statement or statement sequence.

The Iterable Entity
to:

The FOR statement is used to iterate over an iterable entity and execute a statement or statement sequence during each iteration cycle. It consists of a loop header and a loop body. The loop header consists of one or two loop variants, an optional iteration order, and the iterable expression. The loop body consists of a statement or statement sequence.

The Iterable Expression
Changed line 868 from:

The iterable entity — or iterable in short – is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. An ordinal type or subrange iterable is always immutable. A collection iterable may be either mutable or immutable.

to:

The iterable expression — or iterable in short – is denoted by a designator if an instance of a collection type or by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type. An ordinal type or subrange iterable is always immutable. A collection iterable may be either mutable or immutable.

2015-09-28 06:10 by trijezdci -
Added line 24:
Deleted line 25:
Deleted line 191:
  • subrange types
Added line 194:
  • subrange types
2015-09-28 06:09 by trijezdci -
Changed lines 251-252 from:

An immutable type is an immutable subtype of a mutable type. The type it is a subtype of is called its supertype. The supertype may be any dynamically allocatable ADT provided that it is not an immutable subtype itself. An immutable type obtains its properties from its supertype, except for its identifier. It is defined using the CONST type constructor.

to:

An immutable type is an immutable equivalence type of a mutable type. The type it is an equivalence type of is called its base type. The base type may be any dynamically allocatable ADT provided that it is not an immutable equivalence type itself. An immutable type obtains its properties from its base type, except for its identifier. It is defined using the CONST type constructor.

Changed line 258 from:

An immutable type is compatible with its supertype. Any value of an immutable type is also a legal value of its supertype and vice versa. However, instances of an immutable type are immutable, they may not be L-values except for initialisation in a NEW statement and they may not be passed to a formal VAR parameter.

to:

An immutable type is compatible with its base type. Any value of an immutable type is also a legal value of its base type and vice versa. However, instances of an immutable type are immutable, they may not be L-values except for initialisation in a NEW statement and they may not be passed to a formal VAR parameter.

2015-09-28 06:01 by trijezdci -
Changed line 232 from:

An ALIAS type is a nominal sub-type of another type. The type it is a sub-type of is called its base type. The base type may be any type. An ALIAS type obtains its properties from its base type, except for its identifier. It is defined using the ALIAS OF type constructor.

to:

An ALIAS type is a nominal equivalence type of another type. The type it is an equivalence type of is called its base type. The base type may be any type. An ALIAS type obtains its properties from its base type, except for its identifier. It is defined using the ALIAS OF type constructor.

2015-09-28 05:55 by trijezdci -
Changed line 258 from:

An immutable type is compatible with its supertype, except where such compatibility would violate the subtype's immutability. Any value of an immutable type is also a legal value of its supertype and vice versa. However, instances of an immutable type are immutable, they may not be L-values except for initialisation in a NEW statement and they may not be passed to a formal VAR parameter.

to:

An immutable type is compatible with its supertype. Any value of an immutable type is also a legal value of its supertype and vice versa. However, instances of an immutable type are immutable, they may not be L-values except for initialisation in a NEW statement and they may not be passed to a formal VAR parameter.

2015-09-28 05:29 by trijezdci -
Changed lines 207-208 from:

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

to:

A derived type is a nominal derivative of another type. The type it is derived from is called its base type. The base type may be any type. A derived type obtains its properties from its base type, except for its identifier. It is defined using the = symbol followed by the base type in the type constructor.

Changed lines 232-233 from:

An ALIAS type is a derived type specifically defined to be compatible with its base type even though their identifiers are different. An ALIAS type is defined using the ALIAS OF type constructor.

to:

An ALIAS type is a nominal sub-type of another type. The type it is a sub-type of is called its base type. The base type may be any type. An ALIAS type obtains its properties from its base type, except for its identifier. It is defined using the ALIAS OF type constructor.

Changed lines 247-251 from:

Subrange Types

A subrange type is a type defined as a subset of a scalar or ordinal type. A subrange type is upwards compatible with its base type, but the base type is not downwards compatible with any subrange types derived from it. A subrange type inherits all its properties from its base type, except for its lower and upper bound. A subrange type's lower and upper bound must be specified in its type definition. Both lower and upper bound must be compatible with the base type and they must be legal values of the base type.

to:

Immutable Types

An immutable type is an immutable subtype of a mutable type. The type it is a subtype of is called its supertype. The supertype may be any dynamically allocatable ADT provided that it is not an immutable subtype itself. An immutable type obtains its properties from its supertype, except for its identifier. It is defined using the CONST type constructor.

Changed lines 254-256 from:

Examples:

 TYPE Radian = [0.0 .. tau] OF REAL;
 TYPE Natural = [1 .. TMAX(CARDINAL)] OF CARDINAL;
to:

Example:

 TYPE ImmutableFooArray = CONST FooArray;
Changed lines 258-259 from:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol. An open bound of a subrange type is not a legal value of the type.

to:

An immutable type is compatible with its supertype, except where such compatibility would violate the subtype's immutability. Any value of an immutable type is also a legal value of its supertype and vice versa. However, instances of an immutable type are immutable, they may not be L-values except for initialisation in a NEW statement and they may not be passed to a formal VAR parameter.

Changed lines 261-263 from:

Examples:

 TYPE PosReal = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE NegReal = [TMIN(REAL) .. <0.0] OF REAL;
to:

Example:

 VAR array : FooArray; immArray : ImmutableFooArray;
 NEW array; (* initialisation not required *)
 NEW immArray := { foo, bar, baz }; (* initialisation required *)
 COPY array := immArray; (* copying from immutable to mutable *)
 COPY immArray := array; (* compile time error: attempt to modify immutable instance *)
Changed lines 269-273 from:

Immutable Types

A CONST type is a type defined to be an immutable alias type of a mutable ADT. A CONST type is defined using the CONST type constructor.

to:

Subrange Types

A subrange type is a subtype of a scalar or ordinal type. The type it is a subtype of is called its supertype. The supertype may be any scalar or ordinal type. A subrange type obtains its properties from its supertype, except for its identifier, and its lower and upper bounds. Both lower and upper bound must be specified in its type definition and they must be legal values of the supertype. A subrange type is defined using a range constructor.

Changed lines 276-277 from:

Example:

 TYPE ImmutableFooArray = CONST FooArray;
to:

Examples:

 TYPE Radian = [0.0 .. tau] OF REAL;
 TYPE Natural = [1 .. TMAX(CARDINAL)] OF CARDINAL;
Changed lines 281-282 from:

A CONST type is compatible with its base type, except where such compatibility would violate the type's immutability.

to:

A subrange type is upwards compatible with its supertype, but the supertype is not downwards compatible with all of its subrange types. This restriction exists because any value of a subrange type is always a legal value of its supertype, but a value of a supertype is not necessarily a legal value of its subrange type.

Changed lines 284-289 from:

Example:

 VAR array : FooArray; immArray : ImmutableFooArray;
 NEW array; (* initialisation not required *)
 NEW immArray := { foo, bar, baz }; (* initialisation required *)
 COPY array := immArray; (* copying from immutable to mutable *)
 COPY immArray := array; (* compile time error: attempt to modify immutable instance *)
to:

Examples:

 VAR natural : Natural; cardinal : CARDINAL;
 natural := cardinal; (* compile time error *)
 cardinal := natural; (* OK *)
Changed lines 290-298 from:
to:

The subrange type definition of a scalar type that represents real numbers may specify open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol. An open bound of a subrange type is not a legal value of the subrange type.

Examples:

 TYPE PosReal = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE NegReal = [TMIN(REAL) .. <0.0] OF REAL;
Changed line 2197 from:
to:
2015-09-28 03:12 by trijezdci -
Deleted line 190:
  • opaque types
Changed lines 202-203 from:
to:
  • opaque types
Changed line 207 from:

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

to:

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

2015-09-27 16:59 by trijezdci -
Changed lines 149-150 from:

Semantics

to:

Semantics

Changed lines 152-153 from:
Compilation Units
to:

Compilation Units

Changed lines 159-160 from:
Import of Identifiers
to:

Import of Identifiers

Changed lines 168-169 from:
Definition Modules
to:

Definition Modules

Changed lines 174-175 from:
Definitions
to:

Definitions

Changed lines 179-180 from:
Constant Definitions
to:

Constant Definitions

Changed lines 184-185 from:
Variable Declarations
to:

Variable Declarations

Changed lines 189-190 from:
Type Definitions
to:

Type Definitions

Changed lines 205-206 from:
Derived Types
to:

Derived Types

Changed lines 230-231 from:
ALIAS Types
to:

ALIAS Types

Changed lines 248-249 from:
Subrange Types
to:

Subrange Types

Changed lines 267-268 from:
Immutable Types
to:

Immutable Types

Changed lines 289-290 from:
Enumeration Types
to:

Enumeration Types

Changed lines 308-309 from:
Enumeration Type Extension
to:

Enumeration Type Extension

Changed lines 321-322 from:
Set Types
to:

Set Types

Changed lines 343-344 from:
Array Types
to:

Array Types

Changed lines 364-365 from:
Flexible Array Types
to:

Flexible Array Types

Changed lines 394-395 from:
Character Arrays
to:

Character Arrays

Changed lines 407-408 from:
Record Types
to:

Record Types

Changed lines 428-429 from:
Record Type Extension
to:

Record Type Extension

Changed lines 441-442 from:
Pointer Types
to:

Pointer Types

Changed lines 479-480 from:
Coroutine Types
to:

Coroutine Types

Changed lines 491-492 from:
Procedure Types
to:

Procedure Types

Changed lines 505-506 from:
Opaque Types
to:

Opaque Types

Changed lines 513-514 from:
Opaque Pointer Types
to:

Opaque Pointer Types

Changed lines 550-551 from:
Opaque Record Types
to:

Opaque Record Types

Changed lines 593-594 from:
Semi-Opaque Record Types
to:

Semi-Opaque Record Types

Changed lines 619-620 from:
Implementation and Program Modules
to:

Implementation and Program Modules

Changed lines 624-625 from:
Statements
to:

Statements

Changed lines 643-644 from:
Memory Management Statements
to:

Memory Management Statements

Changed lines 654-655 from:
The NEW Statement
to:

The NEW Statement

Changed lines 665-666 from:
The RETAIN Statement
to:

The RETAIN Statement

Changed lines 675-676 from:
The RELEASE Statement
to:

The RELEASE Statement

Changed lines 684-685 from:
Destructive Update Statements
to:

Destructive Update Statements

Changed lines 694-695 from:
The Assignment Statement
to:

The Assignment Statement

Changed lines 704-705 from:
The Increment Statement
to:

The Increment Statement

Changed lines 714-715 from:
The Decrement Statement
to:

The Decrement Statement

Changed lines 724-725 from:
The COPY Statement
to:

The COPY Statement

Changed lines 729-730 from:
The Procedure Call Statement
to:

The Procedure Call Statement

Changed lines 739-740 from:
The RETURN Statement
to:

The RETURN Statement

Changed lines 752-753 from:
The YIELD Statement
to:

The YIELD Statement

Changed lines 768-769 from:
The IF Statement
to:

The IF Statement

Changed lines 786-787 from:
The CASE Statement
to:

The CASE Statement

Changed lines 806-807 from:
The WHILE Statement
to:

The WHILE Statement

Changed lines 818-819 from:
The REPEAT Statement
to:

The REPEAT Statement

Changed lines 830-831 from:
The LOOP Statement
to:

The LOOP Statement

Changed lines 847-848 from:
The FOR Statement
to:

The FOR Statement

Changed lines 853-854 from:
The Iterable Entity
to:
The Iterable Entity
Changed lines 859-860 from:
The Loop Variant Section
to:
The Loop Variant Section
Changed lines 867-868 from:
The Iteration Order
to:
The Iteration Order
Changed lines 873-874 from:
Iterating Over Ordinal Types
to:
Iterating Over Ordinal Types
Changed lines 881-882 from:
Iterating Over The CHAR Type
to:
Iterating Over The CHAR Type
Changed lines 891-892 from:
Iterating Over An Enumeration Type
to:
Iterating Over An Enumeration Type
Changed lines 902-903 from:
Iterating Over A Whole Number Type
to:
Iterating Over A Whole Number Type
Changed lines 912-913 from:
Iterating Over Collections
to:
Iterating Over Collections
Changed lines 921-922 from:
Iterating Over A List
to:
Iterating Over A List
Changed lines 931-932 from:
Iterating Over An Array
to:
Iterating Over An Array
Changed lines 941-942 from:
Iterating Over A Set
to:
Iterating Over A Set
Changed lines 951-952 from:
Iterating Over A Dictionary
to:
Iterating Over A Dictionary
Changed lines 962-963 from:
The EXIT Statement
to:

The EXIT Statement

Changed lines 978-979 from:
Expressions
to:

Expressions

Changed lines 985-986 from:
Operators
to:

Operators

Changed lines 1018-1019 from:
The Pointer Dereferencing Operator
to:
The Pointer Dereferencing Operator
Changed lines 1031-1032 from:
The Type Conversion Operator
to:
The Type Conversion Operator
Changed lines 1044-1045 from:
The NOT Operator
to:
The NOT Operator
Changed lines 1056-1057 from:
The Asterisk Operator
to:
The Asterisk Operator
Changed lines 1069-1070 from:
The Solidus Operator
to:
The Solidus Operator
Changed lines 1082-1083 from:
The DIV Operator
to:
The DIV Operator
Changed lines 1094-1095 from:
The MOD Operator
to:
The MOD Operator
Changed lines 1106-1107 from:
The AND Operator
to:
The AND Operator
Changed lines 1118-1119 from:
The Set Difference Operator
to:
The Set Difference Operator
Changed lines 1130-1131 from:
The Plus Operator
to:
The Plus Operator
Changed lines 1161-1162 from:
The Minus Operator
to:
The Minus Operator
Changed lines 1191-1192 from:
The Concatenation Operator
to:
The Concatenation Operator
Changed lines 1203-1204 from:
The OR Operator
to:
The OR Operator
Changed lines 1215-1216 from:
The Equality Operator
to:
The Equality Operator
Changed lines 1227-1228 from:
The Inequality Operator
to:
The Inequality Operator
Changed lines 1239-1240 from:
The > Operator
to:
The > Operator
Changed lines 1252-1253 from:
The >= Operator
to:
The >= Operator
Changed lines 1265-1266 from:
The < Operator
to:
The < Operator
Changed lines 1278-1279 from:
The <= Operator
to:
The <= Operator
Changed lines 1291-1292 from:
The IN Operator
to:
The IN Operator
Changed lines 1303-1304 from:
The Identity Operator
to:
The Identity Operator
Changed lines 1315-1316 from:
Structured Values
to:

Structured Values

Changed lines 1331-1332 from:
Predefined Identifiers
to:

Predefined Identifiers

Changed line 1386 from:
Summary Of Built-in Compile-Time Macros
to:
Summary Of Built-in Compile-Time Macros
Changed lines 1395-1396 from:
Constant NIL
to:
Constant NIL
Changed lines 1407-1408 from:
Constant EMPTY
to:
Constant EMPTY
Changed lines 1417-1418 from:
Constants TRUE and FALSE
to:
Constants TRUE and FALSE
Changed lines 1431-1432 from:
Predefined Types
to:

Predefined Types

Changed lines 1434-1435 from:
Type BOOLEAN
to:
Type BOOLEAN
Changed lines 1448-1449 from:
Type CHAR
to:
Type CHAR
Changed lines 1462-1463 from:
Type UNICHAR
to:
Type UNICHAR
Changed lines 1468-1469 from:
Type OCTET
to:
Type OCTET
Changed lines 1480-1481 from:
Type CARDINAL
to:
Type CARDINAL
Changed lines 1492-1493 from:
Type LONGCARD
to:
Type LONGCARD
Changed lines 1504-1505 from:
Type INTEGER
to:
Type INTEGER
Changed lines 1516-1517 from:
Type LONGINT
to:
Type LONGINT
Changed lines 1528-1529 from:
Type REAL
to:
Type REAL
Changed lines 1534-1535 from:
Type LONGREAL
to:
Type LONGREAL
Changed lines 1541-1542 from:
Predefined Procedures
to:

Predefined Procedures

Changed lines 1938-1939 from:
Blueprints
to:

Blueprints

Changed lines 1944-1945 from:
Type Classification
to:
Type Classification
Changed lines 1950-1951 from:
Literal Compatibility
to:
Literal Compatibility
Changed lines 1956-1957 from:
Constraints
to:
Constraints
Changed lines 1962-1963 from:
Requirements
to:
Requirements
Changed lines 1969-1970 from:
Primitives
to:

Primitives

Changed lines 2166-2167 from:
Pragmas
to:

Pragmas

Changed line 2179 from:

Older Wiki content, parts of which may be reused:

to:

Older Wiki content, parts of which may be reused

2015-09-27 16:44 by trijezdci -
Changed line 148 from:

(To do: enter from PDF version and update)

to:

(To do: transfer missing content from PDF version and update)

2015-09-27 16:43 by trijezdci -
Deleted lines 147-155:

(To do: move and merge content)

Scope
Types
Predefined Identifiers

Changed lines 2175-2186 from:
  • Language Report (PDF) (needs update)
to:
  • Language Report (PDF) (needs update)

Older Wiki content, parts of which may be reused:

Scope
Types
Predefined Identifiers
2015-09-27 16:38 by trijezdci -
Added lines 95-96:
2015-09-27 16:36 by trijezdci -
Changed lines 1457-1458 from:

Type CHAR is an ordinal type for 7-bit character values. It is defined as:

to:

Type CHAR is an ordinal type for 7-bit character values and its value range is 0u0 .. 0u7F. It is defined as:

Changed lines 1471-1473 from:

Type UNICHAR is a container type for Unicode character values. Its size is always 32-bit. Type CHAR is upwards compatible with UNICHAR but the reverse is not the case. This restriction exists because every legal value of type CHAR is also a legal value of type UNICHAR but not every value of type UNICHAR is also a legal value of type CHAR.

to:

Type UNICHAR is a container type for Unicode character values. Its size is always 32-bit but its value range is 0u0 .. 0u10FFFF. Type CHAR is upwards compatible with UNICHAR but the reverse is not the case. This restriction exists because every legal value of type CHAR is also a legal value of type UNICHAR but not every value of type UNICHAR is also a legal value of type CHAR.

Changed lines 1537-1539 from:

TO DO

to:

Type REAL is a real number type with implementation defined precision and range.

Changed lines 1543-1544 from:

TO DO

to:

Type LONGREAL is a real number type with a precision and range equal to or higher than that of type REAL.

No predefined type may be an ALIAS type of another, even if the types share the same implementation.

2015-09-27 16:26 by trijezdci -
Changed line 1326 from:

A structured value is a compound value that consist of a comma separated list of value components enclosed in braces. A component value may be a value repetition clause, a value range, a literal, a structured value or an identifier denoting a value or structured value. A value repetition clause is a constant expression followed by BY followed by a repetition factor which shall be a constant expression of a whole number type. A value range is an ordinal constant expression representing the start value followed by .. followed by another ordinal constant expression representing the end value, both ordinal values shall be of the same type.

to:

A structured value is a compound value that consists of a comma separated list of value components enclosed in braces. A component value may be a value repetition clause, a value range, a literal, a structured value or an identifier denoting a value or structured value. A value repetition clause is a constant expression followed by BY followed by a repetition factor which shall be a constant expression of a whole number type. A value range is an ordinal constant expression representing the start value followed by .. followed by another ordinal constant expression representing the end value, both ordinal values shall be of the same type.

2015-09-27 16:26 by trijezdci -
Changed lines 1326-1333 from:

to do

to:

A structured value is a compound value that consist of a comma separated list of value components enclosed in braces. A component value may be a value repetition clause, a value range, a literal, a structured value or an identifier denoting a value or structured value. A value repetition clause is a constant expression followed by BY followed by a repetition factor which shall be a constant expression of a whole number type. A value range is an ordinal constant expression representing the start value followed by .. followed by another ordinal constant expression representing the end value, both ordinal values shall be of the same type.

Examples:

 { 0 BY 100 }, { "a" .. "z" }, { 1 .. 31 }
 { 1970, Month.Jan, 1, 0, 0, 0.0, TZ.UTC }
 { "a", "bcd", 123, 456.78, { 9, 10 }, { foo, bar, baz } }
2015-09-27 15:53 by trijezdci -
Added lines 48-49:
Deleted lines 55-56:
Changed lines 745-751 from:

The IF Statement

EBNF | Syntax Diagram

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. At most one block in the statement is executed. IF-statements must always be terminated with an END.

to:

The RETURN Statement

The RETURN statement is used within a procedure body to return control to its caller and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance shall cause a compile time error.

Changed lines 752-758 from:
 IF i > 0 THEN
   WRITE("Positive")
 ELSIF i = 0 THEN
   WRITE("Zero")
 ELSE
   WRITE("Negative")
 END;
to:
 PROCEDURE successor ( n : CARDINAL ) : CARDINAL;
 BEGIN
   RETURN n + 1
 END successor;
Changed lines 758-764 from:

The CASE Statement

EBNF | Syntax Diagram

A CASE statement is a flow-control statement that passes control to one of a number of labeled statements or statement sequences depending on the value of an ordinal expression. Control is passed to the first statement following the case label that matches the ordinal expression. If no label matches, control is passed to the ELSE block.

to:

The YIELD Statement

The YIELD statement is used within a coroutine procedure body to suspend the coroutine and pass control to its caller. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When yielding from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance shall cause a compile time error.

Changed lines 765-771 from:
 CASE colour OF
 | colour.red   : WRITE("Red")
 | colour.green : WRITE("Green")
 | colour.blue  : WRITE("Blue")
 ELSE
   UNSAFE.HALT(1) (* fatal error -- abort *)
 END;
to:
 PROCEDURE [COROUTINE] iterator ( CONST array : ARRAY OF INTEGER ) : INTEGER;
 BEGIN
   FOR value IN array DO
     YIELD value
   END;
   RETURN -1
 END iterator;
Changed lines 774-782 from:

A case label shall be listed at most once. If a case is encountered at runtime that is not listed in the case label list and if there is no ELSE block, no case label statements shall be executed and no error shall result.

The WHILE Statement

EBNF | Syntax Diagram

A WHILE statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time before the DO block is executed. The DO block is repeated as long as the expression evaluates to TRUE.

to:

The IF Statement

EBNF | Syntax Diagram

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. At most one block in the statement is executed. IF-statements must always be terminated with an END.

Changed lines 783-789 from:
 WHILE NOT EOF(file) DO READ(file, ch) END;
to:
 IF i > 0 THEN
   WRITE("Positive")
 ELSIF i = 0 THEN
   WRITE("Zero")
 ELSE
   WRITE("Negative")
 END;
Changed lines 792-798 from:

The REPEAT Statement

EBNF | Syntax Diagram

A REPEAT statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time after the REPEAT block has executed. the expression evaluates to TRUE the REPEAT block is executed, otherwise not.

to:

The CASE Statement

EBNF | Syntax Diagram

A CASE statement is a flow-control statement that passes control to one of a number of labeled statements or statement sequences depending on the value of an ordinal expression. Control is passed to the first statement following the case label that matches the ordinal expression. If no label matches, control is passed to the ELSE block.

Changed lines 801-807 from:
 REPEAT READ(file, ch) UNTIL ch = terminator END;
to:
 CASE colour OF
 | colour.red   : WRITE("Red")
 | colour.green : WRITE("Green")
 | colour.blue  : WRITE("Blue")
 ELSE
   UNSAFE.HALT(1) (* fatal error -- abort *)
 END;
Changed lines 810-816 from:

The LOOP Statement

EBNF | Syntax Diagram

A LOOP statement is used to repeat a statement or statement sequence indefinitely unless explicitly terminated by an EXIT statement.

to:

A case label shall be listed at most once. If a case is encountered at runtime that is not listed in the case label list and if there is no ELSE block, no case label statements shall be executed and no error shall result.

The WHILE Statement

EBNF | Syntax Diagram

A WHILE statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time before the DO block is executed. The DO block is repeated as long as the expression evaluates to TRUE.

Changed lines 821-826 from:
 LOOP
   READ(file, ch);
   IF ch IN TerminatorSet THEN
     EXIT
   END (* IF *)
 END; (* LOOP *)
to:
 WHILE NOT EOF(file) DO READ(file, ch) END;
Added lines 824-852:

The REPEAT Statement

EBNF | Syntax Diagram

A REPEAT statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time after the REPEAT block has executed. the expression evaluates to TRUE the REPEAT block is executed, otherwise not.

Example:

 REPEAT READ(file, ch) UNTIL ch = terminator END;

The LOOP Statement

EBNF | Syntax Diagram

A LOOP statement is used to repeat a statement or statement sequence indefinitely unless explicitly terminated by an EXIT statement.

Example:

 LOOP
   READ(file, ch);
   IF ch IN TerminatorSet THEN
     EXIT
   END (* IF *)
 END; (* LOOP *)
Deleted lines 965-993:

The RETURN Statement

The RETURN statement is used within a procedure body to return control to its caller and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance shall cause a compile time error.

Example:

 PROCEDURE successor ( n : CARDINAL ) : CARDINAL;
 BEGIN
   RETURN n + 1
 END successor;

The YIELD Statement

The YIELD statement is used within a coroutine procedure body to suspend the coroutine and pass control to its caller. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When yielding from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance shall cause a compile time error.

Example:

 PROCEDURE [COROUTINE] iterator ( CONST array : ARRAY OF INTEGER ) : INTEGER;
 BEGIN
   FOR value IN array DO
     YIELD value
   END;
   RETURN -1
 END iterator;
2015-09-27 13:03 by trijezdci -
Changed line 559 from:

An opaque record type is a record type with export restricted fields. An export restricted field is a field that is directly accessible only within the library module in which the type is defined and within any extension library thereof. It is not directly accessible within any other scope. Such a field is declared by prefixing the field declaration with the * symbol.

to:

An opaque record type is a record type whose identifier is available to client modules that import it but its fields are not. Such a record type is defined with exported restricted fields. An export restricted field is a field that is directly accessible only within the library module in which the type is defined and within any extension library thereof. It is not directly accessible within any other scope. Such a field is declared by prefixing the field declaration with the * symbol.

2015-09-27 12:58 by trijezdci -
Changed lines 559-560 from:

An opaque record type is a record type with export restricted fields, used for the construction of ADTs. An export restricted field is a field that is directly accessible only within the library module in which the type is defined and within any extension library thereof. It is not directly accessible within any other scope. An export restricted field is declared by prefixing its declaration with the * symbol.

to:

An opaque record type is a record type with export restricted fields. An export restricted field is a field that is directly accessible only within the library module in which the type is defined and within any extension library thereof. It is not directly accessible within any other scope. Such a field is declared by prefixing the field declaration with the * symbol.

Changed lines 572-573 from:

Since all record fields are lexically present within the definition part, the allocation size of an opaque record type can be calculated at compile time even when no source code is available for the corresponding implementation part. Instances of opaque record based ADTs are therefore statically allocatable.

to:

Since all record fields are lexically present within the definition part, the allocation size of an opaque record type can be determined at compile time even when no source code is available for the corresponding implementation part. Instances of opaque record types are therefore statically allocatable.

Changed line 580 from:

Since export restricted fields are not directly accessible outside their defining library, they may only be operated on by clients through facilities provided in the library's public interface.

to:

Any attempt to access a restricted field within a scope where it is not accessible shall cause a compile time error.

2015-09-27 10:51 by trijezdci -
Changed line 600 from:
Semit-Opaque Record Types
to:
Semi-Opaque Record Types
2015-09-27 10:50 by trijezdci -
Changed lines 600-602 from:
Semi-Opaque Record Types

A record type may contain both public and export restricted fields. Such a record is called semi-opaque.

to:
Semit-Opaque Record Types

A record type may contain both public and export restricted fields. Such a record type is called semi-opaque.

2015-09-27 10:49 by trijezdci -
Added lines 599-600:
Semi-Opaque Record Types
2015-09-27 10:47 by trijezdci -
Changed line 600 from:

A record type may contain both public and export restricted fields. Such a record is called semi-opaque or partially opaque.

to:

A record type may contain both public and export restricted fields. Such a record is called semi-opaque.

2015-09-27 10:45 by trijezdci -
Changed line 610 from:

When an instance of a semi-opaque record type is assigned a structured value, the structured value may only contain values for public fields.

to:

When a structured value is assigned to an instance of a semi-opaque record type, it may only contain values for public fields.

2015-09-27 10:43 by trijezdci -
Changed lines 619-627 from:

Semi-opaque record based AD Ts? should be designed such that restricted fields of instances are auto-initialised.

Example:

 TYPE SemiOpaque = RECORD
 * i : INTEGER = 0; (* auto-initialising restricted field *)
   j, k : INTEGER (* public fields *)
 END;
to:

It is safe practise to declare the restricted fields of semi-opaque record types with an initialisation expression.

2015-09-27 10:39 by trijezdci -
Changed line 587 from:
 len := Pascal String?.Length(str); (* proper use: access via public interface *)
to:
 len := PascalString.Length(str); (* proper use: access via public interface *)
Deleted line 593:
 DEFINITION MODULE PascalString;
Changed line 604 from:
 TYPE Semi Opaque? = RECORD
to:
 TYPE SemiOpaque = RECORD
Changed line 614 from:
 VAR triplet : Semi Opaque?;
to:
 VAR triplet : SemiOpaque;
Changed lines 623-624 from:
 TYPE Semi Opaque? = RECORD
 * i : INTEGER = 0; (* restricted field *)
to:
 TYPE SemiOpaque = RECORD
 * i : INTEGER = 0; (* auto-initialising restricted field *)
2015-09-27 10:35 by trijezdci -
Changed lines 565-566 from:
   * length : OCTET = 0; (* export restricted field *)
   * data : ARRAY 255 OF OCTET (* export restricted field *)
to:
 * length : OCTET; (* export restricted field *)
 * data : OctetArray255 (* export restricted field *)
Changed lines 580-581 from:

Fields that are not export restricted are directly accessible in any scope into which an opaque record type has been imported, but export restricted fields are only accessible within the implementation part and extension modules of the library that defines the opaque record type. Export restricted fields may only be operated on by clients through facilities provided in the library's public interface.

to:

Since export restricted fields are not directly accessible outside their defining library, they may only be operated on by clients through facilities provided in the library's public interface.

Changed lines 585-588 from:
 VAR str : PascalString;
 str.length := 5; (* compile time error: access of a restricted field *)
 Terminal.WriteOctets(str.data); (* compile time error: access of a restricted field *)
 PascalString.copy(str, "foobar"); (* proper use: operation through public interface *)
to:
 VAR str : PascalString; len : OCTET;
 len := str.length; (* compile time error: access of a restricted field *)
 len := Pascal String?.Length(str); (* proper use: access via public interface *)

Export restricted fields may be automatically initialised for every instance of the type by suffixing the field declaration with an initialisation expression. The initialisation expression shall be a compile time expression of the type of the field.

Example:

 DEFINITION MODULE PascalString;
 TYPE PascalString = RECORD
 * length : OCTET = 0; (* auto-initialisation to zero *)
 * data : OctetArray255
 END;

A record type may contain both public and export restricted fields. Such a record is called semi-opaque or partially opaque.

Example:

 TYPE Semi Opaque? = RECORD
 * i : INTEGER; (* restricted field *)
   j, k : INTEGER (* public fields *)
 END;

When an instance of a semi-opaque record type is assigned a structured value, the structured value may only contain values for public fields.

Example:

 VAR triplet : Semi Opaque?;
 triplet := { 0, 0, 0 }; (* compile time error: access of a restricted field *)
 triplet := { 0, 0 }; (* proper use: only public fields are written to *)

Semi-opaque record based AD Ts? should be designed such that restricted fields of instances are auto-initialised.

Example:

 TYPE Semi Opaque? = RECORD
 * i : INTEGER = 0; (* restricted field *)
   j, k : INTEGER (* public fields *)
 END;
2015-09-27 09:34 by trijezdci -
Changed lines 425-426 from:

One or more fields in a record type declaration may be export restricted by prefixing their declaration with the * symbol. An export restricted field is only accessible within the library module in which the record type is defined and any extension library thereof.

to:

An instance of a record type holds exactly one value for each field. Fields are addressable by selector using dot notation.

Deleted lines 427-436:

Example:

 TYPE Point = RECORD
   * typeID : UniqueTypeID; (* export restricted field *)
     x, y : REAL (* publicly accessible fields *)
 END;

An instance of a record type holds exactly one value for each field. Fields are addressable by selector using dot notation.

Changed lines 559-560 from:

An opaque record type is a record type with export restricted fields. It is used for the construction of ADTs.

to:

An opaque record type is a record type with export restricted fields, used for the construction of ADTs. An export restricted field is a field that is directly accessible only within the library module in which the type is defined and within any extension library thereof. It is not directly accessible within any other scope. An export restricted field is declared by prefixing its declaration with the * symbol.

Changed line 565 from:
   * length : OCTET; (* export restricted field *)
to:
   * length : OCTET = 0; (* export restricted field *)
Changed line 586 from:
 str.length := 0; (* compile time error: access of a restricted field *)
to:
 str.length := 5; (* compile time error: access of a restricted field *)
2015-09-27 06:41 by trijezdci -
Added lines 423-432:

One or more fields in a record type declaration may be export restricted by prefixing their declaration with the * symbol. An export restricted field is only accessible within the library module in which the record type is defined and any extension library thereof.

Example:

 TYPE Point = RECORD
   * typeID : UniqueTypeID; (* export restricted field *)
     x, y : REAL (* publicly accessible fields *)
 END;
2015-09-27 06:26 by trijezdci -
Changed line 572 from:

Since all fields are lexically present within the definition part, the allocation size of an opaque record type can be calculated even when no source code is available for the corresponding implementation part. Instances of opaque record based ADTs are therefore statically allocatable.

to:

Since all record fields are lexically present within the definition part, the allocation size of an opaque record type can be calculated at compile time even when no source code is available for the corresponding implementation part. Instances of opaque record based ADTs are therefore statically allocatable.

2015-09-27 05:55 by trijezdci -
Changed line 580 from:

Fields that are not export restricted are directly accessible in any scope into which an opaque record type has been imported, but export restricted fields are only accessible within the implementation part and extension modules of the library that defines the opaque record type. They may only be operated on by clients through facilities provided in the library's public interface.

to:

Fields that are not export restricted are directly accessible in any scope into which an opaque record type has been imported, but export restricted fields are only accessible within the implementation part and extension modules of the library that defines the opaque record type. Export restricted fields may only be operated on by clients through facilities provided in the library's public interface.

2015-09-27 05:53 by trijezdci -
Added line 582:
2015-09-27 05:52 by trijezdci -
Changed lines 565-566 from:
   * length : OCTET;
   * data : ARRAY 255 OF OCTET (* export restricted *)
to:
   * length : OCTET; (* export restricted field *)
   * data : ARRAY 255 OF OCTET (* export restricted field *)
2015-09-27 05:50 by trijezdci -
Changed lines 563-564 from:
 DEFINITION MODULE Pascal String?;
 TYPE Pascal String? = RECORD
to:
 DEFINITION MODULE PascalString;
 TYPE PascalString = RECORD
Changed line 569 from:
to:
 END PascalString.
Changed lines 576-577 from:
 IMPORT Pascal String?;
 VAR str : Pascal String?; (* allocated on the stack *)
to:
 IMPORT PascalString;
 VAR str : PascalString; (* allocated on the stack *)
Changed lines 583-584 from:
 IMPORT Pascal String?;
 VAR str : Pascal String?;
to:
 IMPORT PascalString;
 VAR str : PascalString;
Changed lines 586-587 from:
 Terminal.Write Octets?(str.data); (* compile time error: access of a restricted field *)
 Pascal String?.copy(str, "foobar"); (* proper use: operation through public interface *)
to:
 Terminal.WriteOctets(str.data); (* compile time error: access of a restricted field *)
 PascalString.copy(str, "foobar"); (* proper use: operation through public interface *)
2015-09-27 05:49 by trijezdci -
Changed lines 425-426 from:

An instance of a record type holds exactly one value for each field. Fields are addressable by selector.

to:

An instance of a record type holds exactly one value for each field. Fields are addressable by selector using dot notation.

Added lines 555-588:

Opaque Record Types

An opaque record type is a record type with export restricted fields. It is used for the construction of ADTs.

Example:

 DEFINITION MODULE Pascal String?;
 TYPE Pascal String? = RECORD
   * length : OCTET;
   * data : ARRAY 255 OF OCTET (* export restricted *)
 END;
 (* public interface *)
 END Pascal String?.

Since all fields are lexically present within the definition part, the allocation size of an opaque record type can be calculated even when no source code is available for the corresponding implementation part. Instances of opaque record based ADTs are therefore statically allocatable.

Example:

 IMPORT Pascal String?;
 VAR str : Pascal String?; (* allocated on the stack *)

Fields that are not export restricted are directly accessible in any scope into which an opaque record type has been imported, but export restricted fields are only accessible within the implementation part and extension modules of the library that defines the opaque record type. They may only be operated on by clients through facilities provided in the library's public interface.

Example:

 IMPORT Pascal String?;
 VAR str : Pascal String?;
 str.length := 0; (* compile time error: access of a restricted field *)
 Terminal.Write Octets?(str.data); (* compile time error: access of a restricted field *)
 Pascal String?.copy(str, "foobar"); (* proper use: operation through public interface *)
2015-09-27 04:42 by trijezdci -
Deleted line 21:
Changed lines 33-34 from:
to:
Changed lines 211-223 from:

Opaque Types

An opaque type is a type whose internal composition and structure is not accessible outside of the implementation part of the library in which it is defined. Instances of an opaque type may only be operated on by clients of its exporting library through the operations exported by the public interface of the library. There are two kinds of opaque types:

  • opaque pointer types
  • opaque record types

Opaque Pointer Types

An opaque pointer type is a special pointer type used for the construction of ADTs. The definition and declaration of such an ADT is divided between the definition and implementation part of its library. The identifier of the opaque type is defined in the library's definition part and it may be imported from there by clients. It is defined using the OPAQUE type constructor.

to:

Derived Types

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

Added lines 217-223:

Examples:

 TYPE Celsius = REAL; Fahrenheit = REAL;

Due to strict name equivalence, derived types and their base types are incompatible because their identifiers are different.

Changed lines 225-228 from:
 DEFINITION MODULE Tree;
 TYPE Tree = OPAQUE; (* opaque pointer *)
 (* public interface *)
 END Tree.
to:
 VAR celsius : Celsius; fahrenheit : Fahrenheit;
 celsius := fahrenheit; (* compile time error: incompatible types *)
Changed lines 229-230 from:

The target type of the opaque pointer is declared in the library's corresponding implementation part and it is therefore inaccessible to clients. It is declared using the PPOINTER TO type constructor.

to:

To assign values across type boundaries, type conversion is required.

Changed lines 233-240 from:
 IMPLEMENTATION MODULE Tree;
 TYPE Tree = POINTER TO TreeDescriptor; (* target type specification *)
 TYPE TreeDescriptor = RECORD
   left, right : Tree;
   value : ValueType
 END; (* TreeDescriptor *)
 (* implementation *)
 END Tree.
to:
 celsius := (fahrenheit :: Celsius - 32.0) * 100.0/180.0; (* type conversion *)
Changed lines 236-237 from:

Instances of an opaque pointer based ADT may only be allocated dynamically at runtime.

to:

ALIAS Types

An ALIAS type is a derived type specifically defined to be compatible with its base type even though their identifiers are different. An ALIAS type is defined using the ALIAS OF type constructor.

Changed lines 243-245 from:
 IMPORT Tree;
 VAR tree : Tree;
 NEW tree := { foo, bar, baz };
to:
 TYPE INT = ALIAS OF INTEGER;
Changed lines 246-250 from:

Derived Types

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

to:

An ALIAS type and its base type are compatible in every aspect. They may therefore be used interchangeably.

Changed lines 249-250 from:

Examples:

 TYPE Celsius = REAL; Fahrenheit = REAL;
to:

Example:

 VAR i : INT; j : INTEGER;
 i := j; (* i and j are compatible *)
Changed lines 254-255 from:

Due to strict name equivalence, derived types and their base types are incompatible because their identifiers are different.

to:

Subrange Types

A subrange type is a type defined as a subset of a scalar or ordinal type. A subrange type is upwards compatible with its base type, but the base type is not downwards compatible with any subrange types derived from it. A subrange type inherits all its properties from its base type, except for its lower and upper bound. A subrange type's lower and upper bound must be specified in its type definition. Both lower and upper bound must be compatible with the base type and they must be legal values of the base type.

Changed lines 260-262 from:

Example:

 VAR celsius : Celsius; fahrenheit : Fahrenheit;
 celsius := fahrenheit; (* compile time error: incompatible types *)
to:

Examples:

 TYPE Radian = [0.0 .. tau] OF REAL;
 TYPE Natural = [1 .. TMAX(CARDINAL)] OF CARDINAL;
Changed lines 265-266 from:

To assign values across type boundaries, type conversion is required.

to:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol. An open bound of a subrange type is not a legal value of the type.

Changed lines 268-269 from:

Example:

 celsius := (fahrenheit :: Celsius - 32.0) * 100.0/180.0; (* type conversion *)
to:

Examples:

 TYPE PosReal = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE NegReal = [TMIN(REAL) .. <0.0] OF REAL;
Changed lines 273-277 from:

ALIAS Types

An ALIAS type is a derived type specifically defined to be compatible with its base type even though their identifiers are different. An ALIAS type is defined using the ALIAS OF type constructor.

to:

Immutable Types

A CONST type is a type defined to be an immutable alias type of a mutable ADT. A CONST type is defined using the CONST type constructor.

Changed line 280 from:
 TYPE INT = ALIAS OF INTEGER;
to:
 TYPE ImmutableFooArray = CONST FooArray;
Changed lines 283-284 from:

An ALIAS type and its base type are compatible in every aspect. They may therefore be used interchangeably.

to:

A CONST type is compatible with its base type, except where such compatibility would violate the type's immutability.

Changed lines 287-288 from:
 VAR i : INT; j : INTEGER;
 i := j; (* i and j are compatible *)
to:
 VAR array : FooArray; immArray : ImmutableFooArray;
 NEW array; (* initialisation not required *)
 NEW immArray := { foo, bar, baz }; (* initialisation required *)
 COPY array := immArray; (* copying from immutable to mutable *)
 COPY immArray := array; (* compile time error: attempt to modify immutable instance *)
Changed lines 294-298 from:

Subrange Types

A subrange type is a type defined as a subset of a scalar or ordinal type. A subrange type is upwards compatible with its base type, but the base type is not downwards compatible with any subrange types derived from it. A subrange type inherits all its properties from its base type, except for its lower and upper bound. A subrange type's lower and upper bound must be specified in its type definition. Both lower and upper bound must be compatible with the base type and they must be legal values of the base type.

to:

Enumeration Types

EBNF | Syntax Diagram

An enumeration type is an ordinal type whose legal values are defined by a list of identifiers. The identifiers are assigned ordinal values from left to right as they appear in the type definition. The ordinal value assigned to the leftmost identifier is always zero.

Changed lines 303-305 from:

Examples:

 TYPE Radian = [0.0 .. tau] OF REAL;
 TYPE Natural = [1 .. TMAX(CARDINAL)] OF CARDINAL;
to:

Example:

 TYPE Colour = ( red, green, blue ); (* ORD(red) => 0 *)
Changed lines 307-308 from:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol. An open bound of a subrange type is not a legal value of the type.

to:

When referencing an enumerated value, its identifier must be qualified with its type identifier, except within a subrange type constructor. This requirement fixes a flaw in classic Modula-2 where the import of an enumeration type could cause name conflicts.

Changed lines 310-312 from:

Examples:

 TYPE PosReal = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE NegReal = [TMIN(REAL) .. <0.0] OF REAL;
to:

Example:

 TYPE BaseColour = [red .. green] OF Colour; (* unqualified *)
 VAR colour : Colour;  colour := Colour.green; (* qualified *)
Changed lines 315-319 from:

Immutable Types

A CONST type is a type defined to be an immutable alias type of a mutable ADT. A CONST type is defined using the CONST type constructor.

to:
Enumeration Type Extension

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type. The base type is downwards compatible with any extended types derived from it, but extensions are not upwards compatible with their base type. This restriction exists because any value of the base type is always a legal value of any extension type derived from it, but not every value of an extension type is also a legal value of the base type.

Changed lines 321-322 from:
 TYPE ImmutableFooArray = CONST FooArray;
to:
 TYPE MoreColour = ( +Colour, orange, magenta, cyan );
 (* equivalent to: MoreColour = ( red, green, blue, orange, magenta, cyan );
Changed lines 325-326 from:

A CONST type is compatible with its base type, except where such compatibility would violate the type's immutability.

to:

The allocation size of an enumeration type is always 16 bit. Its maximum value range is 65536 values.

Set Types

EBNF | Syntax Diagram

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type of up to 256 values. The values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

Changed lines 336-340 from:
 VAR array : FooArray; immArray : ImmutableFooArray;
 NEW array; (* initialisation not required *)
 NEW immArray := { foo, bar, baz }; (* initialisation required *)
 COPY array := immArray; (* copying from immutable to mutable *)
 COPY immArray := array; (* compile time error: attempt to modify immutable instance *)
to:
 TYPE ColourSet = SET OF Colour;
Changed lines 339-346 from:

Enumeration Types

EBNF | Syntax Diagram

An enumeration type is an ordinal type whose legal values are defined by a list of identifiers. The identifiers are assigned ordinal values from left to right as they appear in the type definition. The ordinal value assigned to the leftmost identifier is always zero.

to:

An instance of a set type may hold multiple elements but any given element may be stored at most once. An element stored in a set is said to be a member of the set. A set is represented as an array of boolean membership values, where the element is the accessor and the membership is the value. A membership value may thus be either TRUE or FALSE.

Changed lines 342-343 from:

Example:

 TYPE Colour = ( red, green, blue ); (* ORD(red) => 0 *)
to:

Examples:

 VAR  colours : ColourSet; isMember : BOOLEAN;
 colours := { Colour.red, Colour.green }; (* assignment *)
 isMember := colours[Colour.green]; (* membership retrieval *)
 colours[Colour.blue] := TRUE; (* membership storage *)
Changed lines 349-350 from:

When referencing an enumerated value, its identifier must be qualified with its type identifier, except within a subrange type constructor. This requirement fixes a flaw in classic Modula-2 where the import of an enumeration type could cause name conflicts.

to:

Array Types

EBNF | Syntax Diagram

An array type is an indexed collection type whose values are of a single arbitrary type, called the array's value type. The type's capacity is specified by a value count parameter in the type definition. The capacity must be a whole number value and it may not be zero. Array types are defined using the ARRAY OF type constructor.

Changed lines 358-359 from:
 TYPE BaseColour = [red .. green] OF Colour; (* unqualified *)
 VAR colour : Colour;  colour := Colour.green; (* qualified *)
to:
 TYPE IntArray = ARRAY 10 OF INTEGER;
Changed lines 361-364 from:
Enumeration Type Extension

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type. The base type is downwards compatible with any extended types derived from it, but extensions are not upwards compatible with their base type. This restriction exists because any value of the base type is always a legal value of any extension type derived from it, but not every value of an extension type is also a legal value of the base type.

to:

The values of an array instance are addressable by cardinal index using subscript notation. The lowest index is always zero.

Changed lines 364-366 from:

Example:

 TYPE MoreColour = ( +Colour, orange, magenta, cyan );
 (* equivalent to: MoreColour = ( red, green, blue, orange, magenta, cyan );
to:

Examples:

 VAR array : IntArray; int : INTEGER;
 array := { 0 BY TLIMIT(IntArray) }; (* initialise all values with zero *)
 int := array[5]; (* value retrieval *)
 array[5] := 42; (* value storage *)
Changed lines 371-379 from:

The allocation size of an enumeration type is always 16 bit. Its maximum value range is 65536 values.

Set Types

EBNF | Syntax Diagram

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type of up to 256 values. The values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

to:
Flexible Array Types

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it may not be zero.

Changed line 377 from:
 TYPE ColourSet = SET OF Colour;
to:
 TYPE FlexArray = ARRAY < 10 OF INTEGER;
Changed lines 380-381 from:

An instance of a set type may hold multiple elements but any given element may be stored at most once. An element stored in a set is said to be a member of the set. A set is represented as an array of boolean membership values, where the element is the accessor and the membership is the value. A membership value may thus be either TRUE or FALSE.

to:

The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be appended, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be appended, inserted and removed at runtime.

Changed lines 384-387 from:
 VAR  colours : ColourSet; isMember : BOOLEAN;
 colours := { Colour.red, Colour.green }; (* assignment *)
 isMember := colours[Colour.green]; (* membership retrieval *)
 colours[Colour.blue] := TRUE; (* membership storage *)
to:
 VAR array : FlexArray;
 array := { 42, -5, 0 }; (* initialise with three values *)
 APPEND(array, -35); (* append a value *)
 INSERT(array, 0, 11); (* value insertion *)
 REMOVE(array, 3, 1); (* value removal *)
Changed lines 391-397 from:

Array Types

EBNF | Syntax Diagram

An array type is an indexed collection type whose values are of a single arbitrary type, called the array's value type. The type's capacity is specified by a value count parameter in the type definition. The capacity must be a whole number value and it may not be zero. Array types are defined using the ARRAY OF type constructor.

to:

Instances of flexible arrays may further be sliced and concatenated. Flexible array types and their slices are insertion and concatenation compatible as long as the respective value types are compatible.

Deleted lines 393-399:

Example:

 TYPE IntArray = ARRAY 10 OF INTEGER;

The values of an array instance are addressable by cardinal index using subscript notation. The lowest index is always zero.

Changed lines 395-398 from:
 VAR array : IntArray; int : INTEGER;
 array := { 0 BY TLIMIT(IntArray) }; (* initialise all values with zero *)
 int := array[5]; (* value retrieval *)
 array[5] := 42; (* value storage *)
to:
 VAR array1, array2, array3 : FlexArray;
 array2 := { 1, 2, 3, 4 }; array3 := { 7, 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 4, 7, 8, 9 } *)
 array1[4..5] := { 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
Changed lines 401-404 from:
Flexible Array Types

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it may not be zero.

to:
Character Arrays

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. An attempt to define a rigid character array type shall cause a compile time error.

Changed lines 406-407 from:

Example:

 TYPE FlexArray = ARRAY < 10 OF INTEGER;
to:

Examples:

 TYPE String = ARRAY 100 OF CHAR; (* compile time error: unsupported definition *)
 TYPE String = ARRAY < 100 OF CHAR; (* OK, supported character array type definition *)
Changed lines 411-412 from:

The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be appended, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be appended, inserted and removed at runtime.

to:

The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every assign, append and concatenation operation.

Record Types

EBNF | Syntax Diagram

A record type is a compound type whose components are of arbitrary types. The components are called fields. The number of fields is arbitrary. Record types are defined using the RECORD type constructor.

Added lines 421-427:

Example:

 TYPE Point = RECORD x, y : REAL END;

An instance of a record type holds exactly one value for each field. Fields are addressable by selector.

Changed lines 429-433 from:
 VAR array : FlexArray;
 array := { 42, -5, 0 }; (* initialise with three values *)
 APPEND(array, -35); (* append a value *)
 INSERT(array, 0, 11); (* value insertion *)
 REMOVE(array, 3, 1); (* value removal *)
to:
 VAR  point : Point; r : REAL;
 record := { 0.0, 0.0 }; (* initialise all fields with zero *)
 r := point.x; (* field retrieval *)
 point.y := 0.75; (* field storage *)
Changed lines 435-436 from:

Instances of flexible arrays may further be sliced and concatenated. Flexible array types and their slices are insertion and concatenation compatible as long as the respective value types are compatible.

to:
Record Type Extension

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. All fields of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any field of the base type is always a field of any extension type derived from it, but not every field of an extension type is also a field of the base type.

Changed lines 441-444 from:
 VAR array1, array2, array3 : FlexArray;
 array2 := { 1, 2, 3, 4 }; array3 := { 7, 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 4, 7, 8, 9 } *)
 array1[4..5] := { 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
to:
 TYPE ColourPoint = RECORD ( Point ) colour : Colour END;
 VAR  cPoint : ColourPoint;
 cPoint := { 0.0, 0.0, Colour.red }; (* initialise all fields *)
 cPoint.x := 1.5; cPoint.y := 0.75;
Changed lines 447-450 from:
Character Arrays

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. An attempt to define a rigid character array type shall cause a compile time error.

to:

Pointer Types

EBNF | Syntax Diagram

A pointer type is a container for a typed reference to an entity at a memory storage location. The type of the referenced entity is called the target type. The entity referenced by an instance of a pointer type is called the pointer's target. Pointer types are defined using the POINTER TO type constructor.

Changed lines 455-457 from:

Examples:

 TYPE String = ARRAY 100 OF CHAR; (* compile time error: unsupported definition *)
 TYPE String = ARRAY < 100 OF CHAR; (* OK, supported character array type definition *)
to:

Example:

 TYPE IntPtr = POINTER TO INTEGER;
Changed lines 459-467 from:

The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every assign, append and concatenation operation.

Record Types

EBNF | Syntax Diagram

A record type is a compound type whose components are of arbitrary types. The components are called fields. The number of fields is arbitrary. Record types are defined using the RECORD type constructor.

to:

Typed references are created using predefined procedure PTR. Instances of pointer types are dereferenced using the pointer dereferencing operator ^.

Changed lines 463-465 from:
 TYPE Point = RECORD x, y : REAL END;
to:
 VAR int : INTEGER; intPtr : IntPtr;
 intPtr := PTR(int, IntPtr); (* obtain a typed reference to int *)
 intPtr^ := 0; (* write to int via dereferenced pointer intPtr *)
Changed lines 468-469 from:

An instance of a record type holds exactly one value for each field. Fields are addressable by selector.

to:

A pointer type may be defined to restrict the mutability of its target.

Changed lines 471-475 from:

Examples:

 VAR  point : Point; r : REAL;
 record := { 0.0, 0.0 }; (* initialise all fields with zero *)
 r := point.x; (* field retrieval *)
 point.y := 0.75; (* field storage *)
to:

Example:

 TYPE ImmIntPtr = POINTER TO CONST INTEGER;
Changed lines 475-478 from:
Record Type Extension

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. All fields of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any field of the base type is always a field of any extension type derived from it, but not every field of an extension type is also a field of the base type.

to:

Although the instance of such a pointer itself is mutable, its target is always treated immutable. A dereferenced instance may not be used as an L-value and it may not be passed to a procedure as a VAR parameter. Pointers to mutable and immutable targets are therefore always incompatible. Any violation shall cause a compile time error.

Changed lines 478-482 from:

Examples:

 TYPE ColourPoint = RECORD ( Point ) colour : Colour END;
 VAR  cPoint : ColourPoint;
 cPoint := { 0.0, 0.0, Colour.red }; (* initialise all fields *)
 cPoint.x := 1.5; cPoint.y := 0.75;
to:

Example:

 VAR int : INTEGER; intPtr : IntPtr; immPtr : ImmIntPtr;
 intPtr := PTR(int, IntPtr); immPtr := PTR(int, ImmIntPtr);
 intPtr^ := 0; (* OK, modifying a mutable target *)
 immPtr^ := 0; (* compile time error due to attempt to modify an immutable target *)
Changed lines 485-491 from:

Pointer Types

EBNF | Syntax Diagram

A pointer type is a container for a typed reference to an entity at a memory storage location. The type of the referenced entity is called the target type. The entity referenced by an instance of a pointer type is called the pointer's target. Pointer types are defined using the POINTER TO type constructor.

to:

Coroutine Types

EBNF | Syntax Diagram

A coroutine type is a special purpose pointer type whose target is a coroutine. An associated procedure type is part of the type definition. A coroutine procedure is compatible with a coroutine type when it matches the signature of the type's associated procedure type. Coroutine types are defined using the COROUTINE type constructor.

Changed lines 493-494 from:

Example:

 TYPE IntPtr = POINTER TO INTEGER;
to:

Examples:

 TYPE Iterator = COROUTINE ( IteratorProc );
Changed lines 497-498 from:

Typed references are created using predefined procedure PTR. Instances of pointer types are dereferenced using the pointer dereferencing operator ^.

to:

Procedure Types

EBNF | Syntax Diagram

A procedure type is a special purpose pointer type whose target is a procedure. The procedure's signature is part of the type definition. A procedure is compatible with a procedure type when their signatures match. Procedure types are defined using the PROCEDURE type constructor.

Changed lines 505-508 from:

Example:

 VAR int : INTEGER; intPtr : IntPtr;
 intPtr := PTR(int, IntPtr); (* obtain a typed reference to int *)
 intPtr^ := 0; (* write to int via dereferenced pointer intPtr *)
to:

Examples:

 TYPE WriteStrProc = PROCEDURE ( CONST ARRAY OF CHAR );
 TYPE FSM = PROCEDURE ( CONST ARRAY OF CHAR, FSM );
Changed lines 510-511 from:

A pointer type may be defined to restrict the mutability of its target.

to:

Opaque Types

An opaque type is a type whose internal composition and structure is not accessible outside of the implementation part of the library in which it is defined. Instances of an opaque type may only be operated on by clients of its exporting library through the operations exported by the public interface of the library. There are two kinds of opaque types:

  • opaque pointer types
  • opaque record types

Opaque Pointer Types

An opaque pointer type is a special pointer type used for the construction of ADTs. The definition and declaration of such an ADT is divided between the definition and implementation part of its library. The identifier of the opaque type is defined in the library's definition part and it may be imported from there by clients. It is defined using the OPAQUE type constructor.

Changed lines 526-529 from:
 TYPE ImmIntPtr = POINTER TO CONST INTEGER;
to:
 DEFINITION MODULE Tree;
 TYPE Tree = OPAQUE; (* opaque pointer *)
 (* public interface *)
 END Tree.
Changed lines 532-533 from:

Although the instance of such a pointer itself is mutable, its target is always treated immutable. A dereferenced instance may not be used as an L-value and it may not be passed to a procedure as a VAR parameter. Pointers to mutable and immutable targets are therefore always incompatible. Any violation shall cause a compile time error.

to:

The target type of the opaque pointer is declared in the library's corresponding implementation part and it is therefore inaccessible to clients. It is declared using the PPOINTER TO type constructor.

Changed lines 536-539 from:
 VAR int : INTEGER; intPtr : IntPtr; immPtr : ImmIntPtr;
 intPtr := PTR(int, IntPtr); immPtr := PTR(int, ImmIntPtr);
 intPtr^ := 0; (* OK, modifying a mutable target *)
 immPtr^ := 0; (* compile time error due to attempt to modify an immutable target *)
to:
 IMPLEMENTATION MODULE Tree;
 TYPE Tree = POINTER TO TreeDescriptor; (* target type specification *)
 TYPE TreeDescriptor = RECORD
   left, right : Tree;
   value : ValueType
 END; (* TreeDescriptor *)
 (* implementation *)
 END Tree.
Changed lines 546-552 from:

Coroutine Types

EBNF | Syntax Diagram

A coroutine type is a special purpose pointer type whose target is a coroutine. An associated procedure type is part of the type definition. A coroutine procedure is compatible with a coroutine type when it matches the signature of the type's associated procedure type. Coroutine types are defined using the COROUTINE type constructor.

to:

Instances of an opaque pointer based ADT may only be allocated dynamically at runtime.

Changed lines 549-550 from:

Examples:

 TYPE Iterator = COROUTINE ( IteratorProc );
to:

Example:

 IMPORT Tree;
 VAR tree : Tree;
 NEW tree := { foo, bar, baz };
Deleted lines 554-565:

Procedure Types

EBNF | Syntax Diagram

A procedure type is a special purpose pointer type whose target is a procedure. The procedure's signature is part of the type definition. A procedure is compatible with a procedure type when their signatures match. Procedure types are defined using the PROCEDURE type constructor.

Examples:

 TYPE WriteStrProc = PROCEDURE ( CONST ARRAY OF CHAR );
 TYPE FSM = PROCEDURE ( CONST ARRAY OF CHAR, FSM );
2015-09-27 04:35 by trijezdci -
Changed lines 222-224 from:

An opaque pointer type is a special pointer type used for the construction of ADTs. The definition and declaration of such an ADT is divided between the definition and implementation part of its library. The identifier of the opaque type is defined in the library's definition part and may be imported from there by clients.

The identifier of an opaque pointer type is available in the library that defines it and in modules that import it. It is defined using the OPAQUE type constructor.

to:

An opaque pointer type is a special pointer type used for the construction of ADTs. The definition and declaration of such an ADT is divided between the definition and implementation part of its library. The identifier of the opaque type is defined in the library's definition part and it may be imported from there by clients. It is defined using the OPAQUE type constructor.

2015-09-27 04:32 by trijezdci -
Changed line 242 from:
   value : Value Type?
to:
   value : ValueType
2015-09-27 04:32 by trijezdci -
Changed lines 239-240 from:
 TYPE Tree = POINTER TO Tree Descriptor?; (* target type specification *)
 TYPE Tree Descriptor? = RECORD
to:
 TYPE Tree = POINTER TO TreeDescriptor; (* target type specification *)
 TYPE TreeDescriptor = RECORD
Changed line 243 from:
 END; (* Tree Descriptor? *)
to:
 END; (* TreeDescriptor *)
2015-09-27 04:31 by trijezdci -
Changed lines 5-7 from:
to:
Changed lines 10-12 from:
to:
Changed lines 15-17 from:
to:
Changed lines 19-33 from:
to:
Changed lines 36-38 from:
to:
Changed lines 40-57 from:
to:
Changed lines 61-82 from:
to:
Changed lines 88-92 from:
to:
Changed lines 94-102 from:
to:
Changed lines 104-114 from:
to:
Changed lines 116-130 from:
to:
Changed lines 132-136 from:
to:
Changed line 148 from:
to:
Changed line 150 from:
to:
Changed lines 152-153 from:
to:
Added line 198:
  • opaque types
Added lines 210-255:

Opaque Types

An opaque type is a type whose internal composition and structure is not accessible outside of the implementation part of the library in which it is defined. Instances of an opaque type may only be operated on by clients of its exporting library through the operations exported by the public interface of the library. There are two kinds of opaque types:

  • opaque pointer types
  • opaque record types

Opaque Pointer Types

An opaque pointer type is a special pointer type used for the construction of ADTs. The definition and declaration of such an ADT is divided between the definition and implementation part of its library. The identifier of the opaque type is defined in the library's definition part and may be imported from there by clients.

The identifier of an opaque pointer type is available in the library that defines it and in modules that import it. It is defined using the OPAQUE type constructor.

Example:

 DEFINITION MODULE Tree;
 TYPE Tree = OPAQUE; (* opaque pointer *)
 (* public interface *)
 END Tree.

The target type of the opaque pointer is declared in the library's corresponding implementation part and it is therefore inaccessible to clients. It is declared using the PPOINTER TO type constructor.

Example:

 IMPLEMENTATION MODULE Tree;
 TYPE Tree = POINTER TO Tree Descriptor?; (* target type specification *)
 TYPE Tree Descriptor? = RECORD
   left, right : Tree;
   value : Value Type?
 END; (* Tree Descriptor? *)
 (* implementation *)
 END Tree.

Instances of an opaque pointer based ADT may only be allocated dynamically at runtime.

Example:

 IMPORT Tree;
 VAR tree : Tree;
 NEW tree := { foo, bar, baz };
2015-09-26 17:21 by trijezdci -
Changed line 278 from:
to:
 TYPE ImmutableFooArray = CONST FooArray;
Changed line 285 from:
 VAR array : Foo Array?; immArray : Immutable Foo Array?;
to:
 VAR array : FooArray; immArray : ImmutableFooArray;
2015-09-26 17:20 by trijezdci -
Changed lines 274-282 from:

to do

Enumeration Types

EBNF | Syntax Diagram

An enumeration type is an ordinal type whose legal values are defined by a list of identifiers. The identifiers are assigned ordinal values from left to right as they appear in the type definition. The ordinal value assigned to the leftmost identifier is always zero.

to:

A CONST type is a type defined to be an immutable alias type of a mutable ADT. A CONST type is defined using the CONST type constructor.

Example:

 TYPE Immutable Foo Array? = CONST Foo Array?;

A CONST type is compatible with its base type, except where such compatibility would violate the type's immutability.

Example:

 VAR array : Foo Array?; immArray : Immutable Foo Array?;
 NEW array; (* initialisation not required *)
 NEW immArray := { foo, bar, baz }; (* initialisation required *)
 COPY array := immArray; (* copying from immutable to mutable *)
 COPY immArray := array; (* compile time error: attempt to modify immutable instance *)
2015-09-26 17:00 by trijezdci -
Changed line 237 from:

An ALIAS type is a derived type specifically defined to be compatible with its base type. An ALIAS type is defined using the ALIAS OF type constructor.

to:

An ALIAS type is a derived type specifically defined to be compatible with its base type even though their identifiers are different. An ALIAS type is defined using the ALIAS OF type constructor.

2015-09-26 16:58 by trijezdci -
Added line 22:
Changed lines 197-200 from:
  • derived sub-types
to:
  • derived types
  • subrange types
  • alias types
  • immutable types
Changed lines 209-218 from:

to do

Derived Sub-Types

EBNF | Syntax Diagram

  • alias types
  • subrange types
  • immutable types
to:

Derived Types

A derived type is a type defined to inherit all its properties from another type, except for its identifier. A derived type is defined using the = symbol followed by the base type in the type constructor.

Examples:

 TYPE Celsius = REAL; Fahrenheit = REAL;

Due to strict name equivalence, derived types and their base types are incompatible because their identifiers are different.

Example:

 VAR celsius : Celsius; fahrenheit : Fahrenheit;
 celsius := fahrenheit; (* compile time error: incompatible types *)

To assign values across type boundaries, type conversion is required.

Example:

 celsius := (fahrenheit :: Celsius - 32.0) * 100.0/180.0; (* type conversion *)
Changed lines 237-250 from:

to do

to:

An ALIAS type is a derived type specifically defined to be compatible with its base type. An ALIAS type is defined using the ALIAS OF type constructor.

Example:

 TYPE INT = ALIAS OF INTEGER;

An ALIAS type and its base type are compatible in every aspect. They may therefore be used interchangeably.

Example:

 VAR i : INT; j : INTEGER;
 i := j; (* i and j are compatible *)
2015-09-26 16:13 by trijezdci -
Changed line 1993 from:

Primitive SUBSET is a polymorphic primitive to test whether a set is a subset of another. It has one signature:

to:

Primitive SUBSET is a polymorphic primitive to test whether a set is a subset of another. It is called passing the set to be tested as its first operand and the suspected superset as its second operand. Both operands shall be of the same set type. The primitive returns TRUE if the first operand is a subset of the second operand, otherwise FALSE. It has one signature:

2015-09-26 16:05 by trijezdci -
Added lines 1974-1975:

To obtain a list element accessor for the n-th value stored in a list, the primitive is called passing the list as its first operand and the index as its second operand. The first operand shall be of a list type and the second operand shall be of type LONGCARD. The primitive returns an accessor for the list element that stores the value or NIL if no element exists at the given index.

Added lines 1981-1982:

To obtain the preceding or succeeding list element accessor of a known accessor in a list, the primitive is called passing the list as its first operand, the known accessor as its second operand and a neighbour selector as its third operand. The first operand shall be of a list type. The second operand shall be of the list's accessor type and the third operand shall be a quoted character literal of type CHAR where "+" selects the succeeding and "-" selects the preceding neighbour. The primitive returns an accessor to the selected neighbour element in the list or NIL if the selected neighbour does not exist.

2015-09-26 15:46 by trijezdci -
Changed line 1959 from:

To retrieve the n-th value stored for a key in a multi-dictionary, the primitive is called passing the dictionary as its first operand, the key as its second operand and the index of the value to be retrieved as its third operand. The first operand shall be of a dictionary type. The second operand shall be of the dictionary's key type and the third operand shall be of type CARDINAL. The primitive returns the value stored at the index for the key in the dictionary.

to:

To retrieve the n-th value stored for a key in a multi-dictionary, the primitive is called passing the dictionary as its first operand, the key as its second operand and the index of the value to be retrieved as its third operand. The first operand shall be of a multi-dictionary type. The second operand shall be of the dictionary's key type and the third operand shall be of type CARDINAL. The primitive returns the value stored at the index for the key in the dictionary.

2015-09-26 15:45 by trijezdci -
Added lines 1927-1928:

To retrieve the value stored at a given index in an array, the primitive is called passing the array as its first operand and the index as its second operand. The first operand shall be of an array type and the second operand shall be of the array's index type. The primitive returns the value stored at the index in the array.

Added lines 1935-1936:

To retrieve the value stored at a given list element accessor from a list, the primitive is called passing the list as its firs operand and the element accessor as its second operand. The first operand shall be of a list type and the second operand shall be of the list's accessor type. The primitive returns the value stored at the accessor in the list.

Changed lines 1941-1942 from:
Retrieving A Counter From A Set
to:
Retrieving An Element Counter From A Set

To retrieve the counter for a given element in a set, the primitive is called passing the set as its first operand and the element as its second operand. The first operand shall be of a set type and the second operand shall be of the set's element type. The primitive returns a value indicating how many times the element is stored in the list.

Added lines 1951-1952:

To retrieve the value stored for a given key in a dictionary, the primitive is called passing the dictionary as its first operand and the key as its second operand. The first operand shall be of a dictionary type and the second operand shall be of the dictionary's key type. The primitive returns the value stored for the key in the dictionary.

Added lines 1958-1959:

To retrieve the n-th value stored for a key in a multi-dictionary, the primitive is called passing the dictionary as its first operand, the key as its second operand and the index of the value to be retrieved as its third operand. The first operand shall be of a dictionary type. The second operand shall be of the dictionary's key type and the third operand shall be of type CARDINAL. The primitive returns the value stored at the index for the key in the dictionary.

2015-09-26 15:24 by trijezdci -
Changed line 1867 from:

To overwrite one or more consecutive values starting at a given index in an array of list with a fill value, the primitive is called passing the array or list as its first operand, the start index as its second operand, the number of values to be overwritten as its third operand and the fill value as its fourth operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in case of a list, it shall be of type LONGCARD. The third operand shall be of type LONGCARD and the fourth operand shall be of the value type of the array or list.

to:

To overwrite one or more consecutive values starting at a given index in an array or list with a fill value, the primitive is called passing the array or list as its first operand, the start index as its second operand, the number of values to be overwritten as its third operand and the fill value as its fourth operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in case of a list, it shall be of type LONGCARD. The third operand shall be of type LONGCARD and the fourth operand shall be of the value type of the array or list.

2015-09-26 15:22 by trijezdci -
Changed lines 1743-1744 from:

An Invocation of TAMX is replaced by the largest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. Its replacement value is of the type denoted by its operand. It has one signature:

to:

An Invocation of TMAX is replaced by the largest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. Its replacement value is of the type denoted by its operand. It has one signature:

Changed lines 1858-1859 from:

To overwrite multiple consecutive values starting at a given index in an array or list, the primitive is called passing the array or list as its first operand, the start index as its second operand and the values to be written as its third operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in the case of a list, it shall be of type LONGCARD. The third operand shall be a non-empty variadic list of the value type of the array or list.

to:

To overwrite one or more consecutive values starting at a given index in an array or list, the primitive is called passing the array or list as its first operand, the start index as its second operand and the values to be written as its third operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in the case of a list, it shall be of type LONGCARD. The third operand shall be a non-empty variadic list of the value type of the array or list.

Changed lines 1867-1868 from:

To overwrite one of more consecutive values starting at a given index in an array of list with a fill value, the primitive is called passing the array or list as its first operand, the start index as its second operand, the number of values to be overwritten as its third operand and the fill value as its fourth operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in case of a list, it shall be of type LONGCARD. The third operand shall be of type LONGCARD and the fourth operand shall be of the value type of the array or list.

to:

To overwrite one or more consecutive values starting at a given index in an array of list with a fill value, the primitive is called passing the array or list as its first operand, the start index as its second operand, the number of values to be overwritten as its third operand and the fill value as its fourth operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in case of a list, it shall be of type LONGCARD. The third operand shall be of type LONGCARD and the fourth operand shall be of the value type of the array or list.

Changed lines 1885-1886 from:

To overwrite the element counters of multiple given elements in a set, the primitive is called passing the set as its first operand and the element/counter pairs to be written as its second operand. The first operand shall be of a set type. The second operand shall be a non-empty variadic list of element/counter pairs, where the elements are of the set's element type and the counters are of the set's counter type.

to:

To overwrite the element counters of multiple given elements in a set, the primitive is called passing the set as its first operand and a list of element/counter pairs to be written as its second operand. The first operand shall be of a set type. The second operand shall be a non-empty variadic list of element/counter pairs, where the elements are of the set's element type and the counters are of its counter type.

Changed lines 1901-1903 from:
Overwriting Multiple Key/Value Pairs In A Dictionary

To overwrite multiple values for given keys in a dictionary, the primitive is called passing the dictionary as its first operand and the key/value pairs to be written as its second operand. The first operand shall be of a dictionary type. The second operand shall be a non-empty variadic list of key/value pairs, where the keys are of the dictionary's key type and the values are of the dictionary's value type.

to:
Overwriting Multiple Values For Given Keys In A Dictionary

To overwrite multiple values for given keys in a dictionary, the primitive is called passing the dictionary as its first operand and a list of key/value pairs to be written as its second operand. The first operand shall be of a dictionary type. The second operand shall be a non-empty variadic list of key/value pairs, where the keys are of the dictionary's key type and the values are of its value type.

2015-09-26 15:16 by trijezdci -
Added lines 1842-1843:

To overwrite a value at a given index in an array, the primitive is called passing the array as its first operand, the index as its second operand and the value to be written as its third operand. The first operand shall be of an array type. The second operand shall be of the array type's index type. The third operand shall be of the array's value type.

Added lines 1850-1851:

To overwrite a value for a given accessor in a list, the primitive is called passing the list as its first operand, the accessor as its second operand and the value to be written as its third operand. The first operand shall be of a list type. The second operand shall be of the list type's accessor type. The third operand shall be of the list's value type.

Added lines 1858-1859:

To overwrite multiple consecutive values starting at a given index in an array or list, the primitive is called passing the array or list as its first operand, the start index as its second operand and the values to be written as its third operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in the case of a list, it shall be of type LONGCARD. The third operand shall be a non-empty variadic list of the value type of the array or list.

Added lines 1867-1868:

To overwrite one of more consecutive values starting at a given index in an array of list with a fill value, the primitive is called passing the array or list as its first operand, the start index as its second operand, the number of values to be overwritten as its third operand and the fill value as its fourth operand. The first operand shall be of an array or list type. The second operand shall be of the array's index type or in case of a list, it shall be of type LONGCARD. The third operand shall be of type LONGCARD and the fourth operand shall be of the value type of the array or list.

Added lines 1877-1878:

To overwrite the element counter of a given element in a set, the primitive is called passing the set as its first operand, the element as its second operand and the counter value to be written as its third operand. The first operand shall be of a set type. The second operand shall be of the set's element type. The third operand shall be of the set's counter type.

Added lines 1885-1886:

To overwrite the element counters of multiple given elements in a set, the primitive is called passing the set as its first operand and the element/counter pairs to be written as its second operand. The first operand shall be of a set type. The second operand shall be a non-empty variadic list of element/counter pairs, where the elements are of the set's element type and the counters are of the set's counter type.

Changed lines 1893-1894 from:
Overwriting A Key/Value Pair In A Dictionary
to:
Overwriting A Single Value For A Key In A Dictionary

To overwrite a value for a given key in a dictionary, the primitive is called passing the dictionary as its first operand, the key as its second operand and the value to be written as its third operand. The first operand shall be of a dictionary type. The second operand shall be of the dictionary's key type. The third operand shall be of the dictionary's value type.

Added lines 1903-1904:

To overwrite multiple values for given keys in a dictionary, the primitive is called passing the dictionary as its first operand and the key/value pairs to be written as its second operand. The first operand shall be of a dictionary type. The second operand shall be a non-empty variadic list of key/value pairs, where the keys are of the dictionary's key type and the values are of the dictionary's value type.

Changed lines 1910-1912 from:
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
to:
Overwriting The N-th Value For A Key In A Multi-Dictionary

To overwrite the n-th value for a given key in a multi-dictionary, the primitive is called passing the dictionary as its first operand, the key as its second operand, the index of the value to be overwritten as its third operand and the value to be written as its fourth operand. The first operand shall be of a multi-dictionary type. The second operand shall be of the dictionary's key type. The third operand shall be of type CARDINAL. The fourth operand shall be of the dictionary's value type.

2015-09-26 14:45 by trijezdci -
Changed lines 604-605 from:

A CASE statement is a flow-control statement that passes control to one of a number of labeled statements or statement sequences depending on the value of an ordinal expression.

to:

A CASE statement is a flow-control statement that passes control to one of a number of labeled statements or statement sequences depending on the value of an ordinal expression. Control is passed to the first statement following the case label that matches the ordinal expression. If no label matches, control is passed to the ELSE block.

Changed lines 617-618 from:

A case label shall be listed at most once. If a case is encountered at runtime that is not listed in the case label list and if there is no ELSE clause, no case label statements shall be executed and no error shall result.

to:

A case label shall be listed at most once. If a case is encountered at runtime that is not listed in the case label list and if there is no ELSE block, no case label statements shall be executed and no error shall result.

Changed line 1891 from:
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
to:
   ( c : <DictionaryType>; entries : ARGLIST >0 OF { key : <KeyType >; value : <ValueType> );
2015-09-26 14:32 by trijezdci -
Changed lines 1838-1841 from:

Primitive STORE is a polymorphic primitive to overwrite one or more values in a collection. It has eight signatures:

Overwriting A Single Value In An Array Or List
to:

Primitive STORE is a polymorphic primitive to overwrite one or more values in a collection. It has nine signatures:

Overwriting A Single Value In An Array
Changed line 1843 from:
 PROCEDURE STORE ( c : <SeqType>; atIndex : <IndexType>; value : <ValueType> );
to:
 PROCEDURE STORE ( c : <ArrayType>; atIndex : <IndexType>; value : <ValueType> );
Changed lines 1846-1847 from:
Overwriting Multiple Values In An Array Or List
to:
Overwriting A Single Value In A List
Changed lines 1849-1850 from:
 PROCEDURE STORE
   ( c : <SeqType>; fromIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
to:
 PROCEDURE STORE ( c : <ListType>; p : <AccessorType>; value : <ValueType> );
Changed lines 1852-1853 from:
Overwriting An Array Or List Or Part Thereof With A Fill-Value
to:
Overwriting Multiple Values In An Array Or List
Changed line 1856 from:
   ( c : <SeqType>; fromIndex : <IndexType>; valueCount : LONGCARD; fillValue : <ValueType> );
to:
   ( c : <SeqType>; fromIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
Changed lines 1859-1861 from:
Overwriting The Element Counter for A Single Element In A Set
to:
Overwriting An Array Or List Or Part Thereof With A Fill-Value
Changed lines 1862-1863 from:
 PROCEDURE STORE ( c : <SetType>; element : <ElementType>; counter : <CounterType> );
to:
 PROCEDURE STORE
   ( c : <SeqType>; fromIndex : <IndexType>; valueCount : LONGCARD; fillValue : <ValueType> );
Changed lines 1866-1867 from:
Overwriting The Element Counters for Multiple Elements In A Set
to:
Overwriting The Element Counter for A Single Element In A Set
Changed lines 1870-1871 from:
 PROCEDURE STORE
   ( c : <SetType>; entries : ARGLIST >0 OF { element : <ElementType>; counter : <CounterType> } );
to:
 PROCEDURE STORE ( c : <SetType>; element : <ElementType>; counter : <CounterType> );
Changed lines 1873-1875 from:
Overwriting A Key/Value Pair In A Dictionary
to:
Overwriting The Element Counters for Multiple Elements In A Set
Changed lines 1876-1877 from:
 PROCEDURE STORE ( c : <DictionaryType>; key : <KeyType>; value : <ValueType> );
to:
 PROCEDURE STORE
   ( c : <SetType>; entries : ARGLIST >0 OF { element : <ElementType>; counter : <CounterType> } );
Changed lines 1880-1881 from:
Overwriting Multiple Key/Value Pairs In A Dictionary
to:
Overwriting A Key/Value Pair In A Dictionary
Changed lines 1884-1885 from:
 PROCEDURE STORE
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
to:
 PROCEDURE STORE ( c : <DictionaryType>; key : <KeyType>; value : <ValueType> );
Changed lines 1887-1888 from:
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
to:
Overwriting Multiple Key/Value Pairs In A Dictionary
Changed line 1891 from:
   ( c : <DictionaryType>; key : <KeyType>; index : CARDINAL; value : <ValueType> );
to:
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
Changed lines 1894-1901 from:
to:
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
 PROCEDURE STORE
   ( c : <DictionaryType>; key : <KeyType>; index : CARDINAL; value : <ValueType> );
Changed line 1916 from:
 PROCEDURE VALUE ( VAR c : <ListType>; accessor : <AccessorType> ) : <ValueType>;
to:
 PROCEDURE VALUE ( VAR c : <ListType>; p : <AccessorType> ) : <ValueType>;
2015-09-26 12:17 by trijezdci -
Changed line 1941 from:
 PROCEDURE SEEK ( c : <ListType>; index : LONGCARD ) : <AccessorType> );
to:
 PROCEDURE SEEK ( c : <ListType>; index : LONGCARD ) : <AccessorType>;
Changed line 1948 from:
   ( c : <ListType>; current : <AccessorType>; plusOrMinus : <CharLiteral> ) : <AccessorType> );
to:
   ( c : <ListType>; current : <AccessorType>; plusOrMinus : <CharLiteral> ) : <AccessorType>;
Added lines 1951-1959:

Primitive SUBSET

Primitive SUBSET is a polymorphic primitive to test whether a set is a subset of another. It has one signature:

 PROCEDURE SUBSET ( subset, superset : <SetType> ) : BOOLEAN;
2015-09-26 12:11 by trijezdci -
Added lines 1932-1949:

Primitive SEEK

Primitive SEEK is a polymorphic primitive to obtain accessors to list elements for list traversal. It has two signatures:

Obtaining An Element Accessor By Index
 PROCEDURE SEEK ( c : <ListType>; index : LONGCARD ) : <AccessorType> );
Obtaining An Element Accessor Through Neighbour
 PROCEDURE SEEK
   ( c : <ListType>; current : <AccessorType>; plusOrMinus : <CharLiteral> ) : <AccessorType> );
2015-09-26 11:07 by trijezdci -
Changed lines 1838-1839 from:

Primitive STORE is a polymorphic macro to overwrite one or more values in a collection. It has eight signatures:

to:

Primitive STORE is a polymorphic primitive to overwrite one or more values in a collection. It has eight signatures:

Added lines 1894-1932:

Primitive VALUE

Primitive VALUE is a polymorphic primitive to retrieve a value from a collection. It has five signatures:

Retrieving A Value From An Array
 PROCEDURE VALUE ( VAR c : <ArrayType>; atIndex : <IndexType> ) : <ValueType>;
Retrieving A Value From A List
 PROCEDURE VALUE ( VAR c : <ListType>; accessor : <AccessorType> ) : <ValueType>;
Retrieving A Counter From A Set
 PROCEDURE VALUE ( VAR c : <SetType>; element : <ElementType> ) : <CounterType>;
Retrieving A Value From A Dictionary
 PROCEDURE VALUE ( VAR c : <DictionaryType>; key : <KeyType> ) : <ValueType>;
Retrieving The N-th Value For A Key From A Multi-Dictionary
 PROCEDURE VALUE
   ( VAR c : <DictionaryType>; key : <KeyType>; index : CARDINAL ) : <ValueType>;
2015-09-26 10:50 by trijezdci -
Changed lines 1881-1882 from:
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
to:
Overwriting Multiple Key/Value Pairs In A Dictionary
Changed line 1885 from:
   ( c : <DictionaryType>; key : <KeyType>; index : CARDINAL; value : <ValueType> );
to:
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
Changed lines 1888-1889 from:
Overwriting Multiple Key/Value Pairs In A Dictionary
to:
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
Changed line 1892 from:
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
to:
   ( c : <DictionaryType>; key : <KeyType>; index : CARDINAL; value : <ValueType> );
2015-09-26 10:45 by trijezdci -
Changed line 1838 from:

Primitive STORE is a polymorphic macro to overwrite one or more values in a collection. It has X signatures:

to:

Primitive STORE is a polymorphic macro to overwrite one or more values in a collection. It has eight signatures:

2015-09-26 10:45 by trijezdci -
Changed line 1853 from:
Overwriting A Slice Or All Of An Array Or List With A Fill-Value
to:
Overwriting An Array Or List Or Part Thereof With A Fill-Value
2015-09-26 10:41 by trijezdci -
Changed lines 1840-1841 from:
Overwriting A Single Value In An Array
to:
Overwriting A Single Value In An Array Or List
Changed line 1843 from:
 PROCEDURE STORE ( c : <ArrayType>; atIndex : <IndexType>; value : <ValueType> );
to:
 PROCEDURE STORE ( c : <SeqType>; atIndex : <IndexType>; value : <ValueType> );
Changed lines 1846-1847 from:
Overwriting Multiple Values In An Array
to:
Overwriting Multiple Values In An Array Or List
Changed line 1850 from:
   ( c : <ArrayType>; fromIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
to:
   ( c : <SeqType>; fromIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
Changed lines 1853-1854 from:
Overwriting an Array or Array Slice With A Fill-Value
to:
Overwriting A Slice Or All Of An Array Or List With A Fill-Value
Changed line 1857 from:
   ( c : <ArrayType>; fromIndex : <IndexType>; valueCount : LONGCARD; fillValue : <ValueType> );
to:
   ( c : <SeqType>; fromIndex : <IndexType>; valueCount : LONGCARD; fillValue : <ValueType> );
Changed lines 1861-1862 from:
Overwriting The Element Count for A Single Element In A Set
to:
Overwriting The Element Counter for A Single Element In A Set
Changed line 1867 from:
Overwriting The Element Counts for Multiple Elements In A Set
to:
Overwriting The Element Counters for Multiple Elements In A Set
2015-09-26 10:31 by trijezdci -
Changed lines 1818-1819 from:

Primitive SXF is a polymorphic macro to serialise a scalar value given by its first operand to scalar exchange format and pass the serialised value back in its second operand. Its first operand shall be of a scalar type. Its second operand shall be an OCTET array large enough to hold the serialised value. It has one signature:

to:

Primitive SXF is a polymorphic primitive to serialise a scalar value given by its first operand to scalar exchange format and pass the serialised value back in its second operand. Its first operand shall be of a scalar type. Its second operand shall be an OCTET array large enough to hold the serialised value. It has one signature:

Changed lines 1828-1829 from:

Primitive VAL is a polymorphic macro to convert a serialised scalar value given by its first operand to a value of a scalar type and pass the converted value back in its second operand. Its first operand shall be an OCTET array. Its second operand shall be of the scalar target type. It has one signature:

to:

Primitive VAL is a polymorphic primitive to convert a serialised scalar value given by its first operand to a value of a scalar type and pass the converted value back in its second operand. Its first operand shall be an OCTET array. Its second operand shall be of the scalar target type. It has one signature:

Added lines 1834-1893:

Primitive STORE

Primitive STORE is a polymorphic macro to overwrite one or more values in a collection. It has X signatures:

Overwriting A Single Value In An Array
 PROCEDURE STORE ( c : <ArrayType>; atIndex : <IndexType>; value : <ValueType> );
Overwriting Multiple Values In An Array
 PROCEDURE STORE
   ( c : <ArrayType>; fromIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
Overwriting an Array or Array Slice With A Fill-Value
 PROCEDURE STORE
   ( c : <ArrayType>; fromIndex : <IndexType>; valueCount : LONGCARD; fillValue : <ValueType> );
Overwriting The Element Count for A Single Element In A Set
 PROCEDURE STORE ( c : <SetType>; element : <ElementType>; counter : <CounterType> );
Overwriting The Element Counts for Multiple Elements In A Set
 PROCEDURE STORE
   ( c : <SetType>; entries : ARGLIST >0 OF { element : <ElementType>; counter : <CounterType> } );
Overwriting A Key/Value Pair In A Dictionary
 PROCEDURE STORE ( c : <DictionaryType>; key : <KeyType>; value : <ValueType> );
Overwriting The N-th Key/Value Pair In A Multi-Dictionary
 PROCEDURE STORE
   ( c : <DictionaryType>; key : <KeyType>; index : CARDINAL; value : <ValueType> );
Overwriting Multiple Key/Value Pairs In A Dictionary
 PROCEDURE STORE
   ( c : <DictionaryType>; entries : ARGLIST >1 OF { key : <KeyType >; value : <ValueType> );
2015-09-26 08:33 by trijezdci -
Changed lines 1806-1807 from:

Primitives are built-in polymorphic macros for internal use by the compiler to synthesise various operations for library defined AD Ts?. They should not need to be invoked directly by library or program code since their functionality becomes available through built-in syntax. Library implementations of AD Ts? may be required to provide specific implementations and bind them to their respective primitives.

to:

Primitives are built-in polymorphic macros for internal use by the compiler to synthesise various operations for library defined ADTs. They should not need to be invoked directly by library or program code since their functionality becomes available through built-in syntax. Library implementations of ADTs may be required to provide specific implementations and bind them to their respective primitives.

Added lines 1814-1832:

Primitive SXF

Primitive SXF is a polymorphic macro to serialise a scalar value given by its first operand to scalar exchange format and pass the serialised value back in its second operand. Its first operand shall be of a scalar type. Its second operand shall be an OCTET array large enough to hold the serialised value. It has one signature:

 PROCEDURE SXF ( CONST value : <ScalarType>; VAR sxfValue : ARRAY OF OCTET );

Primitive VAL

Primitive VAL is a polymorphic macro to convert a serialised scalar value given by its first operand to a value of a scalar type and pass the converted value back in its second operand. Its first operand shall be an OCTET array. Its second operand shall be of the scalar target type. It has one signature:

 PROCEDURE VAL ( CONST sxfValue : ARRAY OF OCTET; VAR value : <ScalarType> );
2015-09-26 08:14 by trijezdci -
Changed lines 135-142 from:
to:
Added lines 1802-1816:

Primitives

Primitives are built-in polymorphic macros for internal use by the compiler to synthesise various operations for library defined AD Ts?. They should not need to be invoked directly by library or program code since their functionality becomes available through built-in syntax. Library implementations of AD Ts? may be required to provide specific implementations and bind them to their respective primitives.

  • Primitive SXF
  • Primitive VAL
  • Primitive STORE
  • Primitive VALUE
  • Primitive SEEK
  • Primitive SUBSET

2015-09-26 07:40 by trijezdci -
Changed lines 1726-1727 from:

An Invocation of TMIN is replaced by the smallest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. The type of its replacement value is of the type denoted by its operand. It has one signature:

to:

An Invocation of TMIN is replaced by the smallest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. Its replacement value is of the type denoted by its operand. It has one signature:

Changed lines 1736-1737 from:

An Invocation of TAMX is replaced by the largest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. The type of its replacement value is of the type denoted by its operand. It has one signature:

to:

An Invocation of TAMX is replaced by the largest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. Its replacement value is of the type denoted by its operand. It has one signature:

Changed line 1746 from:

An Invocation of TLIMIT is replaced by the capacity limit of its operand. Its operand shall be the type identifier of a collection type. The type of its replacement value is type LONGCARD. It has one signature:

to:

An Invocation of TLIMIT is replaced by the capacity limit of its operand. Its operand shall be the type identifier of a collection type. Its replacement value is of type LONGCARD. It has one signature:

2015-09-26 07:25 by trijezdci -
Changed line 1546 from:

Function ABS is a polymorphic function to return the absolute value of its operand. Unlike the mathematical definition of abs(x), the ABS function is strictly limited to scalar operands. Its operand shall be of a scalar type. Its return type is the operand type. It has one signature:

to:

Function ABS is a polymorphic function to return the absolute value of its operand. Unlike the mathematical definition of abs(x), the ABS function is strictly limited to scalar operands. Its operand shall be of a scalar type. Its return type is the operand type. It has one signature:

2015-09-26 07:24 by trijezdci -
Changed lines 1546-1547 from:

Function ABS is a polymorphic function to return the absolute value of its operand. It is strictly limited to scalar operands. Its operand shall be of a scalar or ordinal type. Its return type is the operand type. It has one signature:

to:

Function ABS is a polymorphic function to return the absolute value of its operand. Unlike the mathematical definition of abs(x), the ABS function is strictly limited to scalar operands. Its operand shall be of a scalar type. Its return type is the operand type. It has one signature:

Changed line 1549 from:
 PROCEDURE ABS ( value : <ScalarOrOrdinalType> ) : <OperandType>;
to:
 PROCEDURE ABS ( value : <ScalarType> ) : <OperandType>;
2015-09-26 07:20 by trijezdci -
Changed line 1546 from:

Function ABS is a polymorphic function to return the absolute value of its operand. Its operand shall be of a scalar or ordinal type. Its return type is the operand type. It has one signature:

to:

Function ABS is a polymorphic function to return the absolute value of its operand. It is strictly limited to scalar operands. Its operand shall be of a scalar or ordinal type. Its return type is the operand type. It has one signature:

2015-09-26 07:15 by trijezdci -
Changed lines 1664-1665 from:

Function LENGTH is a polymorphic function to return the number of values stored in a character string. It has one signature:

to:

Function COUNT is a polymorphic function to return the number of characters stored in its operand. Its operand shall be of a CHAR or UNICHAR array type or a string ADT. Its return type is type LONGCARD. It has one signature:

Changed lines 1674-1675 from:

Function PTR is a polymorphic function to return a typed pointer to a variable provided its type is compatible with the target type of a passed in pointer type. It has one signature:

to:

Function PTR is a polymorphic function to return a typed pointer to its first operand. Its return type is given by its second operand. Its first operand shall be a variable of arbitrary type. Its second operand shall be a pointer type whose target type is the type of the first operand. If the first operand is immutable within the scope where PTR is invoked, the second operand shall be a pointer type with immutable target. Otherwise, the second operand may be a pointer type with mutable or immutable target. The function has one signature:

Changed line 1677 from:
 PROCEDURE PTR ( v : <AnyType>; T : <PointerType> ) : <T>;
to:
 PROCEDURE PTR ( v : <AnyType>; T : <TypeIdentifier> ) : <T>;
Changed lines 1684-1685 from:

Function FIRST is a polymorphic function to return the first value of an ordered collection. It has one signature:

to:

Function FIRST is a polymorphic function to return the first value of its operand. Its operand shall be of an ordered collection type. Its return type is the value type of the type of the first operand. It has one signature:

Changed line 1687 from:
 PROCEDURE FIRST ( c : <CollectionType> ) : <ValueType>;
to:
 PROCEDURE FIRST ( c : <OrderedCollectionType> ) : <ValueType>;
Changed lines 1694-1695 from:

Function LAST is a polymorphic function to return the last value of an ordered collection. It has one signature:

to:

Function LAST is a polymorphic function to return the last value of its operand. Its operand shall be of an ordered collection type. Its return type is the value type of the type of the first operand. It has one signature:

Changed line 1697 from:
 PROCEDURE LAST ( c : <CollectionType> ) : <ValueType>;
to:
 PROCEDURE LAST ( c : <OrderedCollectionType> ) : <ValueType>;
Changed lines 1704-1705 from:

Function MIN is a polymorphic function to return the smallest value from a list of scalar or ordinal values. It has one signature:

to:

Function MIN is a polymorphic function to return the smallest value from a non-empty variadic list of operands. All its operands shall be of the same type. The operand type shall be a scalar or ordinal type. Its return type is the operand type. It has one signature:

Changed lines 1713-1714 from:

Function MAX is a polymorphic function to return the largest value from a list of scalar or ordinal values. It has one signature:

to:

Function MAX is a polymorphic function to return the largest value from a non-empty variadic list of operands. All its operands shall be of the same type. The operand type shall be a scalar or ordinal type. Its return type is the operand type. It has one signature:

Changed lines 1726-1727 from:

An Invocation of TMIN is replaced by the smallest legal value of a scalar or ordinal type given as its argument. It has one signature:

to:

An Invocation of TMIN is replaced by the smallest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. The type of its replacement value is of the type denoted by its operand. It has one signature:

Changed lines 1736-1737 from:

An Invocation of TMAX is replaced by the largest legal value of a scalar or ordinal type given as its argument. It has one signature:

to:

An Invocation of TAMX is replaced by the largest legal value of its operand. Its operand shall be the type identifier of a scalar or ordinal type. The type of its replacement value is of the type denoted by its operand. It has one signature:

Changed lines 1746-1747 from:

An Invocation of TLIMIT is replaced by the capacity limit of the collection type given as its argument. It has one signature:

to:

An Invocation of TLIMIT is replaced by the capacity limit of its operand. Its operand shall be the type identifier of a collection type. The type of its replacement value is type LONGCARD. It has one signature:

Changed line 1756 from:

An Invocation of TSIZE is replaced by the allocation size required for an instance of the type given as its argument. It has one signature:

to:

An Invocation of TSIZE is replaced by the allocation size required for an instance of a type denoted by its operand. Its operand shall be any type identifier. Its replacement value is of type LONGCARD. It has one signature:

2015-09-26 04:05 by trijezdci -
Changed lines 1546-1547 from:

Function ABS is a polymorphic function to return the absolute value of a scalar or ordinal value. It has one signature:

to:

Function ABS is a polymorphic function to return the absolute value of its operand. Its operand shall be of a scalar or ordinal type. Its return type is the operand type. It has one signature:

Changed lines 1556-1557 from:

Function ODD is a polymorphic function to test whether a given whole number value is odd. It returns TRUE if it is, otherwise FALSE. It has one signature:

to:

Function ODD is a polymorphic function to test whether its operand is odd. Its operand shall be of a whole number type. Its return type is BOOLEAN. It returns TRUE if its operand is odd, otherwise FALSE. It has one signature:

Changed lines 1566-1567 from:

Function PRED is a polymorphic function to return the n-th predecessor of an ordinal value. It has two signatures:

to:

Function PRED is a polymorphic function to return the n-th predecessor of its first operand, where n is the second operand, or one if it is omitted. Its first operand shall be of an ordinal type. Its second operand is of type CARDINAL. Its return type is the first operand type. It has two signatures:

Changed lines 1584-1585 from:

Function SUCC is a polymorphic function to return the n-th successor of an ordinal value. It has two signatures:

to:

Function SUCC is a polymorphic function to return the n-th successor of its first operand, where n is the second operand, or one if it is omitted. Its first operand shall be of an ordinal type. Its second operand is of type CARDINAL. Its return type is the first operand type. It has two signatures:

Changed lines 1602-1603 from:

Function ORD is a polymorphic function to return the ordinal value of a character or enumerated value. It has one signature:

to:

Function ORD is a polymorphic function to return the ordinal value of its operand. Its operand shall be of type CHAR or any enumeration type. Its return type is type CARDINAL. It has one signature:

Changed lines 1612-1613 from:

Function CHR is a polymorphic function to return the character whose code point matches its parameter. It has one signature:

to:

Function CHR is a polymorphic function to return the character for the code point given by its operand. Its operand shall be of type OCTET or CARDINAL or LONGCARD. If the value of the operand is less than 128 then its return type is CHAR, otherwise it is UNICHAR. It has one signature:

Changed lines 1622-1623 from:

Function EXISTS is a polymorphic function to test whether a given value for a given key is already present in a dictionary. It returns TRUE if the value is present, otherwise FALSE. It has one signature:

to:

Function EXISTS is a polymorphic function to test the presence of a key/value pair in a dictionary. It has three operands. Its first operand is the dictionary to be tested and it shall be of a dictionary ADT. Its second and third operands are the key and value respectively, and they shall be of the dictionary ADT's key and value types, respectively. The function returns TRUE if the key/value pair is present, otherwise FALSE. Its return type is type BOOLEAN.

 It returns TRUE if the value is present, otherwise FALSE. It has one signature:
Changed lines 1634-1635 from:

Function COUNT is a polymorphic function to return the number of values stored in a collection. It has two signatures:

to:

Function COUNT is a polymorphic function to return the number of values stored in its operand or the number of actual parameters passed in a formal parameter denoted by its operand. Its return type is type LONGCARD. It has three signatures:

Added lines 1638-1639:

To obtain the number of values stored in a collection, the function is called passing the collection as a single operand. The operand shall be of a collection type.

Added lines 1646-1647:

To obtain the number of values stored for a given key in a multi-dictionary, the function is called passing the dictionary as its first operand and the key as its second operand. The first operand shall be of a dictionary ADT. The second operand shall be of the dictionary's key type.

Added lines 1650-1657:
Number Of Arguments Passed To A Variadic Parameter

To obtain the number of actual parameters passed to a variadic parameter list within the body of a variadic procedure, the function is called passing the designator of the variadic parameter list.

 PROCEDURE COUNT ( designator : <VariadicFormalParameter> ) : LONGCARD;
2015-09-25 18:02 by trijezdci -
Added lines 1233-1242:

Constant EMPTY

The constant EMPTY represents an empty collection literal. It is compatible with any collection type. Its value is defined as:

CONST EMPTY = { } | "";

2015-09-25 17:51 by trijezdci -
Changed line 2 from:

Status: 2015-09-25

to:

Status: 2015-09-25 (update in progress)

2015-09-25 17:50 by trijezdci -
Changed lines 1-2 from:

Copyright © 2010-2015 B.Kowarsch & R.Sutcliffe. All rights reserved. Reproduction requires written permission.

to:

Copyright © 2010-2015 B.Kowarsch & R.Sutcliffe. All rights reserved. Reproduction requires written permission.

2015-09-25 17:50 by trijezdci -
Added line 2:
2015-09-25 17:49 by trijezdci -
Added line 1:

Copyright © 2010-2015 B.Kowarsch & R.Sutcliffe. All rights reserved. Reproduction requires written permission.

2015-09-25 17:47 by trijezdci -
Added lines 1-2:

Status: 2015-09-25

2015-09-25 17:41 by trijezdci -
Changed line 37 from:
to:
2015-09-25 17:40 by trijezdci -
Changed lines 35-52 from:
to:
Changed lines 56-76 from:
to:
2015-09-25 17:10 by trijezdci -
Changed line 26 from:
to:
2015-09-25 17:08 by trijezdci -
Changed line 1 from:

Lexis

to:

Lexis

Changed lines 5-8 from:
to:
Added lines 26-48:
Added line 367:

Added line 402:

Added line 413:

Added line 423:

Added line 442:

Added line 452:

Added line 462:

Added line 472:

Added line 477:

Added line 487:

Added line 505:

Added line 525:

Added line 537:

Added line 549:

Added line 566:

Added line 681:

Added line 694:

Added line 710:

Added line 726:

Added line 766:

Added line 779:

Added line 792:

Added line 804:

Changed lines 817-818 from:
The Slash Operator
to:

The Solidus Operator
Added line 830:

Added line 842:

Added line 854:

Added line 866:

Added line 878:

Added line 909:

Added line 939:

Added line 951:

Added line 963:

Added line 975:

Added line 987:

Added line 1000:

Added line 1013:

Added line 1026:

Added line 1039:

Added line 1051:

Added line 1063:

2015-09-25 16:47 by trijezdci -
Changed line 11 from:
to:
2015-09-25 16:45 by trijezdci -
Changed lines 2-15 from:
Character Encoding
Lexical Entities

(To do: move and merge content)

Scope
Types
Predefined Identifiers

(To do: enter from PDF version and update)

to:
Changed lines 6-18 from:
Compilation Units

EBNF | Syntax Diagram

to do

Import of Identifiers

EBNF | Syntax Diagram

to do

to:
Changed lines 25-29 from:
Definition Modules

EBNF | Syntax Diagram

to:

(To do: move and merge content)

Scope
Types
Predefined Identifiers

(To do: enter from PDF version and update)

Semantics

Compilation Units

EBNF | Syntax Diagram

Changed lines 44-49 from:
Definitions

EBNF | Syntax Diagram

Constant Definitions
to:

Import of Identifiers

EBNF | Syntax Diagram

Changed lines 51-52 from:
Variable Declarations
to:

Definition Modules

EBNF | Syntax Diagram

Added lines 60-74:
Definitions

EBNF | Syntax Diagram

Constant Definitions

to do

Variable Declarations

to do

Added line 96:

Added line 101:

Added line 120:

Added line 125:

Added line 157:

Changed line 179 from:

to:

Added line 243:

Added line 277:

Added line 315:

Added line 327:

Changed line 1386 from:
 PROCEDURE ABS ( value : <ScalarOrOrdinalType> ) : <Operand Type?>;
to:
 PROCEDURE ABS ( value : <ScalarOrOrdinalType> ) : <OperandType>;
Changed line 1408 from:
 PROCEDURE PRED ( value : <OrdinalType> ) : <Operand Type?>;
to:
 PROCEDURE PRED ( value : <OrdinalType> ) : <OperandType>;
Changed line 1414 from:
 PROCEDURE PRED ( value : <OrdinalType>; n : CARDINAL ) : <Operand Type?>;
to:
 PROCEDURE PRED ( value : <OrdinalType>; n : CARDINAL ) : <OperandType>;
Changed line 1426 from:
 PROCEDURE SUCC ( value : <OrdinalType> ) : <Operand Type?>;
to:
 PROCEDURE SUCC ( value : <OrdinalType> ) : <OperandType>;
Changed line 1432 from:
 PROCEDURE SUCC ( value : <OrdinalType>; n : CARDINAL ) : <Operand Type?>;
to:
 PROCEDURE SUCC ( value : <OrdinalType>; n : CARDINAL ) : <OperandType>;
Changed line 1452 from:
 PROCEDURE CHR ( codePoint : <OctetOrCardinalOrLongcard> ) : <Char Or Unichar?>;
to:
 PROCEDURE CHR ( codePoint : <OctetOrCardinalOrLongcard> ) : <CharOrUnichar>;
2015-09-25 16:29 by trijezdci -
Changed line 1336 from:

Procedure TODO is a dummy procedure to indicate unimplemented code. It causes a compile time warning when compiling in DEBUG mode, otherwise it causes a compile time error, either way printing a user defined message. It has one signature:

to:

Procedure TODO is a dummy procedure to indicate unimplemented code. It causes a compile time warning when compiling in DEBUG mode, otherwise it causes a compile time error, either way printing a user defined compile time message. It has one signature:

2015-09-25 15:41 by trijezdci -
Changed line 1545 from:

An Invocation of TSIZZE is replaced by the allocation size required for an instance of the type given as its argument. It has one signature:

to:

An Invocation of TSIZE is replaced by the allocation size required for an instance of the type given as its argument. It has one signature:

2015-09-25 15:39 by trijezdci -
Added lines 1349-1355:

Function ABS is a polymorphic function to return the absolute value of a scalar or ordinal value. It has one signature:

 PROCEDURE ABS ( value : <ScalarOrOrdinalType> ) : <Operand Type?>;
Added lines 1359-1365:

Function ODD is a polymorphic function to test whether a given whole number value is odd. It returns TRUE if it is, otherwise FALSE. It has one signature:

 PROCEDURE ODD ( value : <WholeNumberType> ) : BOOLEAN;
Added lines 1369-1383:

Function PRED is a polymorphic function to return the n-th predecessor of an ordinal value. It has two signatures:

Decrement Value One
 PROCEDURE PRED ( value : <OrdinalType> ) : <Operand Type?>;
Arbitrary Decrement Value
 PROCEDURE PRED ( value : <OrdinalType>; n : CARDINAL ) : <Operand Type?>;
Added lines 1387-1401:

Function SUCC is a polymorphic function to return the n-th successor of an ordinal value. It has two signatures:

Increment Value One
 PROCEDURE SUCC ( value : <OrdinalType> ) : <Operand Type?>;
Arbitrary Increment Value
 PROCEDURE SUCC ( value : <OrdinalType>; n : CARDINAL ) : <Operand Type?>;
Added lines 1405-1411:

Function ORD is a polymorphic function to return the ordinal value of a character or enumerated value. It has one signature:

 PROCEDURE ORD ( value : <CharOrEnumType> ) : CARDINAL;
Added lines 1415-1421:

Function CHR is a polymorphic function to return the character whose code point matches its parameter. It has one signature:

 PROCEDURE CHR ( codePoint : <OctetOrCardinalOrLongcard> ) : <Char Or Unichar?>;
Added lines 1425-1431:

Function EXISTS is a polymorphic function to test whether a given value for a given key is already present in a dictionary. It returns TRUE if the value is present, otherwise FALSE. It has one signature:

 PROCEDURE EXISTS ( dict : <DictionaryType>; key : <KeyType>; value : <ValueType> ) : BOOLEAN;
Added lines 1435-1449:

Function COUNT is a polymorphic function to return the number of values stored in a collection. It has two signatures:

Number Of Values Stored In a Collection
 PROCEDURE COUNT ( c : <CollectionType> ) : LONGCARD;
Number Of Values Stored For a Key In A Multi-Dictionary
 PROCEDURE COUNT ( c : <DictionaryType>; key : <KeyType> ) : LONGCARD;
Added lines 1453-1459:

Function LENGTH is a polymorphic function to return the number of values stored in a character string. It has one signature:

 PROCEDURE LENGTH ( s : <CharacterStringType> ) : LONGCARD;
Added lines 1463-1469:

Function PTR is a polymorphic function to return a typed pointer to a variable provided its type is compatible with the target type of a passed in pointer type. It has one signature:

 PROCEDURE PTR ( v : <AnyType>; T : <PointerType> ) : <T>;
Added lines 1473-1479:

Function FIRST is a polymorphic function to return the first value of an ordered collection. It has one signature:

 PROCEDURE FIRST ( c : <CollectionType> ) : <ValueType>;
Added lines 1483-1489:

Function LAST is a polymorphic function to return the last value of an ordered collection. It has one signature:

 PROCEDURE LAST ( c : <CollectionType> ) : <ValueType>;
Added lines 1493-1498:

Function MIN is a polymorphic function to return the smallest value from a list of scalar or ordinal values. It has one signature:

 PROCEDURE MIN ( values : ARGLIST >0 OF <ScalarOrOrdinalType> ) : <OperandType>;
Changed lines 1502-1508 from:
to:

Function MAX is a polymorphic function to return the largest value from a list of scalar or ordinal values. It has one signature:

 PROCEDURE MAX ( values : ARGLIST >0 OF <ScalarOrOrdinalType> ) : <OperandType>;
Added lines 1515-1521:

An Invocation of TMIN is replaced by the smallest legal value of a scalar or ordinal type given as its argument. It has one signature:

 PROCEDURE TMIN ( T : <ScalarOrOrdinalTypeIdentifier> ) : <T>;
Added lines 1525-1531:

An Invocation of TMAX is replaced by the largest legal value of a scalar or ordinal type given as its argument. It has one signature:

 PROCEDURE TMAX ( T : <ScalarOrOrdinalTypeIdentifier> ) : <T>;
Added lines 1535-1541:

An Invocation of TLIMIT is replaced by the capacity limit of the collection type given as its argument. It has one signature:

 PROCEDURE TLIMIT ( T : <CollectionTypeIdentifier> ) : LONGCARD;
Added lines 1544-1549:

An Invocation of TSIZZE is replaced by the allocation size required for an instance of the type given as its argument. It has one signature:

 PROCEDURE TSIZE ( T : <TypeIdentifier> ) : LONGCARD;
2015-09-25 14:53 by trijezdci -
Changed line 1339 from:
 PROCEDURE TODO ( msg : <String Literal?> );
to:
 PROCEDURE TODO ( msg : <StringLiteral> );
2015-09-25 14:51 by trijezdci -
Changed line 1225 from:
 PROCEDURE REMOVE ( VAR set : <SetType>; elements : ARGLIST OF <ElementType> );
to:
 PROCEDURE REMOVE ( VAR set : <SetType>; elements : ARGLIST >0 OF <ElementType> );
Added lines 1330-1339:

Procedure TODO

Procedure TODO is a dummy procedure to indicate unimplemented code. It causes a compile time warning when compiling in DEBUG mode, otherwise it causes a compile time error, either way printing a user defined message. It has one signature:

 PROCEDURE TODO ( msg : <String Literal?> );
2015-09-25 14:45 by trijezdci -
Changed line 1189 from:
 PROCEDURE INSERT ( VAR set : <SetType>; elements : ARGLIST OF <ElementType> );
to:
 PROCEDURE INSERT ( VAR set : <SetType>; elements : ARGLIST >0 OF <ElementType> );
Changed line 1195 from:
 PROCEDURE INSERT ( VAR dict : <DictType>; values : ARGLIST OF { key : <KeyType>; value : <ValueType> } );
to:
 PROCEDURE INSERT ( VAR dict : <DictType>; values : ARGLIST >0 OF { key : <KeyType>; value : <ValueType> } );
Changed line 1201 from:
 PROCEDURE INSERT ( VAR seq : <SeqType>; atIndex : <IndexType>; values : ARGLIST OF <ValueType> );
to:
 PROCEDURE INSERT ( VAR seq : <SeqType>; atIndex : <IndexType>; values : ARGLIST >0 OF <ValueType> );
Changed line 1213 from:
 PROCEDURE APPEND ( VAR seq : <SeqType>; values : ARGLIST OF <ValueType> );
to:
 PROCEDURE APPEND ( VAR seq : <SeqType>; values : ARGLIST >0 OF <ValueType> );
Changed line 1231 from:
 PROCEDURE REMOVE ( VAR dict : <DictType>; values : ARGLIST OF <KeyType> } );
to:
 PROCEDURE REMOVE ( VAR dict : <DictType>; values : ARGLIST >0 OF <KeyType> } );
Deleted line 1240:
Changed lines 1266-1267 from:
Reading From Std In?
to:
Reading From StdIn
Changed lines 1284-1285 from:
Reading From Std In?
to:
Reading From StdIn
Changed lines 1302-1303 from:
Writing To Std Out?
to:
Writing To StdOut
Changed lines 1320-1321 from:
Writing To Std Out?
to:
Writing To StdOut
Changed line 1323 from:
 PROCEDURE WRITEF ( CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST OF <SourceType> );
to:
 PROCEDURE WRITEF ( CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST >0 OF <SourceType> );
Changed line 1329 from:
 PROCEDURE WRITE ( f : FILE; CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST OF <SourceType> );
to:
 PROCEDURE WRITE ( f : FILE; CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST >0 OF <SourceType> );
2015-09-25 14:39 by trijezdci -
Changed lines 1184-1185 from:

Procedure INSERT is a polymorphic procedure to insert one or more values or key/value pairs into an instance of a collection type. It has four signatures:

to:

Procedure INSERT is a polymorphic procedure to insert one or more values or key/value pairs into an instance of a collection type. It has three signatures:

Changed lines 1192-1193 from:
Inserting Values Into A Collection By Index
to:
Inserting Key/Value Pairs Into A Dictionary
Changed line 1195 from:
 PROCEDURE INSERT ( VAR array : <ArrayType>; atIndex : <IndexType>; values : ARGLIST OF <ValueType> );
to:
 PROCEDURE INSERT ( VAR dict : <DictType>; values : ARGLIST OF { key : <KeyType>; value : <ValueType> } );
Changed lines 1198-1199 from:
Inserting Key/Value Pairs Into A Collection
to:
Inserting Values Into An Array Or List By Index
Changed line 1201 from:
 PROCEDURE INSERT ( VAR dict : <DictType>; values : ARGLIST OF { key : <KeyType>; value : <ValueType> } );
to:
 PROCEDURE INSERT ( VAR seq : <SeqType>; atIndex : <IndexType>; values : ARGLIST OF <ValueType> );
Deleted line 1204:
Added lines 1208-1216:

Procedure APPEND is a polymorphic procedure to append one or more values to an instance of a collection type. It has one signature:

Appending Values To An Array Or List
 PROCEDURE APPEND ( VAR seq : <SeqType>; values : ARGLIST OF <ValueType> );
Added lines 1220-1241:

Procedure REMOVE is a polymorphic procedure to remove one or more values or all values from an instance of a collection type. It has three signatures:

Removing Values From A Set
 PROCEDURE REMOVE ( VAR set : <SetType>; elements : ARGLIST OF <ElementType> );
Removing Key/Value Pairs From A Dictionary
 PROCEDURE REMOVE ( VAR dict : <DictType>; values : ARGLIST OF <KeyType> } );
Removing Values From An Array Or List By Index
 PROCEDURE REMOVE ( VAR seq : <SeqType>; startIndex, endIndex : <IndexType>;  );
Added lines 1245-1251:

Procedure SORT is a polymorphic procedure to sort the values of a collection and copy them into another. It has one signature:

 PROCEDURE SORT ( VAR target : <TargetCollectionType>; source : <SourceCollectionType>;  order : CHAR );
Added lines 1255-1261:

Procedure SORTNEW is a polymorphic procedure to initialise an immutable target collection with the sorted values of another collection. It has one signature:

 PROCEDURE SORTNEW ( NEW target : <TargetCollectionType>; source : <SourceCollectionType>;  order : CHAR );
Added lines 1265-1279:

Procedure READ is a polymorphic procedure to read a value from a file into a target. It has two signatures:

Reading From Std In?
 PROCEDURE READ ( VAR target : <TargetType> );
Reading From A Given File
 PROCEDURE READ ( f : FILE; VAR target : <TargetType> );
Added lines 1283-1297:

Procedure READNEW is a polymorphic procedure to initialise an immutable target with the contents of a file. It has two signatures:

Reading From Std In?
 PROCEDURE READNEW ( NEW target : <TargetType> );
Reading From A Given File
 PROCEDURE READNEW ( f : FILE; NEW target : <TargetType> );
Added lines 1301-1315:

Procedure WRITE is a polymorphic procedure to write a value to a file. It has two signatures:

Writing To Std Out?
 PROCEDURE WRITE ( CONST source : <SourceType> );
Writing To A Given File
 PROCEDURE WRITE ( f : FILE; CONST source : <SourceType> );
Added lines 1318-1331:

Procedure WRITEF is a polymorphic procedure for formatted writing of one or more values to a file. It has two signatures:

Writing To Std Out?
 PROCEDURE WRITEF ( CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST OF <SourceType> );
Writing To A Given File
 PROCEDURE WRITE ( f : FILE; CONST fmt : ARRAY OF CHAR; CONST source : ARGLIST OF <SourceType> );
2015-09-25 14:03 by trijezdci -
Changed line 1189 from:
 PROCEDURE INSERT ( VAR set : <Set Type>; elements : ARGLIST OF <Element Type?> );
to:
 PROCEDURE INSERT ( VAR set : <SetType>; elements : ARGLIST OF <ElementType> );
Changed line 1195 from:
 PROCEDURE INSERT ( VAR array : <Array Type>; atIndex : <Index Type?>; values : ARGLIST OF <Value Type?> );
to:
 PROCEDURE INSERT ( VAR array : <ArrayType>; atIndex : <IndexType>; values : ARGLIST OF <ValueType> );
Changed line 1201 from:
 PROCEDURE INSERT ( VAR dict : <Dict Type?>; values : ARGLIST OF { key : <Key Type?>; value : <Value Type?> } );
to:
 PROCEDURE INSERT ( VAR dict : <DictType>; values : ARGLIST OF { key : <KeyType>; value : <ValueType> } );
2015-09-25 14:02 by trijezdci -
Added lines 1183-1204:

Procedure INSERT is a polymorphic procedure to insert one or more values or key/value pairs into an instance of a collection type. It has four signatures:

Inserting Values Into A Set
 PROCEDURE INSERT ( VAR set : <Set Type>; elements : ARGLIST OF <Element Type?> );
Inserting Values Into A Collection By Index
 PROCEDURE INSERT ( VAR array : <Array Type>; atIndex : <Index Type?>; values : ARGLIST OF <Value Type?> );
Inserting Key/Value Pairs Into A Collection
 PROCEDURE INSERT ( VAR dict : <Dict Type?>; values : ARGLIST OF { key : <Key Type?>; value : <Value Type?> } );
2015-09-25 13:48 by trijezdci -
Added lines 1169-1268:

Predefined Procedures

Predefined procedures are built-in procedures that are bound to predefined identifiers visible in every scope without import.

A predefined procedure differs from a library defined procedure:

  • it does not have an address
  • it cannot be passed as a procedure parameter
  • it cannot be assigned to any procedure variable

Procedure INSERT

Procedure APPEND

Procedure REMOVE

Procedure SORT

Procedure SORTNEW

Procedure READ

Procedure READNEW

Procedure WRITE

Procedure WRITEF

Predefined Function Procedures

Function Procedure ABS

Function Procedure ODD

Function Procedure PRED

Function Procedure SUCC

Function Procedure ORD

Function Procedure CHR

Function Procedure EXISTS

Function Procedure COUNT

Function Procedure LENGTH

Function Procedure PTR

Function Procedure FIRST

Function Procedure LAST

Function Procedure MIN

Function Procedure MAX

Built-in Compile-Time Macros

Macro TMIN

Macro TMAX

Macro TLIMIT

Macro TSIZE
2015-09-25 13:31 by trijezdci -
Changed lines 1063-1064 from:

to:
Predefined Types
Changed line 1075 from:

TSIZE(BOOLEAN) = 1 (* one octet *)@]

to:

TSIZE(BOOLEAN) = 2 (* 2 octets *)@]

Changed lines 1096-1098 from:

TO DO

to:

Type UNICHAR is a container type for Unicode character values. Its size is always 32-bit. Type CHAR is upwards compatible with UNICHAR but the reverse is not the case. This restriction exists because every legal value of type CHAR is also a legal value of type UNICHAR but not every value of type UNICHAR is also a legal value of type CHAR.

Changed lines 1102-1103 from:

Type OCTET is an unsigned integer type that represents a storage unit of eight bits. The type is defined as:

to:

Type OCTET is an unsigned whole number type that represents a storage unit of eight bits. Its parameters are:

Changed line 1114 from:

Type CARDINAL is an unsigned integer type large enough to hold any value in the range 0 to 65535 and any value of type SYSTEM.WORD whichever is larger. The type is defined as:

to:

Type CARDINAL is an unsigned integer type large enough to hold any value in the range 0 to 65535 and any value of type SYSTEM.WORD whichever is larger. The type's parameters are:

2015-09-25 13:21 by trijezdci -
Changed lines 983-984 from:
Predefined Constants Summary
to:
Summary Of Predefined Constants
Changed line 990 from:
Predefined Types Summary
to:
Summary Of Predefined Types
Changed line 998 from:
Predefined Procedures Summary
to:
Summary Of Predefined Procedures
Changed line 1011 from:
Predefined Functions Summary
to:
Summary Of Predefined Functions
Changed line 1028 from:
Built-in Compile-Time Macros
to:
Summary Of Built-in Compile-Time Macros
Added lines 1033-1168:
Predefined Constants

Constant NIL

The constant NIL represents an invalid pointer. It is compatible with any pointer type. Its value is defined as:

CONST NIL = 0 :: POINTER TO CONST OCTET;

Dereferencing the constant NIL results in a compile time error. Dereferencing a pointer whose value is NIL results in a runtime error.

Constants TRUE and FALSE

The constants TRUE and FALSE represent the values of type BOOLEAN. Their values are defined as:

CONST TRUE = BOOLEAN.TRUE;
CONST FALSE = BOOLEAN.FALSE;

ORD(TRUE) = 0
ORD(FALSE) = 1

see also BOOLEAN


Type BOOLEAN

Type BOOLEAN is an ordinal type for boolean algebra. All boolean expressions evaluate to type BOOLEAN. It is defined as:

TYPE BOOLEAN = ( TRUE, FALSE );

TMIN(BOOLEAN) = BOOLEAN.TRUE
TMAX(BOOLEAN) = BOOLEAN.FALSE
TSIZE(BOOLEAN) = 1 (* one octet *)

Type CHAR

Type CHAR is an ordinal type for 7-bit character values. It is defined as:

TYPE CHAR = ( CHR(0) .. CHR(127) );

TMIN(CHAR) = CHR(0)
TMAX(CHAR) = CHR(127)
TSIZE(CHAR) = 1 (* 1 octet *)

Type UNICHAR

TO DO

Type OCTET

Type OCTET is an unsigned integer type that represents a storage unit of eight bits. The type is defined as:

TMIN(OCTET) = 0
TMAX(OCTET) = 255
TSIZE(OCTET) = 1 (* one octet, eight bits by definition *)

Type CARDINAL

Type CARDINAL is an unsigned integer type large enough to hold any value in the range 0 to 65535 and any value of type SYSTEM.WORD whichever is larger. The type is defined as:

TMIN(CARDINAL) = 0
TMAX(CARDINAL) = pow(2, TSIZE(CARDINAL) * 8) - 1
TSIZE(CARDINAL) >= MAX(TSIZE(OCTET) * 2, TSIZE(WORD))

Type LONGCARD

Type LONGCARD is an unsigned integer type large enough to hold the size of the largest allocatable storage area measured in octets. The type is defined as:

TMIN(LONGCARD) = 0
TMAX(LONGCARD) = pow(2, TSIZE(LONGCARD) * 8) - 1
TSIZE(LONGCARD) >= (TSIZE(ADDRESS) DIV 8)

Type INTEGER

Type INTEGER is a signed integer type large enough to hold any value in the range -32768 to 32767 and any value of type SYSTEM.WORD whichever is larger. The type is defined as:

TMIN(INTEGER) = (pow(2, TSIZE(INTEGER) * 8) DIV 2) * (-1)
TMAX(INTEGER) = (pow(2, TSIZE(INTEGER) * 8) DIV 2) - 1
TSIZE(INTEGER) = TSIZE(CARDINAL)

Type LONGINT

Type LONGINT is a signed integer type large enough to hold the size of the largest allocatable storage area measured in octets. The type is defined as:

TMIN(LONGINT) = (pow(2, TSIZE(LONGINT) * 8) DIV 2) * (-1)
TMAX(LONGINT) = (pow(2, TSIZE(LONGINT) * 8) DIV 2) - 1
TSIZE(LONGINT) = TSIZE(LONGCARD)

Type REAL

TO DO

Type LONGREAL

TO DO

2015-09-25 13:16 by trijezdci -
Added lines 30-31:

Added lines 306-307:

Added lines 647-648:

Added lines 969-970:

2015-09-25 13:14 by trijezdci -
Changed lines 992-993 from:

APPEND(c, v1, v2, v3) appends values to the end of list or array collection c
REMOVE(c, ...) removes values or key/value pairs from collection c

to:

APPEND(c, v1, v2, v3) appends values to the end of list or array collection c
REMOVE(c, ...) removes values or key/value pairs from collection c

Changed line 995 from:

SORTNEW(t, s, order) sorts values of source collection s into newly allocated target collection t

to:

SORTNEW(t, s, order) sorts values of source collection s into newly allocated target collection t

Changed line 999 from:

WRITEF(f, fmtStr, x, ...) writes x formatted to file or channel f

to:

WRITEF(f, fmtStr, x, ...) writes one or more values formatted to file or channel f

2015-09-25 13:12 by trijezdci -
Added line 964:

2015-09-25 13:11 by trijezdci -
Changed lines 995-998 from:

READ(f, x) invokes TypeOf(x).Read(f, x)
READNEW(f, x) invokes TypeOf(x).Read(f, x)
WRITE(f, x) invokes TypeOf(x).Write(f, x)
WRITEF(f, fmtStr, x, ...) invokes TypeOf(x).WriteF(f, fmtStr, x, ...)

to:

READ(f, x) reads value from file or channel f into x
READNEW(f, x) reads value from file or channel f into newly allocated x
WRITE(f, x) writes x unformatted to file or channel f
WRITEF(f, fmtStr, x, ...) writes x formatted to file or channel f

Deleted lines 999-1000:

where TypeOf(x) means the identifier of type x.

2015-09-25 13:08 by trijezdci -
Added lines 963-1029:
Predefined Identifiers

Predefined identifiers are language defined identifiers that are visible in any lexical scope without import. There are five kinds:

Predefined Constants Summary

Invalid pointer value: NIL
Empty collection value: EMPTY
Boolean truth values: TRUE, FALSE

Predefined Types Summary

Boolean type: BOOLEAN
Character types: CHAR, UNICHAR
Unsigned whole number types: OCTET, CARDINAL, LONGCARD
Signed whole number types: INTEGER, LONGINT
Real number types: REAL, LONGREAL

Predefined Procedures Summary

INSERT(c, ...) inserts values or accessor/value pairs into collection c
APPEND(c, v1, v2, v3) appends values to the end of list or array collection c
REMOVE(c, ...) removes values or key/value pairs from collection c
SORT(t, s, order) sorts values of source collection s into target collection t
SORTNEW(t, s, order) sorts values of source collection s into newly allocated target collection t
READ(f, x) invokes TypeOf(x).Read(f, x)
READNEW(f, x) invokes TypeOf(x).Read(f, x)
WRITE(f, x) invokes TypeOf(x).Write(f, x)
WRITEF(f, fmtStr, x, ...) invokes TypeOf(x).WriteF(f, fmtStr, x, ...)
TODO(str) prints str to console, causes warning in DEBUG mode, or error otherwise

where TypeOf(x) means the identifier of type x.

Predefined Functions Summary

ABS(x) returns the absolute value of x
ODD(x) returns TRUE if x is an odd number
PRED(x, n) returns n-th predecessor of x
SUCC(x, n) returns n-th successor of x
ORD(x) returns the ordinal value of x
CHR(x) returns the character for codepoint x
EXISTS(c, a, v) returns TRUE if value v exists for accessor a in collection c
COUNT(c) returns the number of values stored in collection c
LENGTH(s) returns length of character string s
PTR(v, T) returns typed pointer to variable v if its type is compatible with T
FIRST(c) returns first value of ordered collection c
LAST(c) returns last value of ordered collection c
MIN(v1, v2, v3 ...) returns smallest value of a list of ordinal or scalar values
MAX(v1, v2, v3 ...) returns largest value of a list of ordinal or scalar values

Built-in Compile-Time Macros

TMIN(T) replaced by smallest legal value of type T
TMAX(T) replaced by largest legal value of type T
TLIMIT(T) replaced by the capacity of collection type T
TSIZE(T) replaced by allocation size required for type T


2015-09-24 17:45 by trijezdci -
Changed line 285 from:

A coroutine type is a special purpose pointer type whose target is a coroutine procedure. An associated procedure type is part of the type definition. A procedure is compatible with a coroutine type when it matches the signature of the type's associated procedure type. Coroutine types are defined using the COROUTINE type constructor.

to:

A coroutine type is a special purpose pointer type whose target is a coroutine. An associated procedure type is part of the type definition. A coroutine procedure is compatible with a coroutine type when it matches the signature of the type's associated procedure type. Coroutine types are defined using the COROUTINE type constructor.

2015-09-24 17:43 by trijezdci -
Changed line 289 from:
 TYPE Iterator = COROUTINE ( Iterator Proc? );
to:
 TYPE Iterator = COROUTINE ( IteratorProc );
2015-09-24 17:41 by trijezdci -
Changed lines 285-290 from:

to do

to:

A coroutine type is a special purpose pointer type whose target is a coroutine procedure. An associated procedure type is part of the type definition. A procedure is compatible with a coroutine type when it matches the signature of the type's associated procedure type. Coroutine types are defined using the COROUTINE type constructor.

Examples:

 TYPE Iterator = COROUTINE ( Iterator Proc? );
2015-09-24 17:37 by trijezdci -
Changed lines 291-297 from:

to do

to:

A procedure type is a special purpose pointer type whose target is a procedure. The procedure's signature is part of the type definition. A procedure is compatible with a procedure type when their signatures match. Procedure types are defined using the PROCEDURE type constructor.

Examples:

 TYPE WriteStrProc = PROCEDURE ( CONST ARRAY OF CHAR );
 TYPE FSM = PROCEDURE ( CONST ARRAY OF CHAR, FSM );
2015-09-24 17:18 by trijezdci -
Changed line 171 from:

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it must not be zero.

to:

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it may not be zero.

2015-09-24 17:06 by trijezdci -
Changed line 147 from:
to:

2015-09-24 17:05 by trijezdci -
Added line 147:
2015-09-24 17:02 by trijezdci -
Changed lines 204-205 from:
 TYPE `String = ARRAY 100 OF CHAR; (* compile time error *)
 TYPE `String = ARRAY < 100 OF CHAR; (* supported definition *)
to:
 TYPE String = ARRAY 100 OF CHAR; (* compile time error: unsupported definition *)
 TYPE String = ARRAY < 100 OF CHAR; (* OK, supported character array type definition *)
2015-09-24 17:01 by trijezdci -
Changed lines 200-208 from:

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every assign, append and concatenation operation.

to:

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. An attempt to define a rigid character array type shall cause a compile time error.

Examples:

 TYPE `String = ARRAY 100 OF CHAR; (* compile time error *)
 TYPE `String = ARRAY < 100 OF CHAR; (* supported definition *)

The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every assign, append and concatenation operation.

2015-09-24 16:55 by trijezdci -
Changed line 170 from:

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it must not be zero.

to:

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it must not be zero.

2015-09-24 16:51 by trijezdci -
Changed line 200 from:

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every append and concatenation operation.

to:

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every assign, append and concatenation operation.

2015-09-24 16:45 by trijezdci -
Changed lines 198-199 from:
to:
Character Arrays

For security reasons, array types with value types CHAR and UNICHAR may only be defined as flexible array types. Rigid character array types are not supported. The instances of character array types are initialised with a single NUL character and compliant implementations must ensure that they are NUL terminated after every append and concatenation operation.

2015-09-24 16:30 by trijezdci -
Changed line 188 from:

Instances of flexible arrays may further be sliced and concatenated. Flexible array types are slice and concatenation compatible as long as their value types are compatible.

to:

Instances of flexible arrays may further be sliced and concatenated. Flexible array types and their slices are insertion and concatenation compatible as long as the respective value types are compatible.

2015-09-24 16:28 by trijezdci -
Changed line 195 from:
 array1[4..6] := { 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
to:
 array1[4..5] := { 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
2015-09-24 16:28 by trijezdci -
Changed lines 193-195 from:
 array2 := { 1, 2, 3, 4 }; array3 := { 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 4, 8, 9 } *)
 array1[4..6] := { 5, 6, 7 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
to:
 array2 := { 1, 2, 3, 4 }; array3 := { 7, 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 4, 7, 8, 9 } *)
 array1[4..6] := { 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
2015-09-24 16:27 by trijezdci -
Changed lines 193-195 from:
 array2 := { 1, 2, 3 }; array3 := { 7, 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 7, 8, 9 } *)
 array1[3..5] := { 4, 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
to:
 array2 := { 1, 2, 3, 4 }; array3 := { 8, 9 };
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 4, 8, 9 } *)
 array1[4..6] := { 5, 6, 7 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
2015-09-24 16:25 by trijezdci -
Changed lines 194-195 from:
 array1 := array2 & array3; (* concatenation results in { 1, 2, 3, 7, 8, 9 } *)
 array1[3..5] := { 4, 5, 6 }; (* sliced insertion results in { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
to:
 array1 := array2 & array3; (* concatenation : { 1, 2, 3, 7, 8, 9 } *)
 array1[3..5] := { 4, 5, 6 }; (* sliced insert : { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
2015-09-24 16:24 by trijezdci -
Changed lines 170-171 from:

An array type may be defined either rigid or flexible. The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be added, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be added, inserted and removed at runtime. A flexible array is defined by prefixing the value count parameter in the type definition with the < symbol.

to:

An array type may be defined to hold a variable number of values by prefixing the value count parameter in the type's definition with the < symbol. The type's capacity is one less than the specified value count and it must not be zero.

Added lines 176-199:

The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be appended, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be appended, inserted and removed at runtime.

Examples:

 VAR array : FlexArray;
 array := { 42, -5, 0 }; (* initialise with three values *)
 APPEND(array, -35); (* append a value *)
 INSERT(array, 0, 11); (* value insertion *)
 REMOVE(array, 3, 1); (* value removal *)

Instances of flexible arrays may further be sliced and concatenated. Flexible array types are slice and concatenation compatible as long as their value types are compatible.

Examples:

 VAR array1, array2, array3 : FlexArray;
 array2 := { 1, 2, 3 }; array3 := { 7, 8, 9 };
 array1 := array2 & array3; (* concatenation results in { 1, 2, 3, 7, 8, 9 } *)
 array1[3..5] := { 4, 5, 6 }; (* sliced insertion results in { 1, 2, 3, 4, 5, 6, 7, 8, 9 } *)
2015-09-24 15:56 by trijezdci -
Changed lines 168-170 from:

An array type is defined to be rigid or flexible. The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be added, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be added, inserted and removed at runtime. A flexible array is defined with an upper open bound by prefixing the value count parameter in the type definition with the < symbol.

to:
Flexible Array Types

An array type may be defined either rigid or flexible. The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be added, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be added, inserted and removed at runtime. A flexible array is defined by prefixing the value count parameter in the type definition with the < symbol.

2015-09-24 15:53 by trijezdci -
Changed lines 151-152 from:

An array type is an indexed collection type whose values are of a single arbitrary type, called the array's value type. The type's capacity is specified by a value count parameter in the type definition. The capacity must be whole number value and it may not be zero. Array types are defined using the ARRAY OF type constructor.

to:

An array type is an indexed collection type whose values are of a single arbitrary type, called the array's value type. The type's capacity is specified by a value count parameter in the type definition. The capacity must be a whole number value and it may not be zero. Array types are defined using the ARRAY OF type constructor.

Changed lines 158-159 from:

An instance of an array type holds exactly the number of values given by the value count parameter in the type definition. Values are addressable by cardinal index using subscript notation. The lowest index is always zero.

to:

The values of an array instance are addressable by cardinal index using subscript notation. The lowest index is always zero.

Added lines 166-172:

An array type is defined to be rigid or flexible. The instance of a rigid array type always holds exactly the number of values that equals the type's capacity. No values may be added, inserted or removed at runtime. By contrast, the instance of a flexible array type may hold a variable number of values. Within the limits of the type's capacity, values may be added, inserted and removed at runtime. A flexible array is defined with an upper open bound by prefixing the value count parameter in the type definition with the < symbol.

Example:

 TYPE FlexArray = ARRAY < 10 OF INTEGER;
2015-09-24 15:28 by trijezdci -
Changed lines 151-152 from:

An array type is an indexed collection type whose values are all of the same type and addressable by cardinal index. The lowest index is always zero. Array types are defined using the ARRAY OF type constructor. The type's capacity is specified by the component count parameter which shall be of an unsigned whole number type and its value shall never be zero.

to:

An array type is an indexed collection type whose values are of a single arbitrary type, called the array's value type. The type's capacity is specified by a value count parameter in the type definition. The capacity must be whole number value and it may not be zero. Array types are defined using the ARRAY OF type constructor.

Changed lines 158-159 from:

An instance of an array type may hold multiple values up to its capacity. Values are addressable by cardinal index.

to:

An instance of an array type holds exactly the number of values given by the value count parameter in the type definition. Values are addressable by cardinal index using subscript notation. The lowest index is always zero.

Changed line 162 from:
 VAR  array : IntArray; int : INTEGER;
to:
 VAR array : IntArray; int : INTEGER;
2015-09-24 04:36 by trijezdci -
2015-09-24 04:32 by trijezdci -
Changed lines 221-222 from:

A pointer type may be defined to have an immutable target.

to:

A pointer type may be defined to restrict the mutability of its target.

Changed line 228 from:

Although the instance of such a pointer itself is mutable, its target is not. A dereferenced instance may not be used as an L-value and it may not be passed to a procedure as a VAR parameter. Pointers to mutable and immutable targets are therefore always incompatible. Any violation shall cause a compile time error.

to:

Although the instance of such a pointer itself is mutable, its target is always treated immutable. A dereferenced instance may not be used as an L-value and it may not be passed to a procedure as a VAR parameter. Pointers to mutable and immutable targets are therefore always incompatible. Any violation shall cause a compile time error.

2015-09-24 04:28 by trijezdci -
Changed lines 205-236 from:

to do

to:

A pointer type is a container for a typed reference to an entity at a memory storage location. The type of the referenced entity is called the target type. The entity referenced by an instance of a pointer type is called the pointer's target. Pointer types are defined using the POINTER TO type constructor.

Example:

 TYPE IntPtr = POINTER TO INTEGER;

Typed references are created using predefined procedure PTR. Instances of pointer types are dereferenced using the pointer dereferencing operator ^.

Example:

 VAR int : INTEGER; intPtr : IntPtr;
 intPtr := PTR(int, IntPtr); (* obtain a typed reference to int *)
 intPtr^ := 0; (* write to int via dereferenced pointer intPtr *)

A pointer type may be defined to have an immutable target.

Example:

 TYPE ImmIntPtr = POINTER TO CONST INTEGER;

Although the instance of such a pointer itself is mutable, its target is not. A dereferenced instance may not be used as an L-value and it may not be passed to a procedure as a VAR parameter. Pointers to mutable and immutable targets are therefore always incompatible. Any violation shall cause a compile time error.

Example:

 VAR int : INTEGER; intPtr : IntPtr; immPtr : ImmIntPtr;
 intPtr := PTR(int, IntPtr); immPtr := PTR(int, ImmIntPtr);
 intPtr^ := 0; (* OK, modifying a mutable target *)
 immPtr^ := 0; (* compile time error due to attempt to modify an immutable target *)
2015-09-23 17:13 by trijezdci -
Changed line 265 from:

The RETAIN statement is used to retain a reference to an instance of a reference counted dynamically allocatable type to prevent its premature deallocation. The RETAIN statement may only be used for instances of reference counted types. Non-compliance shall cause a compile time error.

to:

The RETAIN statement is used to retain a reference to an instance of a reference counted dynamically allocatable type to prevent its premature deallocation. The RETAIN statement may therefore only be used for instances of reference counted types. Non-compliance shall cause a compile time error.

2015-09-23 17:11 by trijezdci -
Changed line 265 from:

The RETAIN statement is used to retain a reference to an instance of a reference counted dynamically allocatable type to prevent its premature deallocation.

to:

The RETAIN statement is used to retain a reference to an instance of a reference counted dynamically allocatable type to prevent its premature deallocation. The RETAIN statement may only be used for instances of reference counted types. Non-compliance shall cause a compile time error.

2015-09-23 17:08 by trijezdci -
Changed line 259 from:
 VAR dict : Sym Table?;
to:
 VAR dict : SymTable;
2015-09-23 17:07 by trijezdci -
Changed lines 255-256 from:

The NEW statement is used to dynamically allocate storage at runtime.

to:

The NEW statement is used to dynamically allocate storage for a new instance of a dynamically allocatable type.

Example:

 VAR dict : Sym Table?;
 NEW dict; (* allocation without initialisation *)
Changed lines 265-266 from:

The NEW statement is used to retain a dynamically allocated entity to prevent its premature deallocation.

to:

The RETAIN statement is used to retain a reference to an instance of a reference counted dynamically allocatable type to prevent its premature deallocation.

Example:

 RETAIN dict;
Changed lines 274-279 from:

The RELEASE statement is used to cancel a previous RETAIN operation for a dynamically allocated entity and deallocate the entity if no further retains are outstanding.

to:

The RELEASE statement is used to release a reference for an instance of a reference counted dynamically allocatable type and thereby cancel an earlier retain operation. If no further retains are outstanding or if the target is not reference counted, the target is deallocated.

Example:

 RELEASE dict;
2015-09-23 16:59 by trijezdci -
Changed lines 255-256 from:

to do

to:

The NEW statement is used to dynamically allocate storage at runtime.

Changed lines 259-260 from:

to do

to:

The NEW statement is used to retain a dynamically allocated entity to prevent its premature deallocation.

Changed line 263 from:

to do

to:

The RELEASE statement is used to cancel a previous RETAIN operation for a dynamically allocated entity and deallocate the entity if no further retains are outstanding.

2015-09-23 16:52 by trijezdci -
Changed lines 504-505 from:

The RETURN statement is used within a procedure body to return control to its caller and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance with these requirements shall cause a compile time error.

to:

The RETURN statement is used within a procedure body to return control to its caller and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance shall cause a compile time error.

Changed line 516 from:

The YIELD statement is used within a coroutine procedure body to suspend the coroutine and pass control to its caller. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When yielding from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance with these requirements shall cause a compile time error.

to:

The YIELD statement is used within a coroutine procedure body to suspend the coroutine and pass control to its caller. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When yielding from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance shall cause a compile time error.

2015-09-23 16:50 by trijezdci -
Added lines 527-539:
The EXIT Statement

The EXIT statement is used within the body of a WHILE, REPEAT, LOOP or FOR statement to terminate execution of the statement's body and transfer control to the first statement after the loop body. The EXIT statement may only occur within the body of loop statements. Non-compliance shall cause a compile time error.

Example:

 LOOP
   ch := nextChar(stdIn);
   CASE ch OF
   | ASCII.ESC : EXIT
   | (* other case labels ... *)
2015-09-23 16:44 by trijezdci -
Changed lines 504-505 from:

The RETURN statement is used within a procedure body to return control to the calling procedure and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance with these requirements shall cause a compile time error.

to:

The RETURN statement is used within a procedure body to return control to its caller and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance with these requirements shall cause a compile time error.

Changed line 516 from:

The YIELD statement is used within a coroutine procedure body to suspend itself and pass control to the calling procedure. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When returning from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance with these requirements shall cause a compile time error.

to:

The YIELD statement is used within a coroutine procedure body to suspend the coroutine and pass control to its caller. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When yielding from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance with these requirements shall cause a compile time error.

2015-09-23 16:41 by trijezdci -
Changed line 508 from:
 PROCEDURE successor ( x : CARDINAL ) : CARDINAL;
to:
 PROCEDURE successor ( n : CARDINAL ) : CARDINAL;
Changed line 510 from:
   RETURN x + 1
to:
   RETURN n + 1
Changed line 525 from:
   RETURN -1;
to:
   RETURN -1
2015-09-23 16:40 by trijezdci -
Added lines 502-527:
The RETURN Statement

The RETURN statement is used within a procedure body to return control to the calling procedure and in the main body of the program to return control to the operating environment that activated the program. A RETURN statement may or may not return a value, depending on the type of the procedure in which it is invoked. When returning from a regular procedure, no value may be returned. When returning from a function procedure a value of the procedure's return type must be returned. Non-compliance with these requirements shall cause a compile time error.

Example:

 PROCEDURE successor ( x : CARDINAL ) : CARDINAL;
 BEGIN
   RETURN x + 1
 END successor;
The YIELD Statement

The YIELD statement is used within a coroutine procedure body to suspend itself and pass control to the calling procedure. A YIELD statement may or may not yield a value, depending on the type of the coroutine procedure in which it is invoked. When yielding from a regular procedure, no value may be yielded. When returning from a function procedure a value of the procedure's return type must be yielded. The YIELD statement may only occur within the body of coroutine procedures. Non-compliance with these requirements shall cause a compile time error.

Example:

 PROCEDURE [COROUTINE] iterator ( CONST array : ARRAY OF INTEGER ) : INTEGER;
 BEGIN
   FOR value IN array DO
     YIELD value
   END;
   RETURN -1;
 END iterator;
2015-09-23 16:18 by trijezdci -
Changed line 191 from:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any field of the base type is always a field of any extension type derived from it, but not every field of an extension type is also a field of the base type.

to:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. All fields of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any field of the base type is always a field of any extension type derived from it, but not every field of an extension type is also a field of the base type.

2015-09-23 16:15 by trijezdci -
Changed line 189 from:
Enumeration Type Extension
to:
Record Type Extension
2015-09-23 16:15 by trijezdci -
Changed line 103 from:
 TYPE Colour = ( red, green, blue, orange, magenta, cyan ); (* ORD(red) => 0 *)
to:
 TYPE Colour = ( red, green, blue ); (* ORD(red) => 0 *)
Changed line 110 from:
 TYPE BaseColour = [red .. blue] OF Colour; (* unqualified *)
to:
 TYPE BaseColour = [red .. green] OF Colour; (* unqualified *)
Changed lines 120-121 from:
 TYPE Colour = ( red, green, blue  );
 TYPE MoreColour = ( +MoreColour, orange, magenta, cyan );
to:
 TYPE MoreColour = ( +Colour, orange, magenta, cyan );
2015-09-23 16:13 by trijezdci -
Added lines 114-115:
Enumeration Type Extension
Changed lines 190-192 from:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any value set of the base type is always a legal value set of any extension type derived from it, but value sets of an extension type are not legal values of the base type.

to:
Enumeration Type Extension

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any field of the base type is always a field of any extension type derived from it, but not every field of an extension type is also a field of the base type.

2015-09-23 15:35 by trijezdci -
Changed lines 114-115 from:

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type. The base type is downwards compatible with any extended types derived from it, but extensions are not upwards compatible with their base type. This restriction is imposed because any value of the base type is always a legal value of any extension type derived from it, but not every value of an extension type is also a legal value of the base type.

to:

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type. The base type is downwards compatible with any extended types derived from it, but extensions are not upwards compatible with their base type. This restriction exists because any value of the base type is always a legal value of any extension type derived from it, but not every value of an extension type is also a legal value of the base type.

Changed line 188 from:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction is imposed because any value set of the base type is always a legal value set of any extension type derived from it, but value sets of an extension type are not legal values of the base type.

to:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction exists because any value set of the base type is always a legal value set of any extension type derived from it, but value sets of an extension type are not legal values of the base type.

2015-09-23 15:34 by trijezdci -
Changed lines 114-115 from:

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type.

to:

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type. The base type is downwards compatible with any extended types derived from it, but extensions are not upwards compatible with their base type. This restriction is imposed because any value of the base type is always a legal value of any extension type derived from it, but not every value of an extension type is also a legal value of the base type.

Added lines 186-195:

A record type may be defined as an extension of another by giving the identifier of the base type in parentheses before the field list declaration. The field declarations of of the base type become fields of the new type. The field names of the base type may therefore not be reused in the extension type's own field list declaration. The base type is downwards compatible with any extended types derived from it, but type extensions are not upwards compatible with their base type. This restriction is imposed because any value set of the base type is always a legal value set of any extension type derived from it, but value sets of an extension type are not legal values of the base type.

Examples:

 TYPE ColourPoint = RECORD ( Point ) colour : Colour END;
 VAR  cPoint : ColourPoint;
 cPoint := { 0.0, 0.0, Colour.red }; (* initialise all fields *)
 cPoint.x := 1.5; cPoint.y := 0.75;
2015-09-23 15:14 by trijezdci -
Deleted lines 166-167:
Changed lines 171-186 from:

to do

to:

A record type is a compound type whose components are of arbitrary types. The components are called fields. The number of fields is arbitrary. Record types are defined using the RECORD type constructor.

Example:

 TYPE Point = RECORD x, y : REAL END;

An instance of a record type holds exactly one value for each field. Fields are addressable by selector.

Examples:

 VAR  point : Point; r : REAL;
 record := { 0.0, 0.0 }; (* initialise all fields with zero *)
 r := point.x; (* field retrieval *)
 point.y := 0.75; (* field storage *)
2015-09-23 15:03 by trijezdci -
Changed line 162 from:
 array := { 0 BY TLIMIT(Int Array?) }; (* initialise all values with zero *)
to:
 array := { 0 BY TLIMIT(IntArray) }; (* initialise all values with zero *)
2015-09-23 15:03 by trijezdci -
Changed line 162 from:
 array := { 0 BY 10 }; (* initialise all values with zero *)
to:
 array := { 0 BY TLIMIT(Int Array?) }; (* initialise all values with zero *)
2015-09-23 15:00 by trijezdci -
Changed line 143 from:
 colours[Colour.blue] := TRUE; (* membership modification *)
to:
 colours[Colour.blue] := TRUE; (* membership storage *)
Changed lines 150-151 from:

An array type is an indexed collection type whose values are all of the same type and addressable by cardinal index. The lowest index is always zero. Array types are defined using the ARRAY OF type constructor. Its capacity is specified by the component count parameter which shall be of an unsigned whole number type and its value shall never be zero.

to:

An array type is an indexed collection type whose values are all of the same type and addressable by cardinal index. The lowest index is always zero. Array types are defined using the ARRAY OF type constructor. The type's capacity is specified by the component count parameter which shall be of an unsigned whole number type and its value shall never be zero.

Added lines 155-164:

An instance of an array type may hold multiple values up to its capacity. Values are addressable by cardinal index.

Examples:

 VAR  array : IntArray; int : INTEGER;
 array := { 0 BY 10 }; (* initialise all values with zero *)
 int := array[5]; (* value retrieval *)
 array[5] := 42; (* value storage *)
2015-09-23 14:52 by trijezdci -
Changed line 139 from:

Example:

to:

Examples:

Changed lines 150-157 from:

to do

to:

An array type is an indexed collection type whose values are all of the same type and addressable by cardinal index. The lowest index is always zero. Array types are defined using the ARRAY OF type constructor. Its capacity is specified by the component count parameter which shall be of an unsigned whole number type and its value shall never be zero.

Example:

 TYPE IntArray = ARRAY 10 OF INTEGER;
2015-09-23 14:43 by trijezdci -
Added lines 122-123:

The allocation size of an enumeration type is always 16 bit. Its maximum value range is 65536 values.

2015-09-23 14:30 by trijezdci -
Changed line 127 from:

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type of up to 256 values. The values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

to:

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type of up to 256 values. The values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

2015-09-23 14:29 by trijezdci -
Changed line 127 from:

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type. Values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

to:

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type of up to 256 values. The values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

2015-09-23 14:19 by trijezdci -
Deleted lines 122-123:
Changed lines 127-142 from:

to do

to:

A set type is a collection type whose storable values are defined by the legal values of an associated enumeration type. Values stored in a set are also called elements of the set and the associated enumeration type is called its element type. A set type is defined using the SET OF type constructor.

Example:

 TYPE ColourSet = SET OF Colour;

An instance of a set type may hold multiple elements but any given element may be stored at most once. An element stored in a set is said to be a member of the set. A set is represented as an array of boolean membership values, where the element is the accessor and the membership is the value. A membership value may thus be either TRUE or FALSE.

Example:

 VAR  colours : ColourSet; isMember : BOOLEAN;
 colours := { Colour.red, Colour.green }; (* assignment *)
 isMember := colours[Colour.green]; (* membership retrieval *)
 colours[Colour.blue] := TRUE; (* membership modification *)
2015-09-23 11:04 by trijezdci -
Changed line 111 from:
 VAR colour : Colour;   colour := Colour.green; (* qualified *)
to:
 VAR colour : Colour;  colour := Colour.green; (* qualified *)
Added lines 113-122:

An enumeration type may be defined as an extension of another by listing the identifier of the base type as the first item in the enumerated value list prefixed by the + symbol. All enumerated values of the base type become legal values of the new type.

Example:

 TYPE Colour = ( red, green, blue  );
 TYPE MoreColour = ( +MoreColour, orange, magenta, cyan );
 (* equivalent to: MoreColour = ( red, green, blue, orange, magenta, cyan );
2015-09-23 10:50 by trijezdci -
Changed line 103 from:
 TYPE Colour = ( red, green, blue, orange, magenta, cyan );   (* ORD(red) => 0 *)
to:
 TYPE Colour = ( red, green, blue, orange, magenta, cyan ); (* ORD(red) => 0 *)
2015-09-23 10:50 by trijezdci -
Changed lines 103-104 from:
 TYPE Colour = ( red, green, blue, orange, magenta, cyan );
 (* ORD(red) => 0 *)
to:
 TYPE Colour = ( red, green, blue, orange, magenta, cyan );   (* ORD(red) => 0 *)
Changed line 110 from:
 TYPE Base Colour? = [red .. blue] OF Colour; (* unqualified *)
to:
 TYPE BaseColour = [red .. blue] OF Colour; (* unqualified *)
2015-09-23 10:49 by trijezdci -
Added lines 71-72:

to do

Deleted lines 90-91:
Added lines 93-94:

to do

Changed lines 99-114 from:

to do

to:

An enumeration type is an ordinal type whose legal values are defined by a list of identifiers. The identifiers are assigned ordinal values from left to right as they appear in the type definition. The ordinal value assigned to the leftmost identifier is always zero.

Example:

 TYPE Colour = ( red, green, blue, orange, magenta, cyan );
 (* ORD(red) => 0 *)

When referencing an enumerated value, its identifier must be qualified with its type identifier, except within a subrange type constructor. This requirement fixes a flaw in classic Modula-2 where the import of an enumeration type could cause name conflicts.

Example:

 TYPE Base Colour? = [red .. blue] OF Colour; (* unqualified *)
 VAR colour : Colour;   colour := Colour.green; (* qualified *)
2015-09-23 10:38 by trijezdci -
Deleted line 78:
 TYPE CoreColours = [red .. blue] OF Colours;
2015-09-23 10:36 by trijezdci -
Changed line 82 from:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol.

to:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol. An open bound of a subrange type is not a legal value of the type.

2015-09-23 10:32 by trijezdci -
Deleted line 76:
 TYPE CoreColours = [red .. blue] OF Colours;
Added line 79:
 TYPE CoreColours = [red .. blue] OF Colours;
2015-09-23 10:31 by trijezdci -
Changed lines 77-78 from:
 TYPE BaseColours = [red .. blue] OF Colours;
to:
 TYPE CoreColours = [red .. blue] OF Colours;
 TYPE Radian = [0.0 .. tau] OF REAL;
Changed lines 82-83 from:

For subrange types of non-countable scalar types, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol.

to:

For subrange types of scalar types that represent real numbers, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol.

Deleted line 85:
 TYPE Radian = [0.0 .. tau] OF REAL;
2015-09-23 10:28 by trijezdci -
Changed line 77 from:
 TYPE Base Colours? = [red .. blue] OF Colours;
to:
 TYPE BaseColours = [red .. blue] OF Colours;
Changed lines 86-87 from:
 TYPE Pos Real? = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE Neg Real? = [TMIN(REAL) .. <0.0] OF REAL;
to:
 TYPE PosReal = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE NegReal = [TMIN(REAL) .. <0.0] OF REAL;
2015-09-23 10:28 by trijezdci -
Added lines 72-90:

A subrange type is a type defined as a subset of a scalar or ordinal type. A subrange type is upwards compatible with its base type, but the base type is not downwards compatible with any subrange types derived from it. A subrange type inherits all its properties from its base type, except for its lower and upper bound. A subrange type's lower and upper bound must be specified in its type definition. Both lower and upper bound must be compatible with the base type and they must be legal values of the base type.

Examples:

 TYPE Base Colours? = [red .. blue] OF Colours;
 TYPE Natural = [1 .. TMAX(CARDINAL)] OF CARDINAL;

For subrange types of non-countable scalar types, lower and upper bounds may be specified as open bounds. An open lower bound is prefixed by the > symbol. An open upper bound is prefixed by the < symbol.

Examples:

 TYPE Radian = [0.0 .. tau] OF REAL;
 TYPE Pos Real? = [>0.0 .. TMAX(REAL)] OF REAL;
 TYPE Neg Real? = [TMIN(REAL) .. <0.0] OF REAL;
2015-09-23 09:39 by trijezdci -
Added lines 25-28:
2015-09-23 09:36 by trijezdci -
Added lines 713-717:
Changed lines 719-729 from:
Module Type
to:

EBNF | Syntax Diagram

to do

Type Classification

EBNF | Syntax Diagram

to do

Added lines 731-735:
Added lines 737-741:
Added lines 743-747:
Added lines 749-752:
2015-09-23 09:30 by trijezdci -
Added lines 59-64:

EBNF | Syntax Diagram

  • alias types
  • subrange types
  • immutable types
Changed line 69 from:
Immutable Derived Types
to:
Immutable Types
2015-09-23 09:28 by trijezdci -
Added lines 30-31:

to do

Changed lines 36-38 from:
Constant Definitions
Variable Declarations
Type Definitions
to:
Constant Definitions

to do

Variable Declarations

to do

Type Definitions
  • derived sub-types
  • enumeration types
  • set types
  • array types
  • record types
  • pointer types
  • coroutine types
  • procedure types

to do

Derived Sub-Types
ALIAS Types
Subrange Types
Immutable Derived Types
Enumeration Types

EBNF | Syntax Diagram

to do

Set Types

EBNF | Syntax Diagram

to do

Array Types

EBNF | Syntax Diagram

to do

Record Types

EBNF | Syntax Diagram

to do

Pointer Types

EBNF | Syntax Diagram

to do

Coroutine Types

EBNF | Syntax Diagram

to do

Procedure Types

EBNF | Syntax Diagram

to do

2015-09-23 09:21 by trijezdci -
Added line 17:
Added lines 19-23:
Added line 25:
Added lines 27-33:
Added line 37:
Added lines 40-41:
Changed lines 322-323 from:
Expressions
to:
Expressions

EBNF | Syntax Diagram

to do

Changed line 329 from:
Operators
to:
Operators
2015-09-23 09:14 by trijezdci -
Changed line 300 from:
 FOR key IN dict DO dict[key] := EMPTY END;
to:
 FOR key IN dict DO WRITE(key) END;
2015-09-23 09:12 by trijezdci -
Changed lines 276-277 from:

The iterable is an instance of an ARRAY OF type or array ADT.

to:

The iterable is an instance of an ARRAY OF type or array ADT.

Changed line 286 from:

The iterable is an instance of a SET OF type or set ADT.

to:

The iterable is an instance of a SET OF type or set ADT.

2015-09-23 09:11 by trijezdci -
Changed lines 276-277 from:

The iterable is an instance of an array ADT or ARRAY OF type.

to:

The iterable is an instance of an ARRAY OF type or array ADT.

Added lines 282-291:
Iterating Over A Set

The iterable is an instance of a SET OF type or set ADT.

Example:

 FOR elem IN set DO WRITE(elem) END;
 FOR elem, counter IN countedSet DO WRITE(elem); WRITE(" : "); WRITE(counter); WriteLn END;
2015-09-23 09:06 by trijezdci -
Changed line 281 from:
 FOR index, value IN array DO value := source[index] END;
to:
 FOR index, value IN target DO value := source[index] END;
2015-09-23 09:05 by trijezdci -
Changed line 291 from:
 FOR key, value IN dict DO WRITE(key); WRITE(" : "); WRITE(value); Write Ln? END;
to:
 FOR key, value IN dict DO WRITE(key); WRITE(" : "); WRITE(value); WriteLn END;
2015-09-23 08:54 by trijezdci -
Changed lines 270-271 from:
 FOR listNode IN list DO WRITE(listNode^.item) END;
 FOR VALUE item IN list DO WRITE(listElem) END;
to:
 FOR listNode IN list DO WRITE(listNode) END;
 FOR VALUE item IN list DO item := foo END;
2015-09-23 08:52 by trijezdci -
Changed lines 270-271 from:
 FOR listNode IN list DO WRITE(`listNode^.item) END;
 FOR VALUE item IN list DO WRITE(`listElem) END;
to:
 FOR listNode IN list DO WRITE(listNode^.item) END;
 FOR VALUE item IN list DO WRITE(listElem) END;
2015-09-23 08:51 by trijezdci -
Added lines 263-292:
Iterating Over A List

The iterable is an instance of a list ADT.

Example:

 FOR listNode IN list DO WRITE(`listNode^.item) END;
 FOR VALUE item IN list DO WRITE(`listElem) END;
Iterating Over An Array

The iterable is an instance of an array ADT or ARRAY OF type.

Example:

 FOR index IN array DO array[index] := 0 END;
 FOR index, value IN array DO value := source[index] END;
Iterating Over A Dictionary

The iterable is an instance of a dictionary ADT.

Example:

 FOR key IN dict DO dict[key] := EMPTY END;
 FOR key, value IN dict DO WRITE(key); WRITE(" : "); WRITE(value); Write Ln? END;
2015-09-23 08:39 by trijezdci -
Changed lines 30-31 from:

A statement is an action that can be executed to cause a transformation of the computational state of a program. Statements are used for their effects only, they do not return any values and they may not be used within expressions. There are twelve kinds of statements:

to:

A statement is an action that can be executed to cause a transformation of the computational state of a program. Statements are used for their effects only, they do not return any values and they may not occur within expressions. There are twelve kinds of statements:

Added line 50:
Added line 70:
Changed lines 216-217 from:
Ordinal Type Iteration
to:
Iterating Over Ordinal Types
Changed line 255 from:
Collection Iteration
to:
Iterating Over Collections
2015-09-23 08:32 by trijezdci -
Changed lines 44-45 from:
Memory Management Statements
to:
Memory Management Statements
Changed lines 65-66 from:
Destructive Update Statements
to:
Destructive Update Statements
Changed lines 113-114 from:
The IF Statement
to:
The IF Statement
Changed lines 130-131 from:
The CASE Statement
to:
The CASE Statement
Changed lines 149-150 from:
The WHILE Statement
to:
The WHILE Statement
Changed lines 160-161 from:
The REPEAT Statement
to:
The REPEAT Statement
Changed lines 171-172 from:
The LOOP Statement
to:
The LOOP Statement
Changed line 187 from:
The FOR Statement
to:
The FOR Statement
2015-09-23 08:29 by trijezdci -
Changed line 26 from:
Statements
to:
Statements
2015-09-23 08:28 by trijezdci -
Added lines 28-29:
Added lines 46-47:
Added lines 115-116:
Added lines 132-133:
Added lines 151-152:
Added lines 162-163:
Added lines 173-174:
Added lines 189-190:
Added lines 195-196:
Added lines 201-202:
Added lines 208-209:
2015-09-23 07:40 by trijezdci -
Changed line 189 from:

If the iterable supports directional iteration, the prevailing iteration order may be imposed by an ascender or descender following the first loop variant. An ascender imposes ascending order and is denoted by the ++ symbol. A descender imposes descending order and is denoted by the -- symbol. When no ascender nor descender is given, the prevailing iteration order is ascending. However, if the iterable does not support directional iteration, no ascender and no descender may be given and the prevailing iteration order is implementation dependent.

to:

If the iterable supports directional iteration, the prevailing iteration order may be imposed by an ascender or descender following the first loop variant. An ascender imposes ascending order and is denoted by the ++ symbol. A descender imposes descending order and is denoted by the -- symbol. When no ascender nor descender is given, the prevailing iteration order is ascending. However, if the iterable does not support directional iteration, the prevailing iteration order is implementation dependent and no ascender and no descender may be given.

2015-09-23 07:38 by trijezdci -
Changed lines 189-190 from:

If the iterable supports directional iteration, ascending or descending iteration order may be imposed by an ascender or descender following the first loop variant. An ascender is denoted by the ++ symbol. A descender is denoted by the -- symbol. The default iteration order — when no ascender nor descender is given — is always ascending. However, if the iterable does not support directional iteration, no ascender and no descender may be given and the iteration order is implementation dependent.

to:

If the iterable supports directional iteration, the prevailing iteration order may be imposed by an ascender or descender following the first loop variant. An ascender imposes ascending order and is denoted by the ++ symbol. A descender imposes descending order and is denoted by the -- symbol. When no ascender nor descender is given, the prevailing iteration order is ascending. However, if the iterable does not support directional iteration, no ascender and no descender may be given and the prevailing iteration order is implementation dependent.

Changed lines 193-194 from:

If the iterable entity is an ordinal type or a subrange thereof, only one loop variant may be given. The loop variant is immutable. Its type is the ordinal type or subrange given as iterable entity in the loop header and the loop iterates over all values of the given iterable entity. There are three use cases:

to:

If the iterable is an ordinal type or a subrange thereof, only one loop variant may be given. The loop variant is immutable. Its type is the ordinal type or subrange given as iterable and the loop iterates over all values of the given iterable. There are three use cases:

Changed lines 201-202 from:

The iterable entity is type CHAR or a subrange thereof.

to:

The iterable is type CHAR or a subrange thereof.

Changed lines 211-212 from:

The iterable entity is an enumeration type or a subrange thereof.

to:

The iterable is an enumeration type or a subrange thereof.

Changed lines 222-223 from:

The iterable entity is a whole number type or a subrange thereof.

to:

The iterable is a whole number type or a subrange thereof.

Changed line 232 from:

If the iterable entity is an instance of a collection type, one or two loop variants may be given. The accessor is always immutable. Its type is the accessor type of the iterable entity. If the iterable entity is mutable, the value is mutable, otherwise immutable. Its type is the value type of the iterable entity. The loop iterates over all accessor/value pairs of the given iterable entity. There are four use cases:

to:

If the iterable is an instance of a collection type, one or two loop variants may be given. The accessor is always immutable. Its type is the accessor type of the iterable entity. If the iterable entity is mutable, the value is mutable, otherwise immutable. Its type is the value type of the iterable. The loop iterates over all accessor/value pairs of the given iterable. There are four use cases:

2015-09-23 07:29 by trijezdci -
Changed line 183 from:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. During the first iteration cycle the loop variant or variants reference that accessor, value or accessor/value pair which is first for the prevailing iteration order. Before each subsequent iteration cycle the loop variant or variants are advanced to its current successor for the prevailing iteration order. Iteration continues until all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop. During the first iteration cycle the loop variant or variants reference that accessor, value or accessor/value pair which is first for the prevailing iteration order. Before each subsequent iteration cycle the loop variant or variants are advanced to its current successor for the prevailing iteration order. Iteration continues until all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

2015-09-23 07:27 by trijezdci -
Changed line 183 from:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. During the first iteration cycle the loop variant or variants reference that accessor, value or accessor/value pair which is first for the prevailing iteration order. Upon each iteration cycle the loop variant or variants are advanced to its current successor for the prevailing iteration order until all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. During the first iteration cycle the loop variant or variants reference that accessor, value or accessor/value pair which is first for the prevailing iteration order. Before each subsequent iteration cycle the loop variant or variants are advanced to its current successor for the prevailing iteration order. Iteration continues until all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

Deleted lines 189-191:

repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until all accessor/value pairs have been visited.

2015-09-23 07:24 by trijezdci -
Changed line 185 from:

The composition of the loop variant section depends on the iterable. If it is an ordinal type or subrange, the loop variant section may only contain a single variant and it is always immutable within the loop body. If the iterable is a collection instance, the loop variant section may contain one or two loop variants representing the collection's accessor, its value or both. If the accessor is to be omitted, the loop variant must be prefixed with VALUE. An accessor is always immutable within the loop body. For mutable collections, the value is mutable, for immutable collections it is immutable.

to:

The composition of the loop variant section depends on the iterable. If it is an ordinal type or subrange, the loop variant section may only contain a single variant and it is always immutable within the loop body. If the iterable is a collection instance, the loop variant section may contain one or two loop variants representing the collection's accessor, its value or both. If the accessor is to be omitted, the loop variant must be prefixed with VALUE. An accessor is always immutable within the loop body. A value is mutable within the loop body if the iterable is mutable, otherwise immutable.

2015-09-23 07:16 by trijezdci -
Changed line 183 from:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. During the first iteration cycle the loop variant or variants reference that accessor, value or accessor/value pair which is first for the prevailing iteration order. Upon each iteration cycle the loop variant or variants are advanced to its current successor for the prevailing iteration order until all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

2015-09-23 07:06 by trijezdci -
Changed line 183 from:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body, once the loop has terminated, the variants are no longer in scope.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body. Once a FOR loop has terminated, its loop variants are no longer in scope.

2015-09-23 07:05 by trijezdci -
Changed line 183 from:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited. Loop variant identifiers are only in scope within the loop header and body, once the loop has terminated, the variants are no longer in scope.

2015-09-23 07:01 by trijezdci -
Changed lines 185-186 from:

The composition of the loop variant section depends on the iterable. If it is an ordinal type or subrange, the loop variant section may only contain a single variant and it is always immutable within the loop body. If the iterable is a collection instance, the loop variant section may contain one or two loop variants representing the collection's accessor, value or both. An accessor is always immutable within the loop body. For mutable collections, the value is mutable, for immutable collections it is immutable.

to:

The composition of the loop variant section depends on the iterable. If it is an ordinal type or subrange, the loop variant section may only contain a single variant and it is always immutable within the loop body. If the iterable is a collection instance, the loop variant section may contain one or two loop variants representing the collection's accessor, its value or both. If the accessor is to be omitted, the loop variant must be prefixed with VALUE. An accessor is always immutable within the loop body. For mutable collections, the value is mutable, for immutable collections it is immutable.

Changed line 189 from:

If the iterable entity supports directional iteration, ascending or descending iteration order may be imposed by an ascender or descender following the first loop variant. An ascender is denoted by the ++ symbol. A descender is denoted by the -- symbol. The default iteration order — when no ascender nor descender is given — is always ascending. However, if the iterable entity does not support directional iteration, no ascender and no descender may be used and the iteration order is implementation dependent.

to:

If the iterable supports directional iteration, ascending or descending iteration order may be imposed by an ascender or descender following the first loop variant. An ascender is denoted by the ++ symbol. A descender is denoted by the -- symbol. The default iteration order — when no ascender nor descender is given — is always ascending. However, if the iterable does not support directional iteration, no ascender and no descender may be given and the iteration order is implementation dependent.

2015-09-23 06:54 by trijezdci -
Changed line 179 from:

The iterable entity — or iterable in short – is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. If it is an ordinal type or subrange, the iterable is always immutable. If it is a collection, the iterable may be either mutable or immutable.

to:

The iterable entity — or iterable in short – is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. An ordinal type or subrange iterable is always immutable. A collection iterable may be either mutable or immutable.

2015-09-23 06:50 by trijezdci -
Changed lines 179-180 from:

The iterable entity is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. If it is an ordinal type or subrange, the iterable entity is always immutable. If it is a collection, the iterable entity may be either mutable or immutable.

to:

The iterable entity — or iterable in short – is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. If it is an ordinal type or subrange, the iterable is always immutable. If it is a collection, the iterable may be either mutable or immutable.

Changed lines 183-185 from:

The composition of the loop variant section depends on the iterable entity. If the iterable entity is an ordinal type or subrange, the loop variant section may only contain a single variant which is always immutable within the loop body. If the iterable entity is a collection instance, the loop variant section may contain one or two loop variants denoting the accessor, the value or both. The accessor is always immutable within the loop body. For mutable collections, the value is mutable. For immutable collections the value is immutable.

to:

The loop variant section contains one or two identifiers through which accessors and values of the iterable are referenced within the loop body. Upon each iteration cycle, the loop variant or variants are advanced to the next accessor, value or accessor/value pair. Iteration stops when all accessors and/or values have been visited.

The composition of the loop variant section depends on the iterable. If it is an ordinal type or subrange, the loop variant section may only contain a single variant and it is always immutable within the loop body. If the iterable is a collection instance, the loop variant section may contain one or two loop variants representing the collection's accessor, value or both. An accessor is always immutable within the loop body. For mutable collections, the value is mutable, for immutable collections it is immutable.

2015-09-23 06:00 by trijezdci -
Changed line 185 from:
Imposing Iteration Order
to:
The Iteration Order
2015-09-23 05:56 by trijezdci -
Changed lines 175-176 from:

The FOR statement is used to iterate over an iterable entity and execute a statement or statement sequence during each iteration cycle. It consists of a loop header and a loop body. The loop header consists of one or two loop variants, optionally the iteration order, and the iterable entity. The loop body consists of a statement or statement sequence.

to:

The FOR statement is used to iterate over an iterable entity and execute a statement or statement sequence during each iteration cycle. It consists of a loop header and a loop body. The loop header consists of one or two loop variants, an optional iteration order, and the iterable entity. The loop body consists of a statement or statement sequence.

Changed lines 179-180 from:

The iterable entity is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type.

to:

The iterable entity is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type. If it is an ordinal type or subrange, the iterable entity is always immutable. If it is a collection, the iterable entity may be either mutable or immutable.

Changed line 183 from:

The composition of the loop variant section depends on the iterable entity. If the iterable entity is an ordinal type or subrange, the loop variant section may only contain a single variant which is always immutable. If the iterable entity is a collection instance, the loop variant section may contain one or two loop variants denoting the accessor, the value or both.

to:

The composition of the loop variant section depends on the iterable entity. If the iterable entity is an ordinal type or subrange, the loop variant section may only contain a single variant which is always immutable within the loop body. If the iterable entity is a collection instance, the loop variant section may contain one or two loop variants denoting the accessor, the value or both. The accessor is always immutable within the loop body. For mutable collections, the value is mutable. For immutable collections the value is immutable.

2015-09-23 05:49 by trijezdci -
Changed lines 175-179 from:

The FOR statement is used to repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until all accessor/value pairs have been visited.

to do: paragraph on loop variants and iterable entities

If the iterable entity is ordered and bidirectionally iterable, an ascender or descender may be given in the loop header to impose ascending or descending iteration order. The default iteration order — when no ascender nor descender is given — is ascending. If the iterable entity is unordered or if it is only unidirectionally iterable, no ascender and no descender may be given in the loop header. In this case, if ordered, the iteration order is ascending, and if unordered, the iteration order is implementation defined.

to:

The FOR statement is used to iterate over an iterable entity and execute a statement or statement sequence during each iteration cycle. It consists of a loop header and a loop body. The loop header consists of one or two loop variants, optionally the iteration order, and the iterable entity. The loop body consists of a statement or statement sequence.

The Iterable Entity

The iterable entity is denoted by an identifier of an ordinal type or subrange, an anonymous subrange of an ordinal type, or a designator of an instance of a collection type.

The Loop Variant Section

The composition of the loop variant section depends on the iterable entity. If the iterable entity is an ordinal type or subrange, the loop variant section may only contain a single variant which is always immutable. If the iterable entity is a collection instance, the loop variant section may contain one or two loop variants denoting the accessor, the value or both.

Imposing Iteration Order

If the iterable entity supports directional iteration, ascending or descending iteration order may be imposed by an ascender or descender following the first loop variant. An ascender is denoted by the ++ symbol. A descender is denoted by the -- symbol. The default iteration order — when no ascender nor descender is given — is always ascending. However, if the iterable entity does not support directional iteration, no ascender and no descender may be used and the iteration order is implementation dependent.

repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until all accessor/value pairs have been visited.

2015-09-23 04:54 by trijezdci -
Added lines 220-227:
Collection Iteration

If the iterable entity is an instance of a collection type, one or two loop variants may be given. The accessor is always immutable. Its type is the accessor type of the iterable entity. If the iterable entity is mutable, the value is mutable, otherwise immutable. Its type is the value type of the iterable entity. The loop iterates over all accessor/value pairs of the given iterable entity. There are four use cases:

  • iterating over a list
  • iterating over an array
  • iterating over a set
  • iterating over a dictionary
2015-09-23 04:29 by trijezdci -
Changed lines 183-184 from:

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is immutable. Its type is the ordinal type or subrange given as iterable entity in the loop header and the loop iterates over all values of the given iterable entity. There are three use cases:

to:

If the iterable entity is an ordinal type or a subrange thereof, only one loop variant may be given. The loop variant is immutable. Its type is the ordinal type or subrange given as iterable entity in the loop header and the loop iterates over all values of the given iterable entity. There are three use cases:

Changed lines 191-192 from:

The iterable entity is type CHAR or an anonymous subrange thereof.

to:

The iterable entity is type CHAR or a subrange thereof.

Changed lines 201-202 from:

The iterable entity is an enumeration type or an anonymous subrange thereof.

to:

The iterable entity is an enumeration type or a subrange thereof.

Changed line 212 from:

The iterable entity is a whole number type or an anonymous subrange thereof.

to:

The iterable entity is a whole number type or a subrange thereof.

2015-09-23 04:15 by trijezdci -
Added lines 177-178:

to do: paragraph on loop variants and iterable entities

Deleted lines 179-180:

to do: paragraph on loop variants and iterable entities

2015-09-23 04:14 by trijezdci -
Changed lines 195-196 from:
 FOR char IN CHAR DO WRITE(char) END;
 FOR char IN ["a".."z"] OF CHAR DO WRITE(char) END;
to:
 FOR ch IN CHAR DO WRITE(ch) END;
 FOR ch IN ["a".."z"] OF CHAR DO WRITE(ch) END;
2015-09-23 04:12 by trijezdci -
Changed line 264 from:
 value := pointer^^; (* pointer to pointer dereference *)
to:
 value := pointer^^; (* double pointer dereference *)
2015-09-23 04:08 by trijezdci -
Changed line 205 from:
 TYPE Colours = ( red, green, blue, orange, cyan, magenta );
to:
 TYPE Colours = ( red, green, blue, cyan, magenta, ... );
2015-09-23 04:08 by trijezdci -
Changed line 205 from:
 TYPE Colours = ( red, green, blue, orange, cyan, magenta, yellow );
to:
 TYPE Colours = ( red, green, blue, orange, cyan, magenta );
2015-09-23 04:07 by trijezdci -
Changed lines 191-192 from:

When iterating over the CHAR type, the loop variant is of type CHAR.

to:

The iterable entity is type CHAR or an anonymous subrange thereof.

Changed lines 201-202 from:

When iterating over an enumeration type, the loop variant is of the enumeration type.

to:

The iterable entity is an enumeration type or an anonymous subrange thereof.

Changed line 212 from:

When iterating over an enumeration type, the loop variant is of the whole number type.

to:

The iterable entity is a whole number type or an anonymous subrange thereof.

2015-09-23 03:57 by trijezdci -
Changed lines 181-184 from:
Iterating Over An Ordinal Type

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the ordinal type or subrange and it is immutable. The loop iterates over all values of the ordinal type or subrange.

to:
Ordinal Type Iteration

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is immutable. Its type is the ordinal type or subrange given as iterable entity in the loop header and the loop iterates over all values of the given iterable entity. There are three use cases:

  • iterating over the CHAR type
  • iterating over an enumeration type
  • iterating over a whole number type
Iterating Over The CHAR Type

When iterating over the CHAR type, the loop variant is of type CHAR.

Changed lines 194-196 from:

Example:

 TYPE Colours = ( red, green, blue );
 FOR colour IN Colours DO WRITE(NameOfColour(colour)) END;
to:

Examples:

 FOR char IN CHAR DO WRITE(char) END;
 FOR char IN ["a".."z"] OF CHAR DO WRITE(char) END;
Changed lines 199-202 from:
Iterating Over A Whole Number Type

If the iterable entity is a whole number type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the whole number type or subrange and it is immutable. The loop iterates over all values of the whole number type or subrange.

to:
Iterating Over An Enumeration Type

When iterating over an enumeration type, the loop variant is of the enumeration type.

Example:

 TYPE Colours = ( red, green, blue, orange, cyan, magenta, yellow );
 FOR colour IN Colours DO WRITE(NameOfColour(colour)) END;
 FOR colour IN [red..blue] OF Colours DO WRITE(NameOfColour(colour)) END;
Iterating Over A Whole Number Type

When iterating over an enumeration type, the loop variant is of the whole number type.

2015-09-23 03:27 by trijezdci -
Changed lines 183-184 from:

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the ordinal type or subrange and the loop iterates over all values of the ordinal type or subrange.

to:

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the ordinal type or subrange and it is immutable. The loop iterates over all values of the ordinal type or subrange.

Added lines 189-198:
Iterating Over A Whole Number Type

If the iterable entity is a whole number type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the whole number type or subrange and it is immutable. The loop iterates over all values of the whole number type or subrange.

Example:

 FOR number IN CARDINAL DO WRITE(BottlesOfBeer(number)) END;
 FOR n IN [0..9] OF CARDINAL DO array[2*n+1] := odd END; (* indices 1, 3, 5, 7, 9 *)
2015-09-23 03:21 by trijezdci -
Changed line 188 from:
 FOR colour IN Colours DO WRITE(Name Of Colour?(colour)) END;
to:
 FOR colour IN Colours DO WRITE(NameOfColour(colour)) END;
2015-09-23 03:20 by trijezdci -
Added lines 179-189:

to do: paragraph on loop variants and iterable entities

Iterating Over An Ordinal Type

If the iterable entity is an ordinal type or an anonymous subrange thereof, only one loop variant may be given. The loop variant is of the ordinal type or subrange and the loop iterates over all values of the ordinal type or subrange.

Example:

 TYPE Colours = ( red, green, blue );
 FOR colour IN Colours DO WRITE(Name Of Colour?(colour)) END;
2015-09-23 03:10 by trijezdci -
Changed line 111 from:

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. IF-statements must always be terminated with an END. At most one block in the statement is executed.

to:

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. At most one block in the statement is executed. IF-statements must always be terminated with an END.

2015-09-23 03:08 by trijezdci -
Changed line 111 from:

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's boolean condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. IF-statements must always be terminated with an END. At most one block in the statement is executed.

to:

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. IF-statements must always be terminated with an END. At most one block in the statement is executed.

2015-09-22 16:31 by trijezdci -
Changed line 175 from:

The FOR statement is used to repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until no more successor is available.

to:

The FOR statement is used to repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until all accessor/value pairs have been visited.

2015-09-22 16:28 by trijezdci -
Added lines 172-180:
The FOR Statement

The FOR statement is used to repeatedly execute a statement or statement sequence while iterating over all accessor/value pairs of an iterable entity. A reference to the current accessor or value or both is declared in the loop header followed by the entity to be iterated. An iterable entity may be an ordinal or whole number type, or a subrange of an ordinal or whole number type, or a collection type. Before each iteration, the current accessor/value pair is advanced to its successor until no more successor is available.

If the iterable entity is ordered and bidirectionally iterable, an ascender or descender may be given in the loop header to impose ascending or descending iteration order. The default iteration order — when no ascender nor descender is given — is ascending. If the iterable entity is unordered or if it is only unidirectionally iterable, no ascender and no descender may be given in the loop header. In this case, if ordered, the iteration order is ascending, and if unordered, the iteration order is implementation defined.

2015-09-22 16:08 by trijezdci -
Deleted lines 162-163:

depending on a condition in form of a boolean expression. The expression is evaluated each time after the REPEAT block has executed. the expression evaluates to TRUE the REPEAT block is executed, otherwise not.

Changed line 167 from:
   IF ch IN Terminator Set? THEN
to:
   IF ch IN TerminatorSet THEN
2015-09-22 16:07 by trijezdci -
Changed line 159 from:
The LOOP{ Statement
to:
The LOOP Statement
2015-09-22 16:06 by trijezdci -
Added lines 157-172:
The LOOP{ Statement

A LOOP statement is used to repeat a statement or statement sequence indefinitely unless explicitly terminated by an EXIT statement.

depending on a condition in form of a boolean expression. The expression is evaluated each time after the REPEAT block has executed. the expression evaluates to TRUE the REPEAT block is executed, otherwise not.

Example:

 LOOP
   READ(file, ch);
   IF ch IN Terminator Set? THEN
     EXIT
   END (* IF *)
 END; (* LOOP *)
2015-09-22 16:03 by trijezdci -
Added lines 141-157:
The WHILE Statement

A WHILE statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time before the DO block is executed. The DO block is repeated as long as the expression evaluates to TRUE.

Example:

 WHILE NOT EOF(file) DO READ(file, ch) END;
The REPEAT Statement

A REPEAT statement is used to repeat a statement or statement sequence depending on a condition in form of a boolean expression. The expression is evaluated each time after the REPEAT block has executed. the expression evaluates to TRUE the REPEAT block is executed, otherwise not.

Example:

 REPEAT READ(file, ch) UNTIL ch = terminator END;
2015-09-22 15:57 by trijezdci -
Added lines 124-139:
The CASE Statement

A CASE statement is a flow-control statement that passes control to one of a number of labeled statements or statement sequences depending on the value of an ordinal expression.

Example:

 CASE colour OF
 | colour.red   : WRITE("Red")
 | colour.green : WRITE("Green")
 | colour.blue  : WRITE("Blue")
 ELSE
   UNSAFE.HALT(1) (* fatal error -- abort *)
 END;

A case label shall be listed at most once. If a case is encountered at runtime that is not listed in the case label list and if there is no ELSE clause, no case label statements shall be executed and no error shall result.

2015-09-22 15:49 by trijezdci -
Added lines 107-121:
The IF Statement

An IF statement is a conditional flow-control statement. It evaluates a condition in form of a boolean expression. If the condition is true then program control passes to its THEN block. If the condition is false and an ELSIF branch follows, then program control passes to the ELSIF branch to evaluate that branch's boolean condition. Again, if the condition is true then program control passes to the THEN block of the ELSIF branch. If there are no ELSIF branches, or if the conditions of all ELSIF branches are false, and if an ELSE branch follows, then program control passes to the ELSE block. IF-statements must always be terminated with an END. At most one block in the statement is executed.

Example:

 IF i > 0 THEN
   WRITE("Positive")
 ELSIF i = 0 THEN
   WRITE("Zero")
 ELSE
   WRITE("Negative")
 END;
2015-09-22 14:56 by trijezdci -
Changed line 106 from:
 Insert( tree, "Fred Flintstone", 42 );   Clear Buffers?;
to:
 Insert( tree, "Fred Flintstone", 42 );   ClearBuffers;
2015-09-22 14:55 by trijezdci -
Added lines 99-107:
The Procedure Call Statement

A procedure call statement is used to invoke a procedure. It consists of the procedure's identifier, optionally followed by a list of parameters enclosed in parentheses to be passed to the called procedure. Parameters passed are called actual parameters, those defined in the procedure's header are called formal parameters. In every procedure call, the types of actual and formal parameters must match. If these conditions are not met, a compile time error shall occur. Procedure calls may be recursive, that is, a procedure may call itself within its body. Recursive calls shall be optimised by eliminating tail call recursion.

Examples:

 Insert( tree, "Fred Flintstone", 42 );   Clear Buffers?;
2015-09-22 14:49 by trijezdci -
Changed lines 75-76 from:
 int := 42; (* assignment of a whole number value to a variable of a whole number type *)
 str := "foobar"; (* assignment of a quoted string value to a variable of a string type *)
to:
 ch := "a";   str := "foo";   i := -12345;   r := 3.1415926;   z := { 1.2, 3.4 };   array[5] := 0;
2015-09-22 14:46 by trijezdci -
Changed lines 71-72 from:

The assignment statement is used to assign a value to an instance of a mutable type. It consists of a designator, followed by the assignment symbol :=, followed by an expression. The designator is called the L-value, the expression is called the R-value. The L-value must be mutable and the types of L-value and R-value must be assignment compatible. If these conditions are not met, a compile time error shall occur.

to:

The assignment statement is used to assign a value to an instance of a mutable type. It consists of a designator followed by the assignment symbol :=, followed by an expression. The designator is called the L-value, the expression is called the R-value. The L-value must be mutable and the types of L-value and R-value must be assignment compatible. If these conditions are not met, a compile time error shall occur.

Changed lines 81-82 from:

...

to:

The increment statement is used to increment the current value of an instance of a whole number type. It consists of a designator followed by the postfix increment symbol ++. The designator is an L-value. It must be mutable and of a whole number type. If these conditions are not met, a compile time error shall occur.

Examples:

 lineCounter++; index++;
Changed lines 90-95 from:

...

to:

The decrement statement is used to decrement the current value of an instance of a whole number type. It consists of a designator followed by the postfix decrement symbol --. The designator is an L-value. It must be mutable and of a whole number type. If these conditions are not met, a compile time error shall occur.

Examples:

 lineCounter--; index--;
2015-09-22 14:41 by trijezdci -
Added lines 72-77:

Examples:

 int := 42; (* assignment of a whole number value to a variable of a whole number type *)
 str := "foobar"; (* assignment of a quoted string value to a variable of a string type *)
2015-09-22 14:36 by trijezdci -
Added lines 24-25:

Added lines 27-86:

A statement is an action that can be executed to cause a transformation of the computational state of a program. Statements are used for their effects only, they do not return any values and they may not be used within expressions. There are twelve kinds of statements:

  • memory management statements
  • destructive update statements
  • the procedure call statement
  • the IF statement
  • the CASE statement
  • the LOOP statement
  • the WHILE statement
  • the REPEAT statement
  • the FOR statement
  • the RETURN statement
  • the YIELD statement
  • the EXIT statement
Memory Management Statements

Memory management statements are used to allocate, initialise, retain and release instances of dynamic data types at runtime. There are three kinds of memory management statements:

  • the NEW statement
  • the RETAIN statement
  • the RELEASE statement
The NEW Statement

to do

The RETAIN Statement

to do

The RELEASE Statement

to do

Destructive Update Statements

Destructive update statements are used to destructively update instances of mutable data types. There are four kinds:

  • the assignment statement
  • the increment statement
  • the decrement statement
  • the COPY statement
The Assignment Statement

The assignment statement is used to assign a value to an instance of a mutable type. It consists of a designator, followed by the assignment symbol :=, followed by an expression. The designator is called the L-value, the expression is called the R-value. The L-value must be mutable and the types of L-value and R-value must be assignment compatible. If these conditions are not met, a compile time error shall occur.

The Increment Statement

...

The Decrement Statement

...

The COPY Statement

to do

2015-09-22 14:06 by trijezdci -
Changed lines 35-58 from:
OperatorRepresented OperationArityAssociativityPrecedence
^ Pointer Dereferenceunaryleft6 (highest)
:: Type Conversionbinaryleft5
NOT Logical Negationunarynone4
* Multiplication, Set Intersectionbinaryleft3
/ Real Division, Symmetric Set Differencebinaryleft3
DIV Euclidean Integer Divisionbinaryleft3
MOD Modulus of Euclidean Integer Divisionbinaryleft3
AND Logical Conjunctionbinaryleft3
\ Set Differencebinaryleft3
+ Arithmetic Identityunarynone2
Addition, Set Unionbinaryleft2
- Sign Inversionunarynone2
Addition, Set Unionbinaryleft2
OR Logical Disjunctionbinaryleft2
& Concatenationbinaryleft2
= Equality Testbinarynone1
# Inequality Testbinarynone1
> Greater-Than Test, Proper Superset Testbinarynone1
>= Greater-Than-Or-Equal Test, Superset Testbinarynone1
< Less-Than Test, Proper Subset Testbinarynone1
<= Less-Than-Or-Equal Test, Subset Testbinarynone1
IN Membership Testbinarynone1
== Identity Testbinarynone1
to:
OperatorRepresented OperationPositionArityAssociativityPrecedence
^ Pointer Dereferencepostfixunaryleft6 (highest)
:: Type Conversioninfixbinaryleft5
NOT Logical Negationprefixunarynone4
* Multiplication, Set Intersectioninfixbinaryleft3
/ Real Division, Symmetric Set Differenceinfixbinaryleft3
DIV Euclidean Integer Divisioninfixbinaryleft3
MOD Modulus of Euclidean Integer Divisioninfixbinaryleft3
AND Logical Conjunctioninfixbinaryleft3
\ Set Differenceinfixbinaryleft3
+ Arithmetic Identityprefixunarynone2
Addition, Set Unioninfixbinaryleft2
- Sign Inversionprefixunarynone2
Addition, Set Unioninfixbinaryleft2
OR Logical Disjunctioninfixbinaryleft2
& Concatenationinfixbinaryleft2
= Equality Testinfixbinarynone1
# Inequality Testinfixbinarynone1
> Greater-Than Test, Proper Superset Testinfixbinarynone1
>= Greater-Than-Or-Equal Test, Superset Testinfixbinarynone1
< Less-Than Test, Proper Subset Testinfixbinarynone1
<= Less-Than-Or-Equal Test, Subset Testinfixbinarynone1
IN Membership Testinfixbinarynone1
== Identity Testinfixbinarynone1
2015-09-22 14:02 by trijezdci -
Changed line 30 from:

Operators are special symbols or reserved words that represent an operation. An operator may be unary or binary. Unary operators are prefix, binary operators are infix. An operator may be either left-associative or non-associative and it has a precedence level between one and five, where five represents the highest level. Arity, associativity and precedence determine the order of evaluations in expressions that consist of multiple sub-expressions and may contain different operators.

to:

Operators are special symbols or reserved words that represent an operation within an expression. An operator may be unary or binary. Unary operators are prefix or postfix, binary operators are always infix. An operator may be either left-associative or non-associative and it has a precedence level between one and six, where six represents the highest level. Arity, associativity and precedence determine the order of evaluations in expressions that consist of multiple sub-expressions and may contain different operators.

2015-09-22 13:57 by trijezdci -
Changed lines 141-144 from:
The Set Difference Operator

Symbol \ denotes the set difference operator. It is left associative and requires two operands.

to:
The AND Operator

Reserved word AND denotes the logical AND operator. It is left-associative and requires two operands.

Changed line 147 from:
 setDiff := { foo, bar, baz } \ { baz }; (* set difference *)
to:
 conjunction := foo AND bar; (* logical conjunction *)
Added lines 150-160:

The operator always represents the logical conjunction operation. Its operands must be of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The AND operator is not bindable.

The Set Difference Operator

Symbol \ denotes the set difference operator. It is left associative and requires two operands.

Example:

 setDiff := { foo, bar, baz } \ { baz }; (* set difference *)
Deleted lines 231-241:
The AND Operator

Reserved word AND denotes the logical AND operator. It is left-associative and requires two operands.

Example:

 conjunction := foo AND bar; (* logical conjunction *)

The operator always represents the logical conjunction operation. Its operands must be of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The AND operator is not bindable.

2015-09-22 13:56 by trijezdci -
Changed lines 84-87 from:
The Asterisk Operator

Symbol * denotes a multi-purpose operator. It is left associative and requires two operands.

to:
The NOT Operator

Reserved word NOT denotes the logical NOT operator. It is non-associative and requires one operand. The operator precedes its operand.

Changed lines 89-91 from:

Examples:

 product := 3.0 * 5.5; (* real multiplication *)
 intersect := { foo, bar, baz } * { bar, baz, bam }; (* set intersection *)
to:

Example:

 inverse := NOT condition; (* logical negation *)
Added lines 93-104:

The operator always represents the logical negation operation. Its single operand may be any expression of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The NOT operator is not bindable.

The Asterisk Operator

Symbol * denotes a multi-purpose operator. It is left associative and requires two operands.

Examples:

 product := 3.0 * 5.5; (* real multiplication *)
 intersect := { foo, bar, baz } * { bar, baz, bam }; (* set intersection *)
Deleted lines 220-230:
The NOT Operator

Reserved word NOT denotes the logical NOT operator. It is non-associative and requires one operand. The operator precedes its operand.

Example:

 inverse := NOT condition; (* logical negation *)

The operator always represents the logical negation operation. Its single operand may be any expression of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The NOT operator is not bindable.

2015-09-22 13:55 by trijezdci -
Added line 27:

2015-09-22 13:52 by trijezdci -
Added lines 58-69:
The Pointer Dereferencing Operator

Symbol ^ denotes the pointer dereferencing operator. It is left associative and requires one operand. The operator follows its operand.

Examples:

 int := intPointer^; (* pointer dereference *)
 value := pointer^^; (* pointer to pointer dereference *)

The operator always represents the pointer dereferencing operation. Its operand must be of a pointer type. Its result type is the pointer's target type. Any use of the operator with an operand that is not a pointer type shall cause a compile time error. The pointer dereferencing operator is not bindable.

2015-09-22 13:12 by trijezdci -
Changed line 35 from:
^ Pointer Dereferencebinaryleft6 (highest)
to:
^ Pointer Dereferenceunaryleft6 (highest)
2015-09-22 13:10 by trijezdci -
Changed lines 35-36 from:
:: Type Conversionbinaryleft5 (highest)
to:
^ Pointer Dereferencebinaryleft6 (highest)
:: Type Conversionbinaryleft5
2015-09-22 12:57 by trijezdci -
Deleted line 42:
*. Dot Productbinaryleft3
Deleted lines 125-135:
The Dot Product Operator

Symbol *. denotes the dot product operator. It is left associative and requires two operands.

Example:

 dotProduct := v1 *. v2; (* dot product *)

The operator always represents the dot product operation. Its operands must be of a vector type with a cardinality of three and they must be type compatible. Its result type is the vector's component type. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The dot product operator is bindable.

2015-09-22 12:12 by trijezdci -
Changed lines 198-201 from:
The NOT Operator

Reserved word NOT denotes the logical NOT operator. It is non-associative and requires one operand. The operator precedes its operand.

to:
The Concatenation Operator

Symbol & denotes the concatenation operator. It is left-associative and requires two operands.

Changed line 204 from:
 inverse := NOT condition; (* logical negation *)
to:
 string := "foo" & "bar"; (* concatenation *)
Added lines 207-217:

The operator always represents the concatenation operation. Its operands must be collection types and their component types must be compatible. Its result type is the target type of the expression. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The concatenation operator is not bindable.

The NOT Operator

Reserved word NOT denotes the logical NOT operator. It is non-associative and requires one operand. The operator precedes its operand.

Example:

 inverse := NOT condition; (* logical negation *)
Deleted lines 321-331:
The Concatenation Operator

Symbol & denotes the concatenation operator. It is left-associative and requires two operands.

Example:

 string := "foo" & "bar"; (* concatenation *)

The operator always represents the concatenation operation. Its operands must be collection types and their component types must be compatible. Its result type is the target type of the expression. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The concatenation operator is not bindable.

2015-09-22 12:10 by trijezdci -
Added line 49:
& Concatenationbinaryleft2
Deleted line 56:
& Concatenationbinarynone1
2015-09-22 09:56 by trijezdci -
Added lines 127-137:
The Dot Product Operator

Symbol *. denotes the dot product operator. It is left associative and requires two operands.

Example:

 dotProduct := v1 *. v2; (* dot product *)

The operator always represents the dot product operation. Its operands must be of a vector type with a cardinality of three and they must be type compatible. Its result type is the vector's component type. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The dot product operator is bindable.

2015-09-22 09:50 by trijezdci -
Added lines 289-310:
The IN Operator

Reserved word IN denotes the IN operator. It is non-associative and requires two operands.

Example:

 isMember := foo IN { foo, bar, baz }; (* membership test *)

The operator always represents the membership test operation. Its right operand must be of a collection type and its left operand must be of the component type of said collection type. Its result type is BOOLEAN. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The membership operator is bindable.

The Concatenation Operator

Symbol & denotes the concatenation operator. It is left-associative and requires two operands.

Example:

 string := "foo" & "bar"; (* concatenation *)

The operator always represents the concatenation operation. Its operands must be collection types and their component types must be compatible. Its result type is the target type of the expression. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The concatenation operator is not bindable.

2015-09-22 09:42 by trijezdci -
Added lines 289-299:
The Identity Operator

Symbol == denotes the identity operator. It is non-associative and requires two operands.

Example:

 isEqual := foo = bar; (* equality test *)

The operator always represents the identity test operation. Its operands must be compatible pointer types. Its result type is BOOLEAN. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The identity operator is not bindable.

2015-09-22 09:39 by trijezdci -
Changed lines 284-285 from:
 isGreaterOrEqual := 10 >= 5; (* greater-or-equal test *)
 isSuperset := { foo, bar, baz } >= { foo, baz }; (* superset test *)
to:
 isGreaterOrEqual := 5 <= 10; (* less-or-equal test *)
 isSuperset := { foo, bar, baz } <= { foo, baz }; (* subset test *)
2015-09-22 09:38 by trijezdci -
Changed lines 244-245 from:

Symbol > denotes a dual-purpose operator. It is non-associative and requires two operands.

to:

Symbol > denotes a dual-purpose relational operator. It is non-associative and requires two operands.

Changed lines 252-288 from:

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the greater-than test operation. If it is a collection type, it represents the proper-superset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The > operator is bindable.

to:

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the greater-than test operation. If it is a set type, it represents the proper-superset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The > operator is bindable.

The >= Operator

Symbol >= denotes a dual-purpose relational operator. It is non-associative and requires two operands.

Example:

 isGreaterOrEqual := 10 >= 5; (* greater-or-equal test *)
 isSuperset := { foo, bar, baz } >= { foo, baz }; (* superset test *)

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the greater-or-equal test operation. If it is a set type, it represents the superset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The >= operator is not bindable.

The < Operator

Symbol < denotes a dual-purpose relational operator. It is non-associative and requires two operands.

Example:

 isLess := 5 < 10; (* less-than test *)
 isSubset := { foo, baz } < { foo, bar, baz }; (* proper subset test *)

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the less-than test operation. If it is a set type, it represents the proper-subset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The < operator is bindable.

The <= Operator

Symbol <= denotes a dual-purpose relational operator. It is non-associative and requires two operands.

Example:

 isGreaterOrEqual := 10 >= 5; (* greater-or-equal test *)
 isSuperset := { foo, bar, baz } >= { foo, baz }; (* superset test *)

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the less-or-equal test operation. If it is a set type, it represents the subset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The <= operator is not bindable.

2015-09-22 09:20 by trijezdci -
Added lines 242-252:
The > Operator

Symbol > denotes a dual-purpose operator. It is non-associative and requires two operands.

Example:

 isGreater := 10 > 5; (* greater-than test *)
 isSuperset := { foo, bar, baz } > { foo, baz }; (* proper superset test *)

The operator represents different operations, depending on the type of its operands. If the operand type is numeric, it represents the greater-than test operation. If it is a collection type, it represents the proper-superset test operation. Its operands must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The > operator is bindable.

2015-09-22 08:59 by trijezdci -
Added lines 219-240:
The Equality Operator

Symbol = denotes the equality operator. It is non-associative and requires two operands.

Example:

 isEqual := foo = bar; (* equality test *)

The operator always represents the equality test operation. Its operands may be of any type but must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The equality operator is bindable.

The Inequality Operator

Symbol # denotes the inequality operator. It is non-associative and requires two operands.

Example:

 notEqual := foo # bar; (* inequality test *)

The operator always represents the inequality test operation. Its operands may be of any type but must be type compatible. Its result type is BOOLEAN. Any use of the operator with incompatible operand types shall cause a compile time error. The inequality operator is not bindable.

2015-09-22 08:54 by trijezdci -
Changed line 123 from:
 setDiff := { foo, bar , baz } \ { baz }; (* set difference *)
to:
 setDiff := { foo, bar, baz } \ { baz }; (* set difference *)
2015-09-22 08:53 by trijezdci -
Added lines 116-126:
The Set Difference Operator

Symbol \ denotes the set difference operator. It is left associative and requires two operands.

Example:

 setDiff := { foo, bar , baz } \ { baz }; (* set difference *)

The operator always represents the set difference operation. Its operands must be of a set type and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a set type or with incompatible operand types shall cause a compile time error. The set difference operator is bindable.

2015-09-22 08:48 by trijezdci -
Changed lines 162-163 from:

The operator always represents the sign inversion operation. Its operands must be of a signed numeric type. Its result type is the operand type. Any use of the operator with an operand that is not a signed numeric type shall cause a compile time error. The unary minus operator operator is bindable using the +/- binding symbol.

to:

The operator always represents the sign inversion operation. Its operands must be of a signed numeric type. Its result type is the operand type. Any use of the operator with an operand that is not a signed numeric type shall cause a compile time error. The unary minus operator is bindable using the +/- binding symbol.

Changed line 174 from:

The operator always represents the subtraction operation. Its operands must be of numeric types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a numeric type or with incompatible operand types shall cause a compile time error. The - operator is bindable.

to:

The operator always represents the subtraction operation. Its operands must be of numeric types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a numeric type or with incompatible operand types shall cause a compile time error. The binary minus operator is bindable.

2015-09-22 08:46 by trijezdci -
Changed line 169 from:

Example:

to:

Examples:

Added lines 176-207:
The NOT Operator

Reserved word NOT denotes the logical NOT operator. It is non-associative and requires one operand. The operator precedes its operand.

Example:

 inverse := NOT condition; (* logical negation *)

The operator always represents the logical negation operation. Its single operand may be any expression of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The NOT operator is not bindable.

The AND Operator

Reserved word AND denotes the logical AND operator. It is left-associative and requires two operands.

Example:

 conjunction := foo AND bar; (* logical conjunction *)

The operator always represents the logical conjunction operation. Its operands must be of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The AND operator is not bindable.

The OR Operator

Reserved word OR denotes the logical OR operator. It is left-associative and requires two operands.

Example:

 disjunction := foo OR bar; (* logical disjunction *)

The operator always represents the logical disjunction operation. Its operands must be of type BOOLEAN and its result type is BOOLEAN. Any use of the operator with an operand whose type is not BOOLEAN shall cause a compile time error. The OR operator is not bindable.

2015-09-22 08:25 by trijezdci -
Changed lines 115-116 from:

The operator always represents the modulus of Euclidean integer division. Its operands must be of a whole number types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a whole number type or with incompatible operand types shall cause a compile time error. The MOD operator is bindable.

to:

The operator always represents the modulus of Euclidean integer division. Its operands must be of a whole number type and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a whole number type or with incompatible operand types shall cause a compile time error. The MOD operator is bindable.

Changed line 140 from:
 nSum := 100 + 42; (* integer addition *)
to:
 nSum := 100 + 42; (* whole number addition *)
Changed line 170 from:
 nDiff := 100 - 42; (* integer subtraction *)
to:
 nDiff := 100 - 42; (* whole number subtraction *)
2015-09-22 08:24 by trijezdci -
Added lines 146-175:
The Minus Operator

Symbol - denotes a multi-purpose operator. There are two variants:

  • unary minus
  • binary minus
The Unary Minus Operator

The unary minus operator is non-associative and requires one operand. The operator precedes its operand.

Example:

 i := -42; (* sign inversion *)

The operator always represents the sign inversion operation. Its operands must be of a signed numeric type. Its result type is the operand type. Any use of the operator with an operand that is not a signed numeric type shall cause a compile time error. The unary minus operator operator is bindable using the +/- binding symbol.

The Binary Minus Operator

The binary minus operator is left-associative and requires two operands.

Example:

 nDiff := 100 - 42; (* integer subtraction *)
 rDiff := 7.5 - 1.0; (* real number subtraction *)

The operator always represents the subtraction operation. Its operands must be of numeric types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a numeric type or with incompatible operand types shall cause a compile time error. The - operator is bindable.

2015-09-22 08:14 by trijezdci -
Added lines 133-145:
The Binary Plus Operator

The binary plus operator is left-associative and requires two operands.

Example:

 nSum := 100 + 42; (* integer addition *)
 rSum := 7.5 + 1.0; (* real number addition *)
 union := { foo, bar } + { baz, bam }; (* set union *)

The operator represents different operations, depending on the type of its operands. If the operand type is a numeric type, it represents addition. If the operand type is a set type, it represents set union. Its operands must be type compatible. Its result type is the operand type. Any use of the operator with incompatible operand types shall cause a compile time error. The binary plus operator is bindable.

2015-09-22 08:07 by trijezdci -
Changed line 111 from:

Examples:

to:

Example:

Added lines 116-133:
The Plus Operator

Symbol + denotes a multi-purpose operator. There are two variants:

  • unary plus
  • binary plus
The Unary Plus Operator

The unary plus operator is non-associative and requires one operand. The operator precedes its operand.

Example:

 n := +42; (* arithmetic identity *)

The operator always represents the arithmetic identity operation. Its operands must be of a numeric type. Its result type is the operand type. Any use of the operator with an operand that is not a numeric type shall cause a compile time error. The unary plus operator is not bindable.

2015-09-22 08:00 by trijezdci -
Changed lines 100-102 from:

Examples:

 quotient := 7.5 / 3.0; (* real division *)
 symDiff := { foo, bar, baz } / { bar, baz, bam }; (* symmetric set difference *)
to:

Example:

 quotient := 7 DIV 3; (* Euclidean integer division *)
Changed lines 112-113 from:
 quotient := 7.5 / 3.0; (* real division *)
 symDiff := { foo, bar, baz } / { bar, baz, bam }; (* symmetric set difference *)
to:
 modulus := 7 MOD 3; (* Euclidean modulus *)
2015-09-22 07:58 by trijezdci -
Changed lines 39-40 from:
DIV Euclidian Integer Divisionbinaryleft3
MOD Modulus of Euclidian Integer Divisionbinaryleft3
to:
DIV Euclidean Integer Divisionbinaryleft3
MOD Modulus of Euclidean Integer Divisionbinaryleft3
Added lines 95-117:
The DIV Operator

Reserved word DIV denotes the Euclidean division operator. It is left associative and requires two operands.

Examples:

 quotient := 7.5 / 3.0; (* real division *)
 symDiff := { foo, bar, baz } / { bar, baz, bam }; (* symmetric set difference *)

The operator always represents Euclidean integer division. Its operands must be of a whole number types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a whole number type or with incompatible operand types shall cause a compile time error. The DIV operator is bindable.

The MOD Operator

Reserved word MOD denotes the modulus operator. It is left associative and requires two operands.

Examples:

 quotient := 7.5 / 3.0; (* real division *)
 symDiff := { foo, bar, baz } / { bar, baz, bam }; (* symmetric set difference *)

The operator always represents the modulus of Euclidean integer division. Its operands must be of a whole number types and they must be type compatible. Its result type is the operand type. Any use of the operator with an operand that is not a whole number type or with incompatible operand types shall cause a compile time error. The MOD operator is bindable.

2015-09-22 07:52 by trijezdci -
Changed line 89 from:
 quotient := 7.5 * 3.0; (* real division *)
to:
 quotient := 7.5 / 3.0; (* real division *)
2015-09-22 07:51 by trijezdci -
Changed line 77 from:
 r := 3.0 * 5.5; (* real multiplication *)
to:
 product := 3.0 * 5.5; (* real multiplication *)
Added lines 80-93:

The operator represents different operations, depending on the type of its operands. If the operand type is a numeric type, it represents multiplication. If the operand type is a set type, it represents set intersection. Its operands must be type compatible. Its result type is the operand type. Any use of the operator with incompatible operand types shall cause a compile time error. The asterisk operator is bindable.

The Slash Operator

Symbol / denotes a multi-purpose operator. It is left associative and requires two operands.

Examples:

 quotient := 7.5 * 3.0; (* real division *)
 symDiff := { foo, bar, baz } / { bar, baz, bam }; (* symmetric set difference *)

The operator represents different operations, depending on the type of its operands. If the operand type is a numeric type, it represents real division. If the operand type is a set type, it represents symmetric set difference. Its operands must be type compatible. Its result type is the operand type. Any use of the operator with incompatible operand types shall cause a compile time error. The slash operator is bindable.

2015-09-22 07:43 by trijezdci -
Added lines 70-79:
The Asterisk Operator

Symbol * denotes a multi-purpose operator. It is left associative and requires two operands.

Examples:

 r := 3.0 * 5.5; (* real multiplication *)
 intersect := { foo, bar, baz } * { bar, baz, bam }; (* set intersection *)
2015-09-22 07:38 by trijezdci -
Changed line 59 from:
! The Type Conversion Operator
to:
The Type Conversion Operator
2015-09-22 03:18 by trijezdci -
Added lines 58-69:
! The Type Conversion Operator

Symbol :: denotes the type conversion operator. It is left associative and requires two operands.

Examples:

 real := int :: REAL; (* integer to real conversion *)
 bcd := real :: BCD; (* real to binary coded decimal conversion *)

The operator always represents the type conversion operation. Its left operand must be of a convertible type. Its right operand indicates the target type and must be a type identifier. Its result type is the target type. Any use of the operator with operands that do not meet these conditions shall cause a compile time error. The type conversion operator is bindable.

2015-09-22 03:07 by trijezdci -
Changed line 46 from:
- --Sign Inversionunarynone2
to:
- Sign Inversionunarynone2
2015-09-22 03:07 by trijezdci -
Changed line 45 from:
[___________Addition, Set Unionbinaryleft2
to:
Addition, Set Unionbinaryleft2
Changed line 47 from:
[___________Addition, Set Unionbinaryleft2
to:
Addition, Set Unionbinaryleft2
2015-09-22 03:06 by trijezdci -
Added lines 26-59:
Operators

Operators are special symbols or reserved words that represent an operation. An operator may be unary or binary. Unary operators are prefix, binary operators are infix. An operator may be either left-associative or non-associative and it has a precedence level between one and five, where five represents the highest level. Arity, associativity and precedence determine the order of evaluations in expressions that consist of multiple sub-expressions and may contain different operators.

An overview of operators with their operations, arity, associativity and precedence is given below:

OperatorRepresented OperationArityAssociativityPrecedence
:: Type Conversionbinaryleft5 (highest)
NOT Logical Negationunarynone4
* Multiplication, Set Intersectionbinaryleft3
/ Real Division, Symmetric Set Differencebinaryleft3
DIV Euclidian Integer Divisionbinaryleft3
MOD Modulus of Euclidian Integer Divisionbinaryleft3
AND Logical Conjunctionbinaryleft3
\ Set Differencebinaryleft3
*. Dot Productbinaryleft3
+ Arithmetic Identityunarynone2
[___________Addition, Set Unionbinaryleft2
- --Sign Inversionunarynone2
[___________Addition, Set Unionbinaryleft2
OR Logical Disjunctionbinaryleft2
= Equality Testbinarynone1
# Inequality Testbinarynone1
> Greater-Than Test, Proper Superset Testbinarynone1
>= Greater-Than-Or-Equal Test, Superset Testbinarynone1
< Less-Than Test, Proper Subset Testbinarynone1
<= Less-Than-Or-Equal Test, Subset Testbinarynone1
IN Membership Testbinarynone1
& Concatenationbinarynone1
== Identity Testbinarynone1
2015-09-21 07:51 by trijezdci -
Added lines 11-12:
Predefined Identifiers
2015-09-21 07:03 by trijezdci -
Changed line 13 from:

(To do: enter from PDF and update)

to:

(To do: enter from PDF version and update)

2015-09-21 06:35 by trijezdci -
Changed lines 6-7 from:

(Content to be moved)

to:

(To do: move and merge content)

2015-09-21 06:34 by trijezdci -
Changed line 8 from:

Scope

to:
Scope
Changed line 10 from:

Types

to:
Types
2015-09-21 06:34 by trijezdci -
Added line 14:

(To do: enter from PDF and update)

2015-09-21 06:33 by trijezdci -
Added line 32:

2015-09-21 06:32 by trijezdci -
Added lines 4-12:

(Content to be moved)

Scope

Types

2015-09-21 06:31 by trijezdci -
Changed line 4 from:

---

to:

2015-09-21 06:31 by trijezdci -
Changed line 4 from:
to:

---

2015-09-21 06:20 by trijezdci -
Added line 21:
Pragmas
2015-09-21 06:18 by trijezdci -
Changed line 3 from:
to:
2015-09-21 06:17 by trijezdci -
Added lines 1-24:

Lexis

Character Encoding
Lexical Entities?

Semantics

Compilation Units
Import of Identifiers
Definition Modules
Constant Definitions
Variable Declarations
Type Definitions
Implementation and Program Modules
Statements
Expressions
Structured Values
Blueprints
Module Type
Literal Compatibility
Constraints
Requirements

Downloads

  • Syntax Diagrams (PDF)
  • Language Report (PDF) (needs update)