Go to the previous, next section.

# Defining Interfaces

Module interfaces may be defined in either the Object Management Group's CORBA OMG IDL, or in ILU's native Interface Specification Language (aka ISL). This document describes the syntax and semantics of ISL, and how to translate OMG IDL interfaces into ISL; see CORBA 2.0 for a specification of the syntax and semantics of OMG IDL.

## General Syntax of ISL

The conventional file suffix for ISL files is ``.isl'`. Some of the ILU tools rely on the name of the file being the same as the name of the interface defined in it, and rely on having only one interface defined in each ``.isl'` file.

An ISL interface contains four kinds of statements: the interface header, type declarations, exception declarations, and constant declarations. Each statement is terminated with a semi-colon.

Many statements in ISL contain lists: lists of the fields in a record, the types in a union, the methods in an object type. All lists in ISL are terminated with an `END` keyword, and the items in the list are separated by commas.

Comments may be placed in an ISL file. They are introduced with the character sequence `(*`, and terminated with `*)`. Comments nest.

### Identifiers

All identifiers that appear in ISL are alphanumeric, begin with an alphabetic character, and may contain hyphens.(1) Differences in case are not sufficient to distinguish between two identifiers; however, the case of an identifier may be preserved in its mapping to a specific programming language.

All ILU type names, exception names, and constant names have two parts, an interface identifier and a local identifier. When writing the full name, the interface identifier comes first, followed by a period, followed by the local identifier. If the interface identifier is ommitted in a name, it defaults to the interface identifier of the most recently encountered interface header.

Interface names, type names, exception names, and constant names occur in different name spaces. Thus is is possible to have a type and an exception with the same name.(2)

### Reserved Words

The following words are reserved words in ISL: `[ILU]ALIASED`, `ALLOWS`, `ARRAY`, `ASYNCHRONOUS`, `AUTHENTICATION`, `BOOLEAN`, `BRAND`, `BYTE`, `CARDINAL`, `CHARACTER`, `[ILU]CHARSET`, `CLASS`, `COLLECTIBLE`, `CONSTANT`, `DEFAULT`, `[ILU]DENOMINATOR`, `[ILU]DIRECTIVE`, `[ILU]DIRECTIVE-EXPERIMENTAL`, `DOCUMENTATION`, `END`, `ENUMERATION`, `EXCEPTION`, `EXTENSIBLE`, `FALSE`, `[ILU]FIXED`, `[ILU]FIXEDPOINT`, `FROM`, `FUNCTIONAL`, `ILUSTRING`, `IMPORTS`, `IN`, `INOUT`, `INTEGER`, `INTERFACE`, `LATIN1-CHARSET`, `[ILU]LANGUAGE`, `LIMIT`, `[ILU]LOCAL`, `LONG`, `METHODS`, `MAX-NUMERATOR`, `MIN-NUMERATOR`, `OBJECT`, `OF`, `OPTIONAL`, `OTHERS`, `OUT`, `PICKLE`, `RAISES`, `REAL`, `RECORD`, `[ILU]REFERENCE`, `[ILU]SEALED`, `SEQUENCE`, `SHORT`, `SIBLING`, `SINGLETON`, `SINK`, `SOURCE`, `[ILU]STATE`, `[ILU]STRING`, `SUPERCLASS`, `SUPERCLASSES`, `SUPERTYPES`, `TRUE`, `TYPE`, `TYPEID`, `UNICODE-CHARSET`, `UNION`.

Those words prefixed with `[ILU]` will begin with the three characters `ILU` unless the configuration option --enable-new-keywords-plain has been specified in configuring your ILU distribution, in which case the `ILU` prefix will be omitted.

Reserved words may be used as identifiers, by placing them in double quotes, but may not be used as identifiers without quoting.

Other identifiers are worth avoiding, as they may cause problems with specific language implementations. The identifier `t` or `T`, for instance, causes problems with Common Lisp. Language-specific mappings of ISL should try to avoid these problems.

## Statement Syntax

### The Interface Header

Each interface is introduced with exactly one interface header of the form

    INTERFACE interface-name [ BRAND brand ] [ IMPORTS list-of-imported-interfaces END ] ;

The interface-name is used by various language-specific productions to create name spaces in which the types, exceptions, and constants defined in the interface are declared.

The optional brand is a quoted string of printable US-ASCII characters (using the codes from 0x20 to 0x7E, inclusive). It is included into the type UID hash for types and exceptions defined in the interface, and can be used to make the type UIDs for otherwise-identical interfaces distinct.

The optional list-of-imported-interfaces is a comma-separated list of fields, each of the form

    interface-name [ FROM interface-file ]

where interface-file is the name of the file containing the interface definition. Importing an interface allows the current interface to mention the types, exceptions, and constants defined in the imported interface, by referring to them as

    interface-name.type-or-value-name

The graph of imported interfaces must be acyclic; that is, interfaces may not mutually refer to each other, either directly or through some other interfaces. If the optional "FROM interface-file" is not specified for an imported interface, a sensible site-dependent search policy is followed in an attempt to locate that interface, typically looking down a path (environment variable `ILUPATH` on POSIX systems) of directories for a file with the name ``interface-name.isl'`.

