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 ARRAYs 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 ARRAYs 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.