3. TYPES -Ordinal Types: There are three kinds of ordinal types: enumerations, subranges, and integers. There are two integer types, which in order of increasing range and precision are INTEGER and LONGINT. The base type of an ordinal value 'v' is its type (INTEGER or LONGINT) if 'v' is an integer, otherwise it is the unique enumeration type that contains v. Subranges may have base type LONGINT. FIRST, LAST and NUMBER work for LONGINT. LONGINT is predeclared. Should the subrange [0..LAST(LONGINT)] be given a predeclared name? LONGCARD? -Array Types: Arrays can be indexed by all ordinals, including those with underlying LONGINT base type, however array sizes will be restricted as per usual. [The computed index for all arrays, including open, will be computed as INTEGER values, as in the current system]. -Set Types: It seems reasonable that SET OF Base, where the base type for Base is LONGINT, should be allowed. The restrictons on the number of elements in the base set remain (i.e., SET OF [0L..1023L] for elements having base type LONGINT will be practical, but not SET OF LONGINT). -Subtyping Rules: These remain the same for ordinals having LONGINT base type. 4. STATEMENTS. -Assignment: Assignment from LONGINT to INTEGER will force a range check as for assignment from subranges to INTEGER. Assignment from INTEGER to LONGINT requires no check. -For: FOR statements will function with LONGINT-based index types: FOR id := first TO last BY step DO S END where 'id' is an identifier, 'first' and 'last' are ordinal expressions with the same base type (e.g., LONGINT), step is an integer-valued expression of type INTEGER or LONGINT and S is a statement. If omitted 'step' defaults to 1 or 1L, depending on the base type of the loop bounds 'first' and 'last'. If the upper bound of the loop is LAST(INTEGER) or LAST(LONGINT), it should be rewritten as a WHILE loop to avoid overflow. -Case: CASE statements may take an expression whose type is an ordinal type with base type LONGINT. -Inc and Dec: INC and DEC function for both INTEGER-based and LONGINT-based ordinals. 7. EXPRESSIONS -Conventions for describing operations: The class 'Integer' will be used to describe the type class consisting of both INTEGER and LONGINT (similar to the use of 'Float'). -Numeric literals: Numeric literals denote constant non-negative integers or reals. The types of these literals are INTEGER, LONGINT, REAL, LONGREAL, and EXTENDED. A literal LONGINT has the same form as a literal INTEGER, except that it is suffixed with the character 'L'. Thus the LONGINT having value zero would be written '0L'. Moreover, if no explicit base is present, the value of the literal must be at most LAST(LONGINT). If an explicit base is present, the value of the literal must be less than '2^Long.Size', and its interpretation uses the convention of the 'Long' interface. -Arithmetic operations: We adjust the arithmetic operations as follows, where the type class 'Integer' can be one of INTEGER or LONGINT, FloatType represents the type of a type variable taking one of the values REAL, LONGREAL, or EXTENDED, and IntType represents the type of a type variable taking one of the values INTEGER or LONGINT. prefix + (x: Integer) : Integer (x: Float) : Float infix + (x,y: Integer): Integer (x,y: Float) : Float (x,y: Set) : Set prefix - (x: Integer) : Integer (x: Float) : Float infix - (x,y: Integer): Integer (x,y: Float) : Float (x,y: Set) : Set infix * (x,y: Integer): Integer (x,y: Float) : Float (x,y: Set) : Set infix / (x,y: Float) : Float (x,y: Set) : Set infix DIV (x,y: Integer): Integer infix MOD (x,y: Integer): Integer (x,y: Float) : Float ABS (x: Integer) : Integer (x: Float) : Float FLOAT (x: Integer; T: FloatType := REAL): T (x: Float; T: FloatType := REAL): T FLOOR (x: Float; T: IntType := INTEGER) : T CEILING (x: Float; T: IntType := INTEGER) : T ROUND (r: Float; T: IntType := INTEGER) : T TRUNC (r: Float; T: IntType := INTEGER) : T MAX, MIN (x,y: Ordinal) : Ordinal (x,y: Float) : Float -Relations These functions as expected for LONGINT. -Type operations ORD (element: Ordinal): Integer VAL (i: Integer; T: OrdinalType): T These function as expected, except that ORD returns INTEGER for elements of enumeration types. Otherwise, ORD returns an integer of the same base type as the element. Similarly, for VAL, if T is an enumeration type, then i must be an INTEGER. Thus, if 'n' is an integer of type T (INTEGER or LONGINT) then ORD(n) = VAL(n, T: IntType): = n It is a static error if 'n' is not of type 'T'. NUMBER (T: OrdinalType) : [0..LAST(LONGINT)] if BaseType(T) = LONGINT (T: OrdinalType) : [0..LAST(INTEGER)] if BaseType(T) = LONGINT (A: FixedArrayType): CARDINAL (a: Array) : CARDINAL FIRST (T: OrdinalType) : BaseType(T) (T: FloatType) : T (A: FixedArrayType): BaseType(IndexType(A)) (a: Array) : BaseType(IndexType(a)) LAST (T: OrdinalType) : BaseType(T) (T: FloatType) : T (A: FixedArrayType): BaseType(IndexType(A)) (a: Array) : BaseType(IndexType(a)) BITSIZE (x: Any) : CARDINAL (T: Type): CARDINAL BYTESIZE (x: Any) : CARDINAL (T: Type): CARDINAL ADRSIZE (x: Any) : CARDINAL (T: Type): CARDINAL 9. REQUIRED INTERFACES There is an additional required interface 'Long', analogous to 'Word' except that Long.T = LONGINT