Go to the previous, next section.

# Possible ISL Name Mappings for Target Languages

This note outlines a proposal for name mappings and restrictions; this proposal is not yet accepted. (Thanks to external standards such as CORBA, this proposal cannot be implemented for some languages, such as ANSI C.) The mappings outlined here are not necessarily the ones used in the current ILU release.

This proposal is about how to name things in the various programming languages, in a way that avoids name clashes. It imposes no restrictions on the ISL source. However, the mappings will be more straightforward if the ISL source avoids two things: (1) two or more concsecutive hyphens in a name, and (2) starting an interface or type name with "ilu-" (in any casing).

The first step in mapping an ISL to a programming language is to scan type and interface names for the substring "ilu-" (in any casing); wherever it occurs, we insert a trailing digit zero.

In a similar way, we next scan the name for sequences of hyphens. Wherever two or more hyphens appear consecutively, the digit zero (`0') is inserted after every other one, starting with inserting a zero after the second hyphen.

The following steps assume the first two steps have already been done.

Where tuples <N1, N2, ... Nk> of ISL names must be mapped into a flat programming namespace, we concatenate the ISL names, with a double hyphen ("--") inserted between each.

Where ISL names (or tuples thereof) must be mapped, together with ILU-chosen names derived from the ISL names, into a flat programming namespace, the derived names begin with fixed strings specific to the derivation, where the fixed strings begin with "ilu-" (with any case), and a double hyphen is inserted between the fixed string and the ISL name.

Where ISL names (or tuples thereof), and possibly ILU-chosen names derived from the ISL names, must be mapped, together with a fixed set of ILU-chosen names, into a flat programming namespace, the fixed ILU-chosen names begin with "ilu-" (with any case) and do not include a double hyphen.

The final step is to translate hyphens to underscores, for programming languages that accept underscores but not hyphens in names.

Following is a specification of how names are mapped in each language. The notation "[N]" is used to denote the application of the first two steps and the last step. Examples of "[..]" are:

    [Foo] => Foo
    [foo-bar] => foo-bar
    [wait----for--it-] => wait--0--0for--0-it-
    [iluminate] => iluminate
    [ilu--uli] => ilu-0--0uli

The mappings also use the notation "[[..]]" to denote the mapping of a type-reference.

## C mapping

[ This mapping, while clean, will never be adopted because of the more problematic mapping specified by the OMG's CORBA document. ]

Item `N` from interface `I` is mapped to `[I]__[N]`. `[[I.N]] = [I]__[N]`; `[[N]] = [I]__[N]`, where `I` is the current interface.

An enumerated value named `V`, of type `T` in interface `I` is mapped to `[I]__[T]__[V]`.

A declaration of a record type `T` in interface `I` with fields `F1:TR1`, ... `Fn:TRn` is mapped to

    typedef struct {[[TR1]] F1; ... [[TRn]] Fn} [I]__[T];

A declaration of a union type `T` in interface `I` of types `TR1`, ... `TRn` is mapped to

    typedef enum {[[I.T]]__[[TR1]], ... [[I.T]]__[[TRn]]} ilu_tags__[[I.T]];
    typedef struct {ilu_tags__[[I.T]] tag;
        union {
            [[TR1]] [[TR1]];
            ...
            [[TRn]] [[TRn]];
        } val;
    } [[I.T]];

For passing exceptions through the method calls in interface `I`, the following auxiliary declaration is generated (supposing exceptions `ER1:TR1`, ... `ER2:TR2` are raised):

    typedef struct {
        ilu_Exception returnCode;
        union {
            [[TR1]] [[ER1]];
            ...
            [[TRn]] [[ERn]];
        } val;
    } ilu_Status__[I];

An object type named `T` in interface `I` with methods `M1`, ... `Mn` maps to

    typedef ilu_Ojbect [[I.T]];
    [result-type-1] [I]__[T]__[M1]([[I.T]] ilu_self,
        [[arg-type-1-1]] [arg-name-1-1], ...
        [[arg-type-1-k]] [arg-name-1-k]);
    ...

## C++ mapping

Item `N` from interface `I` is mapped to `[I]__[N]`. `[[I.N]] = [I]__[N]`; `[[N]] = [I]__[N]`, where `I` is the current interface.

A declaration of an enumerated type named `T` in interface `I` containing values `V1`, ... `Vn` is mapped to `typedef enum {[V1], ... [Vn]} [I]__[T]`.

Record and union declarations are mapped as for C. The exception status declaration is as for C.

## Modula-3 mapping

## Mapping ILU ISL to Modula-3

Version 1 of ILU supported Modula-3, and this section describes the mapping we worked out for it.

### Names

An item named `Bar` in ISL interface `Foo` becomes an item named `Bar` in the Modula-3 interface `Foo`. A hyphen in an ISL name becomes an underscore in the corresponding Modula-3 name.

### Types

ISL types appear in Modula-3 as follows:

1. `SHORT INTEGER` becomes `[-32768 .. 32767]`.
2. `INTEGER` becomes `INTEGER`.
3. `LONG INTEGER` becomes

       TYPE LongInt = RECORD
                        high: [-16_80000000 .. 2147483647];
                        low : Word.T (*[0 ..  4294967295]*)
                      END;

   This represents the number `high*2^32 + low`. We always have the invariants `-2^31 <= high < 2^31` and `0 <= low < 2^32`, even on systems whose natural word size is greater than 32 bits.
4. `BYTE` becomes `[0 .. 255]`.
5. `SHORT CARDINAL` becomes `[0 .. 65535]`.
6. `CARDINAL` becomes `Word.T`.
7. `LONG CARDINAL` becomes `RECORD high, low: Word.T END`. This representation works analogously to that for `LONG CARDINAL`.
8. `SHORT REAL` becomes `REAL`.
9. `REAL` becomes `LONGREAL`.
10. `LONG REAL` becomes an opaque type. Values of this type can only be handed around; no other operations are provided, not even equality testing. `LONG REAL` is not really supported yet.
11. `SHORT CHARACTER` becomes `['\000' .. '\377']`.
12. `CHARACTER` becomes `[0 .. 65535]`.
13. Variable-length `ARRAY`s of `SHORT CHARACTER` become `TEXT`.
14. Other variable-length arrays become `REF ARRAY OF`.
15. Fixed-length arrays of `SHORT CHARACTER` become arrays of `BITS 8 FOR ['\000' .. '\377']`.
16. Fixed or variable-length `ARRAY`s of `BYTE` become arrays of `BITS 8 FOR [0 .. 255]`.
17. No other arrays specify packing in the Modula-3.
18. A fixed length array, `ARRAY OF L1, ... Ln`, becomes `ARRAY [0 .. L1-1] OF ... ARRAY [0 .. Ln-1] OF`.
19. An ISL record becomes a M3 record.
20. An ISL union becomes a M3 object type and some subtypes. The ISL

        TYPE Foo = DiscT UNION
            case1: T1 = val1-1, ... val1-j END,
            ...
            casen: Tn = valn-1, ... valn-k END
            END OTHERS;

    maps to the Modula-3

        TYPE Foo = BRANDED OBJECT d: DiscT END;
        TYPE  Foo_case1 = Foo BRANDED OBJECT v: T1 END;
        CONST Foo_case1__Code : DiscT = val1-1;
        ...
        TYPE  Foo_casen = Foo BRANDED OBJECT v: Tn END;
        CONST Foo_casen__Code : DiscT = valn-1;
        TYPE  Foo_OTHERS = Foo BRANDED OBJECT END;
        (* Where every Foo is of one of the subtypes enumerated here,
           and the tag field (d) is consistent with the subtype. *)

    The `Foo_OTHERS` subtype appears only for union constructions including the `OTHERS` keyword. If the ISL union has a `DEFAULT` arm

            cased: Td = DEFAULT

    it maps to another subtype in Modula-3:

        TYPE  Foo_cased = Foo BRANDED OBJECT v: Td END;

    The `Foo_casen__Code` constants are conveniences for filling in and decoding the `d` field. Note that code that creates a Foo is responsible for filling in the `d` field.
21. An ISL enumeration becomes a M3 enumeration. Due to the fact that Modula-3 offers no way to specify the codes used to represent enumerated values, the codes specified in ISL, if any, have no effect on the translation.
22. When a Foo becomes a Bar, an `OPTIONAL Foo` becomes a `REF Bar`, unless Bar is a subtype of `REFANY`, in which case `OPTIONAL Foo` becomes Bar; `NIL` encodes the `NULL` case.
23. An ISL object type becomes a Modula-3 object type. The ISL adjectives `SINGLETON`, `DOCUMENTATION`, `COLLECTIBLE`, `OPTIONAL`, `AUTHENTICATION`, and `BRAND` have no effect on the mapping into the Modula-3 type system.

    `OUT` and `INOUT` method parameters in ISL become `VAR` parameters in Modula-3; `IN` parameters become `VALUE` (by default) parameters. The `SIBLING` constraint in ISL has no manifestation in the Modula-3 type system.

    The methods are declared to raise the exceptions `IluBasics.Failed` and `Thread.Alerted` in addition to the exceptions declared in the ISL. Exception `IluBasics.Failed` is used to convey all the errors that can arise from the RPC mechanism, except `Thread.Alerted`. Is the surrogate (and the other surrogates from the same server?) broken after either of these exceptions is raised?

    Because ILU has multiple inheritance (i.e., an object type can have more than one direct supertype), the Modula-3 subtype relation is a sub-relation of the ILU subtype relation. In general, an ILU object type is mapped to a suite of Modula-3 object types, and a cohort of Modula-3 objects (one of each of the suite of Modula-3 types) correspond to one ILU object. There will be only one Modula-3 object (type) when only single-inheritance is used in constructing the ILU object type: when every ancestor type has at most one direct ancestor. Except where the programmer knows this is the case, and plans for it to remain so, she must abandon the native Modula-3 `TYPECASE`/`NARROW`/automatic-widen facilities for explicit calls that invoke the ILU subtype relation.

    To generalize the Modula-3 `TYPECASE`/`NARROW`/automatic-widen facilities, the Modula-3 object type `Ilu.Object` includes the following method:

        PROCEDURE ILU_Qua_Type(ot: ObjectType): Object;

    If the object has, in ILU, the given object type, the Modula-3 object of the appropriate Modula-3 type is returned; otherwise, NIL is returned. As an added convenience, the Modula-3 mapping of interface Foo will contain, for each of its object types Bar:

        PROCEDURE ILU_Qua_Bar(x: Ilu.Object): Bar;

    This procedure takes a non-`NIL` argument. If the argument is, in ILU, an instance of Bar or one of its subtypes, the corresponding language-specific object is returned; otherwise, `NIL` is returned.

### Exceptions

ISL exceptions are exactly like Modula-3 exceptions, and are mapped directly.

### Example

Here's a sample ISL spec, and the resulting Modula-3 mappings:

    INTERFACE Foo;

    TYPE String = ilu.CString;
    TYPE UInt = CARDINAL;

    TYPE E1 = ENUMERATION val1, val2, val3 = 40 END;
    TYPE R1 = RECORD field1 : CARDINAL, field2 : E1 END;
    TYPE FAB = ARRAY OF 200 BYTE;
    TYPE VAB = SEQUENCE OF BYTE;
    TYPE FASC = ARRAY OF 10 SHORT CHARACTER;
    TYPE VASC = SEQUENCE OF SHORT CHARACTER;
    TYPE FAC = ARRAY OF 5 CHARACTER;
    TYPE VAC = SEQUENCE OF CHARACTER;
    TYPE A2 = ARRAY OF 41, 3 R1;
    TYPE S1 = SEQUENCE OF E1;
    TYPE U1 = UNION R1, A2 END;

    EXCEPTION Except1 : String;

    CONSTANT Zero : CARDINAL = 0;

    TYPE O1 = OBJECT
        METHODS
            M1(r1: R1, INOUT v: VASC, OUT s1: S1): UInt RAISES Except1 END,
            FUNCTIONAL Hash(v: VASC): FASC,
            ASYNCHRONOUS Note(x: LONG REAL)
        END;

The Modula-3 mapping:

    INTERFACE Foo;

    IMPORT Ilu, IluBasics, Thread;
    IMPORT ilu; <*NOWARN*>

    TYPE UInt = CARDINAL;
    TYPE E1 = {
      val1,
      val2,
      val3};
    TYPE R1 = RECORD
       field1 : CARDINAL;
       field2 : E1;
    END;
    TYPE VASC = TEXT;  (* NIL not allowed *)
    TYPE S1 = REF ARRAY OF E1;  (* NIL not allowed *)
    TYPE FASC = ARRAY [0..9] OF Ilu.PackedShortChar;

    (* declaration of M3 type "Foo.O1" from ILU class "Foo:O1"  *)

    TYPE O1 = Ilu.Object OBJECT
      METHODS
        M1 (r1: R1; VAR v: VASC; VAR s1: S1): UInt
           RAISES {IluBasics.Failed, Thread.Alerted, Except1};
        Hash (v: VASC): FASC RAISES {IluBasics.Failed, Thread.Alerted};
        Note (x: Ilu.LongReal) RAISES {IluBasics.Failed, Thread.Alerted};
      OVERRIDES
        ILU_Get_Type := ILU_Get_Type_O1
      END;

    PROCEDURE ILU_SBH_To_O1 (sbh: TEXT; mostSpecificTypeID: TEXT := NIL): O1
      RAISES {IluBasics.Failed, Thread.Alerted};

    PROCEDURE ILU_Get_Type_O1 (self : Ilu.Object): Ilu.ObjectType;

    PROCEDURE ILU_Qua_O1 (x: Ilu.Object): O1;

    TYPE A2 = ARRAY [0..40] OF ARRAY [0..2] OF R1;
    TYPE  U1 = BRANDED OBJECT d: Ilu.ShortInt END;  (* NIL not allowed *)
    TYPE  U1_R1       = U1 BRANDED OBJECT v: R1 END;
    CONST U1_R1__Code : [-32768..32767] = 0;
    TYPE  U1_A2       = U1 BRANDED OBJECT v: A2 END;
    CONST U1_A2__Code : [-32768..32767] = 1;
    TYPE VAC = REF ARRAY OF Ilu.Character;  (* NIL not allowed *)
    TYPE FAC = ARRAY [0..4] OF Ilu.Character;
    TYPE VAB = REF ARRAY OF BITS 8 FOR Ilu.Byte;  (* NIL not allowed *)
    TYPE FAB = ARRAY [0..199] OF Ilu.PackedByte;
    TYPE String = TEXT;  (* NIL not allowed *)

    CONST Zero : CARDINAL = 0;

    (* Exceptions *)

    EXCEPTION Except1 (String);

    END Foo.

Go to the previous, next section.