### Interface Directives

Interface directives are experimental and might be changed in the next release.

After the header and before the types, an interface can have an arbitrary list of interface directives of the form

    DIRECTIVE-EXPERIMENTAL list-of-directives ;

where list-of-directives is a comma separated list of quoted strings.

In certain stubbers the list-of-directives of some directive statements may contain language specific instructions about the mapping. Tools which convey special meaning to directive statements currently ignore directive statements which are not recognized by their first quoted string. It is typical that each directive statement is recognized only by tools in a few of the ILU languages; Directive statements influence mapping within one address space but unless understood by all languages don't change the inter address space interfaces.

### Type Declarations

In general, a type is defined with a statement of the form

    TYPE type-name = type-reference | construction [ TYPEID type-id-string ] ;

The form `TYPE type-name = type-reference` is used when you want to rename an existing type to make its usage clear or give it a name in the current interface. A type-reference is just a type-name, or a reference to a type name defined in another interface: interface-name.type-name. The new name is then a `nickname' for the previously defined type.

The optional `TYPEID` attribute is provided for use with CORBA interfaces, which allow specification of type ID information. Type IDs should conform to the syntax for URIs. It's probably safest not to use `TYPEID`, as ILU will automatically generate unique type ID's for your types.

#### Primitive types

The following type "names" are pre-defined:

- `INTEGER,` a 32-bit signed integer value;
- `SHORT INTEGER,` a 16-bit signed integer value;
- `LONG INTEGER,` a 64-bit signed integer value;
- `CARDINAL,` a 32-bit unsigned integer value;
- `SHORT CARDINAL`, a 16-bit unsigned integer value;
- `LONG CARDINAL`, a 64-bit unsigned integer value;
- `BYTE`, an unsigned 8-bit byte value;
- `BOOLEAN`, a logical value either True or False;
- `REAL`, an IEEE 64-bit double-precision floating-point value;
- `SHORT REAL`, an IEEE 32-bit single-precision floating-point value;
- `LONG REAL`, a 128-bit quadruple-precision floating-point value;
- `CHARACTER`, a 16-bit UNICODE/IS-10646 character; and
- `SHORT CHARACTER`, an 8-bit ISO 8859-1 character code (but excluding the octet 8_000).
- `PICKLE`, an opaque value containing some other value (see below).

There is also a special type `NULL`, which cannot be used directly; it has a single value, NULL.

``PICKLE`` is an abstract type, values of which contain a `pickled' or `frozen' value of any other ISL type, and is thus used when a dynamically typed element is needed in an interface. Functionally, it is quite similar to the CORBA ``any`` type, but has more efficient semantics. ``PICKLE`` is only available if ILU has been configured with VARIANT support.

#### Constructor overview

The form ``TYPE` type-name = construction` is used when a user needs to define a new type. Several simple constructors for more complex data types are specified:

- `ARRAY`, a fixed-length N-dimensional array of some specified type;
- `SEQUENCE`, a variable-length one-dimensional array of some specified type;
- `RECORD`, a sequence of typed fields, each of which may be of a different type;
- `UNION`, one of a set of specified types;
- `OPTIONAL`, a union with `NULL`;
- `ENUMERATION`, a type consisting of an explicitly enumerated set of values;
- `OBJECT`, an ILU object type.
- `FIXEDPOINT`, a rational type with a fixed denominator value (not yet implemented);

In addition, the automatically-imported interface ILU defines the short sequence `CString` of short character.

#### Array Declarations

