[M3devel] [Fwd: Re: A nonnative 64-bit language proposal]

Tony Hosking hosking at cs.purdue.edu
Thu Jul 19 22:50:50 CEST 2007


On Jul 19, 2007, at 4:33 PM, Darko wrote:

> I actually favour a implicit conversion, which for this particular  
> case I think would be consistent with existing M3 behaviour.

There is no implicit conversion for floats.  The danger with implicit  
conversion for integers is that it would not be portable: you would  
get different behavior on different machines for the same code.   
Better to make the conversion explicit so that programmers are  
prepared for the range check to fail.

>
>
> On 19/07/2007, at 10:26 PM, Tony Hosking wrote:
>
>> This is a good question.  I would assume that conversion must be  
>> explicit to fit with the M3 philosophy.  It would make sense to  
>> have a conversion operation that performs the appropriate range  
>> check?  Any ideas for a name for the operation.
>>
>> On Jul 19, 2007, at 4:23 PM, Darko wrote:
>>
>>> Have I missed something or is there no way to assign between  
>>> INTEGER and LONGINT? Is there an explicit conversion function  
>>> that I've overlooked? Would assignment be so bad here since there  
>>> would be an implicit range check, much like when you assign  
>>> between two overlapping subranges? In a sense these two types are  
>>> integer subranges of an abstract integer type containing all  
>>> integers.
>>>
>>>
>>> n 19/07/2007, at 9:23 PM, Tony Hosking wrote:
>>>
>>>> Here are my notes from a run through the language spec.  Next  
>>>> step is to flesh out the additional bits in the compiler beyond  
>>>> what I announced yesterday.  I would appreciate any feedback you  
>>>> can give as I look into this.
>>>>
>>>> 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 may only be indexed by ordinals having an underlying  
>>>> INTEGER base type.
>>>> [Otherwise, it will be difficult deciding the index type for  
>>>> open arrays.]
>>>>
>>>> -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:
>>>>
>>>> Since INTEGER and LONGINT have different base types they are not  
>>>> assignable.
>>>>
>>>> -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
>>>>
>>>>
>>>> On Jul 19, 2007, at 1:34 PM, Rodney M. Bates wrote:
>>>>
>>>>>
>>>>>
>>>>> Tony Hosking wrote:
>>>>>> My LONGINT implementation addresses many of your concerns.   
>>>>>> The  LONGINT space is segregated from the INT space.  I want  
>>>>>> to come up  with an implementation that also permits ordinals  
>>>>>> based on LONGINT in  addition to the current system of  
>>>>>> ordinals based on INTEGER.  This  requires revisiting the  
>>>>>> language spec and pushing through the  implications.  I'm  
>>>>>> going to look at that briefly before moving on to  fixing user- 
>>>>>> level threading for all targets.
>>>>>
>>>>> By "ordinals", do you mean enumerations?  Subranges?.  In the  
>>>>> language
>>>>> definition, ordinals refers to both the above, plus INTEGER,  
>>>>> with CHAR and
>>>>> BOOLEAN being enumerations.
>>>>>
>>>>> It is hard to image a use for enumerations with more than 2^32  
>>>>> values.
>>>>> As I recall, I was thinking this would add quite a bit of  
>>>>> complexity to
>>>>> the language for negligible benefit.
>>>>>
>>>>> Subranges of LONGINT seem entirely useful and make for  
>>>>> consistency.
>>>>> From a language definition standpoint, I think these just about  
>>>>> fall
>>>>> into place with very little change.
>>>>>
>>>>> -- 
>>>>> -------------------------------------------------------------
>>>>> Rodney M. Bates, retired assistant professor
>>>>> Dept. of Computer Science, Wichita State University
>>>>> Wichita, KS 67260-0083
>>>>> 316-978-3922
>>>>> rodney.bates at wichita.edu
>>>>
>>




More information about the M3devel mailing list