2011-09-16

Integer Types

All integer types are defined in NINA using is range:

type identifier is range expression .. expression;

The range expressions must be static universal integer expressions.

The compiler must accept all integer type declarations, regardless of their range. Most will be mapped to an underlying hardware integer; large ones may be mapped to two or more hardware integers chained together. The compiler may use the same representation as the predefined type Unbounded_Integer (see below) for integer types that would require more than two hardware integers to be chained together.

Consider an integer type declaration:

type Name is range Low .. High;

where the range can be implemented as a single hardware integer. This is equivalent to

type Name'Base is new appropriate_hardware_integer;
subtype Name is Name'Base range Low .. High;

If Low is negative, the appropriate_hardware_integer is signed and Name'Base is (roughly) symmetrical around zero; otherwise the appropriate_hardware_integer is unsigned.

Bitwise operations (and, or, xor, not) are defined for all integer types. Shift and rotate operations are defined as attribute operations for all integer types:

T'Shift_Left   : function (Value : in T'Base; Bits : in General_Count_Type) return T'Base;
T'Shift_Right  : function (Value : in T'Base; Bits : in General_Count_Type) return T'Base;
T'Rotate_Left  : function (Value : in T'Base; Bits : in General_Count_Type) return T'Base;
T'Rotate_Right : function (Value : in T'Base; Bits : in General_Count_Type) return T'Base;

Since the type of an object is known, these are also available in Object'Operation form:

V'Shift_Left : function (Bits : in General_Count_Type) return T'Base;

and so on.

All integer types have overflow checking on the base type. For an integer type without overflow checking, one can suppress the check on the type. This results in wrap-around semantics for the base type. Suppressing checks usually results in an erroneous program, but suppressing overflow checking on an integer type is an exception.

So far we have seen only one predefined integer type:

type General_Count_Type is range 0 .. 2 ** 64 - 1;
subtype General_Index_Type is General_Count_Type range 1 .. General_Count_Type'Last;

64 bits is available on many modern processors, and chaining two 32-bit integers together should be no problem on the rest. We rarely need to count more than 2 ** 64 - 1 items, so this should be adequate for most needs, and a larger range may be declared when needed. General_Index_Type is the index type for type String.

The compiler must calculate static universal integer expressions (and subexpressions where possible) exactly, no matter how large. This implies an unbounded-integer capability bounded only by available memory. NINA requires that this capability be made available to the user as the predefined type Unbounded_Integer. Unbounded_Integer may be used the same as any other integer type.

No comments:

Post a Comment

Blog Archive