An `ARRAY` is a fixed-length N-dimensional array of some type. It is defined with a declaration of the form

    TYPE type-name = ARRAY OF dimension-list base-type-reference ;

where dimension-list is a comma-separated list of non-negative integers, each integer specifying the size of a dimension of the array, and base-type-reference is a type-reference to some other ILU type. For example,

    TYPE SymbolTable = ARRAY OF 400 Symbol;
    TYPE Matrix3030 = ARRAY OF 30, 30 REAL;

The total number of elements in the array may not exceed 4294967295 (2^32-1).

#### Sequence Declarations

A sequence is a variable-length one-dimensional array of some type. It is defined with a declaration of the form

    TYPE type-name = [ SHORT ] SEQUENCE OF base-type-reference [ LIMIT size ] ;

where base-type-reference is a type-reference to some other ILU type. If the `LIMIT` parameter size is used, it limits the sequences to having at most size elements; otherwise the sequences are limited to having at most 4294967295 (2^32-1) elements. Use of the `SHORT` modifier is shorthand for a `LIMIT` of 65535 (2^16-1). Use of the `LONG` modifier is not defined for sequences.

#### Generalized Array Declarations

This is a proposed language change, not yet accepted. It is not supported in any of the language bindings.

The existing language has a weakness: it cannot express coordinated multidimensional variable-length arrays. Coordinated means that there is only one length per dimension, regardless of how many arrays there are at that level. An example is a bitmap of variable height and width: all rows are the same length, and all columns are the same length.

A generalized array type is defined with a declaration of the form

    TYPE type-name = ARRAY dim , ... dim OF base-type-reference ;

where each dim is of the form

    length | [ LIMIT maxlen | SHORT ]

A dimension can be given a fixed length by simply specifying that length. A variable-length dimension is either left blank (meaning the maximum length is 2**32-1), specified as `SHORT` (meaning the maximum length is 2**16-1), or given an explicit maximum length.

Note that putting the dimensions after the `OF` would create a syntactic ambiguity in some cases, concerning grouping of a `SHORT`.

#### Record Declarations

    TYPE type-name = RECORD fields... END ;

where fields is a comma-separated list of field, which has the form

    field-name : field-type-reference

A sample record declaration:

    TYPE Symbol = RECORD
      name : string,
      ltype : TypeInfo,
      address : cardinal
    END;

#### Union Declarations

A union is a type which may take on values of several different types. To be compliant with the CORBA notion of unions, the union declaration is much more baroque and complicated than it really should be. The declaration has the form:

    TYPE type-name = [ tag-type ] UNION arm-list END [ OTHERS ] ;

where arm-list is a comma-separated list of arm, each of the form:

    [ union-case-name : ] type-name [ arm-valuator ]

where each arm-valuator is either of the form

    = DEFAULT

or of the form

    = value-list END

and where a value-list is a comma-separated list of constant values of the tag type. The tag type must be one of: `SHORT INTEGER`, `SHORT CARDINAL`, `INTEGER`, `CARDINAL`, `BYTE`, `BOOLEAN`, or an enumerated type. (We should also allow `SHORT CHARACTER` and `CHARACTER`.) The tag type is `SHORT INTEGER` if not explicitly specified.

A arm-valuator must be given for either all or none of the arms; if none, the arms are assigned single integral values, starting with 0. arm-valuators must be given if the tag type isn't numeric. All the values appearing in the value-lists of a union must be different from one another. `DEFAULT` can appear in at most one arm of a union type construction. `DEFAULT` and `OTHERS` cannot both appear in the same union.

A union value consists of a tag value, possibly paired with a second value. When the tag value is one that appears in, or is implicitly assigned to, an arm of the union type construction, the second value is of the type named in that arm. Otherwise, the union value is well-formed only if `DEFAULT` or `OTHERS` appears in the union type construction. If an arm is valued with `DEFAULT`, the second value is of that arm's type. If `OTHERS` appears, there is no second value; it is as if there were a default arm of some trivial type (like C's `void` or ML's `unit`).

A simple example:

    TYPE StringOrInt = UNION ilu.CString, CARDINAL END;

A more complex example, that uses an explicit tag type, union case names, and a default arm:

    TYPE ColorType = ENUMERATION RGB, CMY, HSV, YIQ, HLS END;
    TYPE U2 = ColorType
      UNION
        rgb-field : RGBObject = RGB END,
        others : COLORObject = DEFAULT
      END;

The union case name is not guaranteed to be present in language-specific mappings.

ISL unions are logically (and sometimes actually, depending on the programming language) tagged. There is a difference between

    TYPE T1 = UNION Bar, Baz END;
    TYPE T2 = UNION Foo, T1 END;

and

    TYPE T1 = UNION Bar, Baz END;
    TYPE T2 = UNION Foo, Bar, Baz END;

#### Optional Declarations

A variable of type ``OPTIONAL` Foo` can have either a value of `Foo` or of type `NULL`. It is declared with the form

    TYPE type-name = OPTIONAL base-type-reference ;

This should be thought of as roughly equivalent to the declaration

    TYPE type-name = BOOLEAN UNION base-type-reference = TRUE END END OTHERS ;

The difference is that `OPTIONAL` types are logically un-tagged. An optional value is not a pair of (`BOOLEAN`, base-type-reference); rather it is a single value, either a special, distinguished, "null" value or a value of the base-type-reference. There is thus no difference between

    TYPE Bar = OPTIONAL Foo;
    TYPE Baz = OPTIONAL Bar;

and

    TYPE Bar = OPTIONAL Foo;
    TYPE Baz = OPTIONAL Foo;

This type is not yet implemented.

#### Enumeration Declarations

An enumeration is an abstract type whose values are explicitly enumerated. It is declared with the form

    TYPE type-name = ENUMERATION values... END ;

where values is a comma-separated list of value names, with optional value ID's that are constants of type `SHORT CARDINAL` that specify the value used to represent the enumeration value "on the wire".(3) Use of value ID's is deprecated.

    value-name [ = value-id ]

For example,

    TYPE TapeAction = ENUMERATION
      SkipRecord = 1,
      Rewind = 23,
      Backspace = 49,
      WriteEOF = 0
    END;

All value-names and value-IDs must be unique within an enumeration. If value-IDs are not assigned explicitly, appropriate values will be assigned automatically in some unspecified way. An enumeration may have at most 65535 (2^16-1) values.

#### Object Type Declarations

Object types are described in the following way:

    TYPE type-name = OBJECT
                            [ SINGLETON protocol-description-string ]
                            [ DOCUMENTATION documentation-string ]
                            [ COLLECTIBLE ]
                            [ OPTIONAL ]
                            [ TYPEID type-id-string ]
                            [ SUPERTYPES supertype-list END ]
                            [ METHODS method-list... END ]
                            [ BRAND brand-string ] ;

The keyword `CLASS` is a deprecated synonym for `OBJECT`, and `SUPERCLASSES` is a deprecated synonym for `SUPERTYPES`. Also,

                            [ SUPERCLASS supertype-name ]

is a deprecated equivalent to

                            [ SUPERTYPES supertype-name END ]

The `SINGLETON` keyword specifies that instances of this type are singleton servers, and implies that the discriminator object (the subject of the call) should not be implicitly marshalled as the first argument in an RPC. This is typically used in describing an instance of an existing RPC service, which is to be modelled in ILU. The argument to `SINGLETON` is a string in the form of ILU "protocol-info", which specifies particular protocol-specific parameters to be used in implementing this object type `on the wire'. For example, the Sun RPC calendar manager would use a protocol-description-string of `"sunrpc_2_100068_3"`, indicating that it uses a Sun RPC program number of 100068 and a Sun RPC version of 3.

The optional documentation-string is a quoted string, which is passed on to language-specific bindings where possible, such as with the doc-string capability in Common Lisp.

The `COLLECTIBLE` keyword specifies that instances of this type are meant to be garbage collectible, and that methods necessary for this should be automatically added to its method suite. For an object type to be collectible, all ancestor object types must also be collectible.

The `OPTIONAL` keyword specifies that the language-specific `nil` value may be passed, instead of an instance of this object type, anywhere this object type is used. This is a CORBA mis-feature, and its use is strongly deprecated. Better to explicitly use a different type constructed with the ILU `OPTIONAL` keyword.

The optional supertype-list defines an inheritance relationship between the object types named in the list and the type type-name.

The optional type-id-string can be used to explicitly assign an MSTID for an object type. Doing so effectively seals the object type; that is, changes to the structure of the object type will not be reflected in the MSTID, so version mismatches will not be caught automatically by ILU. This is a dangerous feature (mandated by CORBA).

The brand-string in the `BRAND` clause, if any, contributes an arbitrary tag to the structure of the type; omitting the `BRAND` clause is equivalent to giving one with the empty string. The brand is included in the type UID hash of the type, and thus gives the programmer a way to make two types distinct despite their otherwise having the same structure. The brand-string should be a quoted string of printable US-ASCII characters.

The method-list is a comma-separated list of procedure descriptions. All the methods of an object type have distinct names. This means that independently-developed supertypes might not be usable together.

Methods have the syntax:

    [ FUNCTIONAL ] [ ASYNCHRONOUS ] method-name ( [ args... ] )
            [ : return-type-reference ]
            [ RAISES exceptions... END ]
            [ = procedure-id ]
            [ documentation-string ]

where the discriminator (the implicit first argument to the method, the subject of the call, an instance of the object type in question) is not explicitly listed in the signature. Each method has zero or more arguments in a comma-separated list, each element of which is a colon-separated two-ple

    [ argument-direction ] argument-name : [ SIBLING ] argument-type-reference

The `SIBLING` keyword may only appear on arguments of an object type, to indicate that the argument should be a sibling object to the discriminator of the method. The `FUNCTIONAL` keyword indicates that the method, for a given set of arguments, is idempotent (i.e., the side effects of one call are the same as the side effects of more than one call) and will always return the same result (or raise the same exception); this information may be used for caching of return values in the client side stubs. The optional argument-direction information is one of the three keywords `IN`, `OUT`, `INOUT`, specifying whether the parameter is being used as an input parameter, an output parameter, or both.

A method return type is allowed (again separated from the procedure argument list by a colon), and a list of possible exceptions may be specified as a comma-separated list of exception names, bracketed with the keywords RAISES and END.

The optional procedure-id field allows a service description to specify the procedure code that is used in the RPC request packet for this method. Procedure ID's are restricted to the range [0,65279], and must be unique within an interface. This may only be used in methods on objects marked with the `SINGLETON` attribute.

If a method is marked with the `ASYNCHRONOUS` keyword and does not return a value or raise an exception, the RPC method call of a surrogate instance will return after sending the request packet to the RPC partner, as the success of the call does not depend on the completion of the associated code. Other RPC methods will block in such a way as to allow the scheduler to handle other events while it is waiting for the call to complete, if the user has registered the appropriate scheduler hooks with the ILU runtime.

The optional documentation-string is a quoted string, which is passed on to language bindings for which it is meaningful, such as the doc-string capability in Common Lisp.

For example:

    TYPE FancyString = OBJECT
      METHODS
        FUNCTIONAL Length () : cardinal,
        Substring (start : cardinal, end : cardinal) : string
          RAISES StartGreaterThanEnd, StartTooLarge, EndTooLarge END,
        Char (index : cardinal) : character
          RAISES BadIndex END
      END;

Note that the object language in ILU is not intended to be used to fully define an object type, but rather to describe it in a simple language that can be transformed into the different object type definition systems of several other languages.

#### Fixed-point Declarations

A `FIXEDPOINT` type is a rational type with a fixed denominator. It is defined with a declaration of the form

    TYPE type-name = FIXEDPOINT [ MIN-NUMERATOR min-num-value ] [ MAX-NUMERATOR max-num-value ] [ DENOMINATOR denom-value ] ;

where denom-value specifies the denominator of all values of the type, the optional min-num-value specifies the minimum numerator value allowed for values of the type, and the optional max-num-value specifies the maximum numerator value allowed for values of the type. If denom-value is negative, it is interpreted as the reciprocal of its absolute value. If either min-num-value or max-num-value is not specified, the numerator value is not bounded in that direction. If the denominator is not specified, it defaults to 1.

This type is still experimental and may not be supported in any of the ILU language bindings.

### Exception Declarations

Exceptions in ILU are raised by ILU methods. They allow error conditions to be signalled back to the calling code. They are declared with a statement of the form:

    EXCEPTION exception-name [ : type-reference ] [ documentation-string ] ;

The optional type-reference part of the declaration allows the exception to have an associated value, to be used in interpretation of the exception. For example, an exception BadFilename might have the type `ilu.CString`, so that the actual bad filename can be associated with the exception:

The optional documentation-string is a quoted string, which is passed on to language bindings for which it is meaningful, such as the doc-string capability in Common Lisp.

    TYPE Filename = ilu.CString;
    EXCEPTION BadFileName : Filename "The value is the bad filename";

Because of the uncertain nature of life in distributed systems, the pre-defined exception `ilu.ProtocolError` (defined in the ILU interface) may be raised by any method, to indicate that the method could not be handled, for some reason. It has the following form:

    TYPE ProtocolErrorDetail = ENUMERATION
                    NoSuchClassAtServer = 1,
                    BrandMismatch = 2,
                    NoSuchMethodOnClass = 3,
                    InvalidArguments = 4,
                    UnknownObjectInstance = 5,
                    UnreachableModule = 6,
                    RequestRejectedByModule = 7,
                    TimeoutOnRequest = 8,
                    UnknownError = 9
            END;

    EXCEPTION ProtocolError : ProtocolErrorDetail;

Signalling of `ProtocolError` is never done by user-written server code; it is reserved to the transport and runtime layers of ILU.

### Constant Declarations

For convenience of interface design, constant values for certain simple types may be defined in ISL with statements of the form

    CONSTANT constant-name : constant-type = constant-value ;

#### Integer, Cardinal, and Byte Constants

A constant-value for types that are sub-types of `INTEGER`, `CARDINAL`, or `BYTE` is specified with the syntax

    [ sign ] [ base-indicator ] digits

where the optional base-indicator allows selection of bases 2, 8, 10 or 16. It is a digit '0' (zero) followed by either the character 'B' for base 2, 'X' for base 16, 'O' (oh) for base 8, or 'D' for base 10. The sign is only valid for subtypes of `INTEGER`; it is either '+' or '-'; if not specified, '+' is assumed. The base-indicator and digits fields are case-insensitive.

#### Real Constants

A constant-value for subtypes of `REAL` has the syntax:

    [ sign ] integer.fraction [ e exponent ]

where integer and fraction are sequences of decimal digits, sign is either '+' or '-' ('+' is the default), and exponent is the power of 10 which the rest of the value is multiplied by (defaults to 0).

#### ilu.CString Constants

A constant-value for a sub-type of `ilu.CString` has the form

    "characters"

where characters are any ISO-Latin-1 characters except for 8_000. The escape character is defined to be '#' (hash). The escape character may occur in the string only in the following ways:

    #" -- a single double-quote character
    ## -- a single escape character
    #hex-digithex-digit -- the octet 16_hex-digithex-digit
    #n -- newline
    #r -- carriage return

#### Examples of Constants

    CONSTANT Newline : byte = 10;
    CONSTANT Pi : short real = 3.14159;
    CONSTANT Big : long real = -1.1349e27;  (*  -1.1349 * 10**27   *)
    TYPE Filename = ilu.CString;
    CONSTANT MyLogin : Filename = "~/.login";
    CONSTANT Prompt : ilu.CString = "OK#n ";
    CONSTANT HeapBound : cardinal = 0xFFFF39a0;
    CONSTANT Pattern1 : cardinal = 0b000001000001;

## ilu.isl

The standard interface `ilu` can be found in the file ``ILUHOME/interfaces/ilu.isl'`; it is maintained as ``ILUHOME/src/stubbers/parser/ilu.isl'`. Here are its contents:

    INTERFACE ilu BRAND "version 2";

    (*
    Copyright (c) 1991-1997 Xerox Corporation.  All Rights Reserved.

    Unlimited use, reproduction, and distribution of this software is
    permitted.  Any copy of this software must include both the above
    copyright notice of Xerox Corporation and this paragraph.  Any
    distribution of this software must comply with all applicable United
    States export control laws.  This software is made available AS IS,
    and XEROX CORPORATION DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
    INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS FOR A PARTICULAR PURPOSE, AND NOTWITHSTANDING ANY OTHER
    PROVISION CONTAINED HEREIN, ANY LIABILITY FOR DAMAGES RESULTING FROM
    THE SOFTWARE OR ITS USE IS EXPRESSLY DISCLAIMED, WHETHER ARISING IN
    CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, EVEN IF
    XEROX CORPORATION IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

    $Id: isl.tim,v 1.54 1999/08/03 01:56:51 janssen Exp $
    *)

    TYPE CString = SEQUENCE OF SHORT CHARACTER;

    TYPE CORBA-Object = OBJECT OPTIONAL TYPEID "IDL:omg.com/CORBA/Object:1.0";

## Using OMG IDL with ILU

ILU allows the use of CORBA OMG IDL (4) instead of ILU ISL. It does this by translating the OMG IDL to its equivalent form in ISL. Most ILU tools will do this automatically, based on whether the suffix of the filename argument is ``.isl'` or ``.idl'`. In addition, the program `idl2isl` can be invoked explicitly to create an ISL version of an OMG IDL interface file. The program idl2isl translates from IDL to ISL. IDL is the Interface Definition Language defined by the Object Management Group.(5)

### Translation

On the whole, the translation from IDL to ISL is a straightforward change of syntax. There are a few cases, however, where a bit more is needed.

#### Anonymous types

OMG IDL allows type declarators to be used in certain places in the syntax (for example, struct members and operation parameters). ISL does not; it requires a type name in the corresponding situations. As a result, it is sometimes necessary for the translator to introduce a name in the ISL output for those types that are anonymous in the OMG IDL input. These names are always of the form `AnonType-nnn-`, where nnn is an integer.

For example, the OMG IDL declaration

    struct str {
    	long	f1;
    	long	f2[5];
    };

is translated into the following ISL:

    TYPE AnonType-1- = ARRAY OF 5 INTEGER;
    TYPE str = RECORD
    	f1 : INTEGER,
    	f2 : AnonType-1-
    	END;

#### Topmodules mode

When the translator is in this mode (which it is by default), only `module` declarations are allowed at the topmost level. Each `module` translates into an `INTERFACE` declaration in ISL, and the declarations inside each `module` go into the corresponding ISL `INTERFACE`.

If the translator is not in this mode, all the declarations in the IDL file go into one ISL `INTERFACE` whose name is taken from the OMG IDL input filename, less the ``.idl'` suffix.

#### Imports mode

When the translator is in this mode (which it is by default), `#include` preprocessor directives are, roughly speaking, turned into ISL `IMPORT` statements. This mode allows for separate compilation (stub generation) of interfaces. There are some restrictions: the `#include` directives must occur before any declarations in the file, and the files that are included must not be fragments. That is, each must consist of a sequence of whole declarations (more specifically, `module` declarations if in `topmodules` mode). The included files may in turn include other files.

If the translator is not in this mode, the input is considered to be the result of preprocessing the file first and textually substituting the included files, following the usual behavior of C and C++ compilers.

#### Unsupported constructs

If VARIANT support has not been configured in, the IDL type `any` is disallowed by the translator.

Use of `context` clauses on operations is not supported.

### Manual Invocation of `idl2isl`

The program is run automatically as an intermediate step by any of the ILU tools that take ISL files (normally ending in ``.isl'`) if the filename ends in ``.idl'`.

The program may also be run directly, with the following arguments:

    idl2isl { -Wb,toggle | -Wb,!toggle }* source.idl

In this case, it writes the ISL to its standard output. A toggle is set with an argument `-Wb,toggle` and cleared with an argument `-Wb,!toggle`. Toggle settings may also be effected by setting the environment variable ``IDL2ISL_OPTS'` to a comma-separated list of toggle names, each of which is either preceded by a ``!'` character (which clears it) or not (which sets it). Command-line arguments take precedence over the environment variable settings.

The toggles are:

- `dump` (default off): produce a dump of the abstract syntax tree. Used for debugging the translator itself.
- `imports` (default on): set the `imports` mode on (explained below).
- `topmodules` (default on): set the `topmodules` mode on (explained below).

## ISL Grammar

In this grammar, parentheses are used for grouping, vertical-bar indicates selection, braces indicated optionality, quotation marks indicate literal keywords or literal punctuation.

No whitespace is allowed between the parts of a `radix`, `number`, or `quoted-string`. Aside from that, whitespace is used to separate fields where necessary, and excess whitespace is ignored outside of `quoted-string`s.

Three primitives are used:

- name-string, which is a string consisting of decimal digits, upper and lower-case letters, and hyphens, beginning with a letter. It may not be a keyword, unless it is quoted with double-quotes.
- string, which is any sequence of characters.
- digits, which is a sequence of digits drawn from the digits for the particular radix. The default radix is decimal.

    interface = interface-def | interface interface-def

    interface-def = interface-declaration interface-directive-list other-declarations

    interface-declaration = "INTERFACE" name-string
                            [ "BRAND" brand-string ]
                            [ "IMPORTS" import-list "END" ]
                            ";"

    import-name = name-string [ "FROM" filename ]

    import-list = import-name | import-list "," import-name

    interface-directive-list = [ interface-directive interface-directive-list ]

    interface-directive = "DIRECTIVE-EXPERIMENTAL" quoted-string-list ";"

    quoted-string-list = quoted-string | quoted-string-list "," quoted-string

    other-declarations = [ other-declaration other-declarations ]

    other-declaration = constant-decl | exception-decl | type-decl

    constant-decl = "CONSTANT" name-string ":" ( integer-const
                                               | cardinal-const
                                               | boolean-const
                                               | byte-const
                                               | float-const
                                               | string-const ) ";"

    integer-const = [ "SHORT" | "LONG" ] "INTEGER" "=" [ sign ] number

    boolean-const = "BOOLEAN" "=" boolean-value

    cardinal-const = [ "SHORT" | "LONG" ] "CARDINAL" "=" number

    byte-const = "BYTE" "=" number

    float-const = [ "SHORT" | "LONG" ] "REAL" "="
                  [sign] digits [ "." digits ] [ "e" digits ]

    number = [ radix ] digits

    radix = "0" ( binary | octal | hexadecimal )

    binary = "b"

    octal = "o"

    hexadecimal = "x"

    string-const = "ilu.CString" "=" quoted-string

    exception-decl = "EXCEPTION" excp-name [ ":" type ] [ typeid ] [ doc-string ] ";"

    excp-name = name-string

    type-decl = "TYPE" name-string "=" ( type | type-cons ) [ typeid ]";"

    type = primitive-type-name | [ name-string "." ] name-string

    typeid = "TYPEID" type-id-string

    primitive-type-name = "BYTE"
                        | [ "SHORT" | "LONG" ] "CARDINAL"
                        | [ "SHORT" | "LONG" ] "INTEGER"
                        | [ "SHORT" | "LONG" ] "REAL"
                        | [ "SHORT" ] "CHARACTER"
                        | "BOOLEAN"
                        | "PICKLE"

    type-cons =   record-cons
                    | array-cons
                    | sequence-cons
                    | union-cons
                    | optional-cons
                    | enum-cons
                    | object-cons

    record-cons = "RECORD" field-list "END"

    field-list = field | field-list "," field

    field = name-string ":" type

    sequence-cons = [ "SHORT" ] "SEQUENCE" "OF" type [ "LIMIT" number ]

    array-cons = "ARRAY" "OF" dimensions-list type

    dimensions-list = number | dimensions-list "," number

    union-cons = [ int-enum-or-boolean-type ] "UNION" union-field-list "END"

    union-field-list = union-field | union-field-list "," union-field

    union-field = [ field-name-string ":" ] type [ "=" const-list "END" ]

    const-list = const | const-list "," const

    const = number | enum-field-name | boolean-value

    enum-cons = "ENUMERATION" enum-field-list

    enum-field-list = enum-field | enum-field-list "," enum-field

    enum-field = string

    boolean-value = "TRUE" | "FALSE"

    optional-cons = "OPTIONAL" type

    object-cons = "OBJECT" object-attributes

    object-attributes = object-feature | object-attributes object-feature

    object-feature =  "SINGLETON" singleton-protocol-info
                    | "COLLECTIBLE"
                    | "OPTIONAL"
                    | "DOCUMENTATION" doc-string
                    | "BRAND" brand-string
                    | "SUPERTYPES" supertype-list "END"
                    | "METHODS" method-list "END"

    supertype-list = type | supertype-list "," type

    singleton-protocol-info = quoted-string

    method-list = method | method-list "," method

    method = [ "FUNCTIONAL" | "ASYNCHRONOUS" ] name-string
             arguments [ ":" return-type ] [ "RAISES" exception-list "END"]
             [ doc-string ]

    return-type = type

    exception-list = excp-name | exception-list "," excp-name

    arguments = "(" [ argument-list ] ")"

    argument-list = argument | argument-list "," argument

    argument = [ "IN" | "OUT" | "INOUT" ] name-string ":" [ "SIBLING" ] type

    brand-string = printable-ascii-quoted-string

    doc-string = quoted-string

    quoted-string = "\"" string "\""

    printable-ascii-quoted-string = "\"" string consisting of only printable ASCII characters "\""

    type-id-string = "\"" scheme-name ":" string "\""

    scheme-name = string-without-colon-char

Go to the previous, next section.