[M3devel] INTEGER
Tony Hosking
hosking at cs.purdue.edu
Mon Apr 19 02:38:43 CEST 2010
Mika,
First off, I'd be very interested to know what the issues are with LONGINT and stubgen. We are building that every day in regression testing. It would be really good to get some precise feedback.
True, LONGINT is integrated with all of the language tools (same as WIDECHAR).
I suppose that is the price we pay for the language having evolved. Nevertheless, CM3 should be totally backward compatible with the green book. There is no reason it should not build packages from PM3 or SRC.
Now, this is not to say that perhaps we haven't overreached with LONGINT given that 64-bit is more prevalent. But then it is also useful to be able to interoperate with C libraries. The previous interfacing was pretty much a kludge, using ARRAY[0..1] OF INTEGER for "long long" but then not propagating the double INTEGER value properly throughout the Modula-3 libraries.
I'm sorry to say that EWD was not particularly renowned for his practicality; pedant more like. Nice to be high and mighty but we also need to interact with the real world.
We should be able to make this work. Is there a better alternative? Revoke LONGINT, and WIDECHAR?
On 18 Apr 2010, at 15:59, Mika Nystrom wrote:
>
> My problem is really just that it's ugly. LONGx is showing up as an issue
> in all sorts of low-level code, which is not surprising since Modula-3
> with LONGx is not the same language as Modula-3 (maybe we should call
> it Modula-3+?)
>
> The compiler bootstrapping process has gotten more complicated due to it,
> and when I cvs updated m3tk yesterday stubgen wouldn't compile because there
> was something "long" in it that wasn't there before. I have no idea what
> library or components I needed to update and recompile and didn't have the
> time to deal with the issue at the time.
>
> And the new m3tk, stubgen, and compiler(?) won't compile using PM3 or
> SRC M3 since we're no longer using the language of the Green Book.
> (Same comment goes for WIDECHAR, by the way.)
>
> One of the wonderful things about Modula-3 *used to be* that I could
> grab some old package from DECSRC and just use it without changes since
> no one had messed with the language definition. This is still true as
> far as programs that just use the tools go, but it's no longer true for
> programs that process Modula-3 code as input data. Of which there are
> more than a few: many aspects of Modula-3 were specifically designed to
> make the language easy to process by program, as an intermediate format
> and whatnot.
>
> To quote E.W.D.:
>
> 'Unfathomed misunderstanding is further revealed by the term "software
> maintenance", as a result of which many people continue to believe that
> programs and even programming languages themselves are subject to wear
> and tear. Your car needs maintenance too, doesn't it? Famous is the story
> of the oil company that believed that its PASCAL programs did not last
> as long as its FORTRAN programs "because PASCAL was not maintained".'
>
> LONGx is causing me to have to do "software maintenance" on Modula-3
> programs... for a feature that no one appears to be using and is quickly
> becoming irrelevant.
>
> Mika
>
>
> Tony Hosking writes:
>> In the language spec NUMBER(a) and LAST(a) - FIRST(a) + 1 are *not* =
>> defined to mean the same thing for all types.
>> NUMBER does have an INTEGER value, as expected for subranges of LONGINT =
>> that are not too large.
>> This is as it has always been for subranges of INTEGER that are not too =
>> large.
>>
>> Mika, I'm not sure I see any of the problems you are worrying about in =
>> the current definition of LONGINT/LONGCARD.
>>
>> On 18 Apr 2010, at 03:49, Mika Nystrom wrote:
>>
>>> =20
>>> Jay I know most of this, and it doesn't really answer the question
>>> "what is it for?"
>>> =20
>>> I think we've already established that LONGINT isn't useful for =
>> counting
>>> anything that might actually reside in the computer's memory: it makes
>>> no sense as an array index, for instance. INTEGER suffices for that.
>>> =20
>>> I thought that the only real reason for LONGINT was to match C's
>>> declaration of various seek-related routines on 32-bit machines.
>>> That's not a very good reason.
>>> =20
>>> C++ succeeds because it does very well in the area(s) it is good at.
>>> People who want to program in C++ will clearly program in C++, not
>>> Modula-3. Modula-3 is never, ever going to be the language of choice =
>> for
>>> people who want lots of snazzy infix operators. Modula-3 is supposed =
>> to
>>> be a language with about as powerful semantics as C++ and an extremely
>>> simple syntax and definition---snazzy infix is one of the things you
>>> give up for that. I don't see how LONGINT fits into this picture.
>>> Now we have LONGCARD too? And it's infected the definitions
>>> of FIRST and LAST? But not NUMBER... argh!
>>> =20
>>> so,
>>> =20
>>> NUMBER(a) and LAST(a) - FIRST(a) + 1
>>> =20
>>> no longer mean the same thing? Are we going to see lots of comments
>>> in generics in the future where it says T may not be an open array
>>> type nor an array type indexed on LONGINT or a subrange thereof?
>>> =20
>>> Your comments about different parameter-passing techniques was what I =
>> was
>>> trying to address with my suggestion to have a pragma for this---just =
>> to
>>> match C (and Fortran?), of course. Name me a single Modula-3 =
>> programmer
>>> who cares in what order the bits in his parameters are pushed on the
>>> stack in a Modula-3-to-Modula-3 call.
>>> =20
>>> And I am definitely in that school of thought that says that =
>> programming
>>> languages should not "evolve". Better to leave well enough alone.
>>> =20
>>> How much Modula-3 code has been written that uses LONGINT? Other than
>>> to talk to C? I've certainly never used it.
>>> =20
>>> Mika
>>> =20
>>> =20
>>> =20
>>> Jay K writes:
>>>> --_264cb69b-0215-44c3-807c-8b4d8ea0ea59_
>>>> Content-Type: text/plain; charset=3D"iso-8859-1"
>>>> Content-Transfer-Encoding: quoted-printable
>>>> =20
>>>> =20
>>>> TYPE LONGINT =3D3D ARRAY [0..1] OF INTEGER on a 32bit system is very =
>> close to=3D
>>>> LONGINT.
>>>> =20
>>>> Plus treating it opaquely and providing a bunch of functions to =
>> operate on=3D
>>>> it.
>>>> =20
>>>> Just as well therefore could be RECORD hi=3D2Clo:LONGINT END (see =
>> LARGE_INTE=3D
>>>> GER and ULARGE_INTEGER in winnt.h)
>>>> =20
>>>> =3D20
>>>> =20
>>>> Differences that come to mind:
>>>> =20
>>>> infix operators <=3D3D=3D3D=3D3D=3D20
>>>> =20
>>>> possibly passed differently as a parameter
>>>> =20
>>>> or returned differently as a result
>>>> =20
>>>> ie. probably "directly compatible with" "long long"=3D2C passed by =
>> value (o=3D
>>>> f course you could always pass by pointer and achieve compatibilitity =
>> trivi=3D
>>>> ally)
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> I have to say though=3D2C the biggest reason is in-fix operators. =
>> Convenient =3D
>>>> syntax.
>>>> =20
>>>> C++ is the best and some way worst of example of the general right =
>> way to d=3D
>>>> o this -- you let programmers define types and their infix operators. =
>> Other=3D
>>>> languages just come with a passle of special cases of types that have =
>> in-f=3D
>>>> ix operators.
>>>> =20
>>>> A good example is that Java infix operator + on string=3D2C besides =
>> the vario=3D
>>>> us integers=3D2C and nothing else.
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> I think C# lets you define operators=3D2C yet people don't complain =
>> that it i=3D
>>>> s "a mess" as they do of C++.
>>>> =20
>>>> I think Python does now too.
>>>> =20
>>>> So it is feature growing in popularity among "mainstream" =
>> languages=3D2C not =3D
>>>> just C++.
>>>> =20
>>>> C++ of course is extremely mainstream=3D2C but also a favorite =
>> target. (ht=3D
>>>> tp://www.relisoft.com/tools/CppCritic.html)
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> We also have subranges of LONGINT.
>>>> =20
>>>> I'm not sure what the generalization of subranges are=3D2C granted.
>>>> =20
>>>> Maybe some sort of C++ template that takes constants in the template =
>> and d=3D
>>>> oes range checks at runtime. Yeah=3D2C maybe.
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> And as you point out=3D2C convenient literal syntax.
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> People reasonably argue for library extension in place of language =
>> extensio=3D
>>>> n=3D2C but that requires a language which is flexible enough to write =
>> librari=3D
>>>> es with the desired interface=3D2C and so many languages don't let =
>> infix oper=3D
>>>> ators be in a user-written library.
>>>> =20
>>>> (There is a subtle but useless distinction here -- infix operators =
>> being in=3D
>>>> libraries vs. "user-written" libraries. The infix set operations for =
>> examp=3D
>>>> le are in a library=3D2C but not user-written=3D2C special=3D2C the =
>> compiler know=3D
>>>> s about it.)
>>>> =20
>>>> =3D20
>>>> =20
>>>>> that would perhaps not match how C handles "long long" on the same
>>>>> platform (which is how=3D2C come to think of it?)=3D2C and that =
>> would require
>>>> =20
>>>> =20
>>>> =3D20
>>>> =20
>>>> On NT/x86=3D2C __int64/long long is returned in the register pair =
>> edx:eax.
>>>> =20
>>>> edx is high=3D2C eax is low.
>>>> =20
>>>> When passed as a parameter to __stdcall or __cdecl is just passed as =
>> two 32=3D
>>>> bit values adjacent on the stack=3D2C "hi=3D2C lo=3D2C hi=3D2C lo=3D2C =
>> it's off to pu=3D
>>> sh we go" is the Snow White-influenced mantra to remember how to pass =
>> them=3D
>>>> =3D2C at least on little endian stack-growing-down machines (which =
>> includes x=3D
>>>> 86). For __fastcall I'm not sure they are passed in registers or on =
>> the sta=3D
>>>> ck.
>>>> =20
>>>> Passing and/or returning small structs also has special efficient =
>> handling =3D
>>>> in the ABI=3D2C so __int64 really might be equivalent to a small =
>> record. Not =3D
>>>> that cm3 necessarily implements that "correctly" -- for interop with =
>> C=3D3B =3D
>>>> for Modula-3 calling Modula-3 we can make up our own ABI so there =
>> isn't rea=3D
>>>> lly an "incorrect" way. Notice the mingw problem I had passing a =
>> Win32 poin=3D
>>>> t struct by value=3D2C I cheated and passed it by VAR to a C wrapper =
>> to worka=3D
>>>> round the gcc backend bug (which was mentioned a few times and which =
>> I look=3D
>>>> ed into the code for=3D2C but took the easy route)
>>>> =20
>>>> =3D20
>>>> =20
>>>> =3D20
>>>> =20
>>>> I don't know how long long works on other platforms but probably =
>> similar.
>>>> =20
>>>> Probably a certain register pair for return values.
>>>> =20
>>>> =3D20
>>>> =20
>>>> - Jay
>>>> =20
>>>> =3D20
>>>>> To: hosking at cs.purdue.edu
>>>>> Date: Sat=3D2C 17 Apr 2010 19:47:03 -0700
>>>>> From: mika at async.async.caltech.edu
>>>>> CC: m3devel at elegosoft.com
>>>>> Subject: Re: [M3devel] INTEGER
>>>>> =3D20
>>>>> Tony Hosking writes:
>>>>>> =20
>>>>> ...
>>>>>> =20
>>>>>>> We need it to match 64-bit integers on 32-bit machines? That seems =
>> =3D3D
>>>>>> like
>>>>>>> a very weak rationale indeed=3D2C if the same functionality could =
>> be =3D3D
>>>>>> provided
>>>>>>> through some other mechanism (e.g.=3D2C ARRAY [0..1] OF =
>> INTEGER---even =3D
>>>> =3D3D
>>>>>> with
>>>>>>> a pragma e.g. <*CLONGLONG*>.. if it is necessary to tell the =
>> compiler =3D
>>>> =3D3D
>>>>>> that
>>>>>>> a special linkage convention is needed).
>>>>>> =20
>>>>>> There's no special linkage convention. Not sure what you mean here.
>>>>>> =20
>>>>> =3D20
>>>>> I just mean if we had
>>>>> =3D20
>>>>> TYPE LONGINT =3D3D ARRAY [0..1] OF INTEGER
>>>>> =3D20
>>>>> that would perhaps not match how C handles "long long" on the same
>>>>> platform (which is how=3D2C come to think of it?)=3D2C and that =
>> would require
>>>>> special linkage tricks.
>>>>> =3D20
>>>>> But what would be lost? The ability to type literals.=3D20
>>>>> =3D20
>>>>> You could get the same code interface on 32- and 64-bit machine by
>>>>> defining
>>>>> =3D20
>>>>> TYPE FileOffset =3D3D ARRAY[0..1] OF [-16_80000000 .. +16_7fffffff ]
>>>>> =3D20
>>>>> and using that.
>>>>> =3D20
>>>>> =3D20
>>>>> Mika
>>>> =3D
>>>> =20
>>>> --_264cb69b-0215-44c3-807c-8b4d8ea0ea59_
>>>> Content-Type: text/html; charset=3D"iso-8859-1"
>>>> Content-Transfer-Encoding: quoted-printable
>>>> =20
>>>> <html>
>>>> <head>
>>>> <style><!--
>>>> .hmmessage P
>>>> {
>>>> margin:0px=3D3B
>>>> padding:0px
>>>> }
>>>> body.hmmessage
>>>> {
>>>> font-size: 10pt=3D3B
>>>> font-family:Verdana
>>>> }
>>>> --></style>
>>>> </head>
>>>> <body class=3D3D'hmmessage'>
>>>> TYPE LONGINT =3D3D ARRAY [0..1] OF INTEGER on a =3D3B32bit system =
>> is very c=3D
>>>> lose to LONGINT.<BR>
>>>>  =3D3BPlus treating it opaquely and providing a bunch of =
>> functions to ope=3D
>>>> rate on it.<BR>
>>>>  =3D3BJust as well therefore could be RECORD hi=3D2Clo:LONGINT =
>> END (see LAR=3D
>>>> GE_INTEGER and ULARGE_INTEGER in winnt.h)<BR>
>>>>  =3D3B<BR>
>>>> Differences that come to mind:<BR>
>>>>  =3D3B =3D3Binfix operators =3D3B <=3D3B=3D3D=3D3D=3D3D =
>> <BR>
>>>>  =3D3B possibly passed differently =3D3Bas a parameter<BR>
>>>>  =3D3B or returned differently as a result<BR>
>>>>  =3D3B ie. probably "directly compatible with" "long long"=3D2C =
>> passed by v=3D
>>>> alue (of course you could always pass by pointer and achieve =
>> compatibilitit=3D
>>>> y trivially)<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> I have to say though=3D2C the biggest reason is in-fix operators. =
>> Convenient =3D
>>>> syntax.<BR>
>>>> C++ is the best and some way worst of example of the general right =
>> way to d=3D
>>>> o this -- you let programmers define types and their infix operators. =
>> Other=3D
>>>> languages just come with a passle of special cases of types that have =
>> in-f=3D
>>>> ix operators.<BR>
>>>> A good example is that Java infix operator + on string=3D2C besides =
>> the vario=3D
>>>> us integers=3D2C and nothing else.<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> I think C# lets you define operators=3D2C yet people don't complain =
>> that it i=3D
>>>> s "a mess" as they do of C++.<BR>
>>>> I think Python does now too.<BR>
>>>> So it is feature growing in popularity among "mainstream" =
>> languages=3D2C not =3D
>>>> just C++.<BR>
>>>>  =3D3B =3D3B C++ of course is extremely mainstream=3D2C but =
>> also a favori=3D
>>>> te target. (<A =
>> href=3D3D"http://www.relisoft.com/tools/CppCritic.html">http:/=3D
>>>> /www.relisoft.com/tools/CppCritic.html</A>)<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> We also have subranges of LONGINT.<BR>
>>>> I'm not sure what the generalization of subranges are=3D2C =
>> granted.<BR>
>>>>  =3D3BMaybe some sort of C++ template that takes constants in the =
>> templat=3D
>>>> e and does range checks at runtime. Yeah=3D2C maybe.<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> And as you point out=3D2C convenient literal syntax.<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> People reasonably argue for library extension in place of language =
>> extensio=3D
>>>> n=3D2C but that requires a language which is flexible enough to write =
>> librari=3D
>>>> es with the desired interface=3D2C and so many languages don't let =
>> infix oper=3D
>>>> ators be in a user-written library.<BR>
>>>> (There is a subtle but useless distinction here -- infix operators =
>> being in=3D
>>>> libraries vs. "user-written" libraries. The infix set operations for =
>> examp=3D
>>>> le are in a library=3D2C but not user-written=3D2C special=3D2C the =
>> compiler know=3D
>>>> s about it.)<BR>
>>>>  =3D3B<BR>
>>>> >=3D3B that would perhaps not match how C handles "long long" on =
>> the same<B=3D
>>>> R>>=3D3B platform (which is how=3D2C come to think of it?)=3D2C and =
>> that would =3D
>>>> require<BR><BR>
>>>>  =3D3B<BR>
>>>> On NT/x86=3D2C __int64/long long is returned in the register pair =
>> edx:eax.<BR=3D
>>>>> =20
>>>> edx is high=3D2C eax is low.<BR>
>>>> When passed as a parameter to __stdcall or __cdecl is just passed as =
>> two 32=3D
>>>> bit values adjacent on the stack=3D2C "hi=3D2C lo=3D2C hi=3D2C lo=3D2C =
>> it's off to pu=3D
>>>> sh we go" is the Snow White-influenced mantra to remember how to pass =
>> them=3D
>>>> =3D2C at least on little endian stack-growing-down machines (which =
>> includes x=3D
>>>> 86). For __fastcall I'm not sure they are passed in registers or on =
>> the sta=3D
>>>> ck.<BR>
>>>> Passing and/or returning small structs also has special efficient =
>> handling =3D
>>>> in the ABI=3D2C so __int64 really might be equivalent to a small =
>> record. Not =3D
>>>> that cm3 necessarily implements that "correctly" =3D3B -- for =
>> interop wit=3D
>>>> h C=3D3B for Modula-3 calling Modula-3 we can make up our own ABI so =
>> there is=3D
>>>> n't =3D3Breally an "incorrect" way. =3D3BNotice the mingw =
>> problem I had=3D
>>>> passing a Win32 point struct by value=3D2C I cheated and passed it by =
>> VAR to=3D
>>>> a =3D3BC wrapper to workaround the gcc backend bug (which was =
>> mentioned =3D
>>>> a few times and which I looked into the code for=3D2C but took the =
>> easy route=3D
>>>> )<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B<BR>
>>>> I don't know how long long works on other platforms but probably =
>> similar.<B=3D
>>>> R>
>>>> Probably a certain register pair for return values.<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B- Jay<BR><BR> =3D3B<BR>>=3D3B To: =
>> hosking at cs.purdue.edu<BR>>=3D3B=3D
>>>> Date: Sat=3D2C 17 Apr 2010 19:47:03 -0700<BR>>=3D3B From: =
>> mika at async.async.c=3D
>>>> altech.edu<BR>>=3D3B CC: m3devel at elegosoft.com<BR>>=3D3B Subject: =
>> Re: [M3de=3D
>>>> vel] INTEGER<BR>>=3D3B <BR>>=3D3B Tony Hosking writes:<BR>>=3D3B =
>> >=3D3B<BR>=3D
>>>> >=3D3B ...<BR>>=3D3B >=3D3B<BR>>=3D3B >=3D3B>=3D3B We =
>> need it to match 64-b=3D
>>>> it integers on 32-bit machines? That seems =3D3D<BR>>=3D3B =
>> >=3D3Blike<BR>>=3D
>>>> =3D3B >=3D3B>=3D3B a very weak rationale indeed=3D2C if the same =
>> functionality =3D
>>>> could be =3D3D<BR>>=3D3B >=3D3Bprovided<BR>>=3D3B >=3D3B>=3D3=
>> B through some o=3D
>>>> ther mechanism (e.g.=3D2C ARRAY [0..1] OF INTEGER---even =
>> =3D3D<BR>>=3D3B >=3D3B=3D
>>>> with<BR>>=3D3B >=3D3B>=3D3B a pragma e.g. =
>> <=3D3B*CLONGLONG*>=3D3B.. if it i=3D
>>>> s necessary to tell the compiler =3D3D<BR>>=3D3B =
>> >=3D3Bthat<BR>>=3D3B >=3D3B&=3D
>>>> gt=3D3B a special linkage convention is needed).<BR>>=3D3B =
>> >=3D3B<BR>>=3D3B &=3D
>>>> gt=3D3BThere's no special linkage convention. Not sure what you mean =
>> here.<BR=3D
>>>>> >=3D3B >=3D3B<BR>>=3D3B <BR>>=3D3B I just mean if we =
>> had<BR>>=3D3B <BR>>=3D
>>>> =3D3B TYPE LONGINT =3D3D ARRAY [0..1] OF INTEGER<BR>>=3D3B =
>> <BR>>=3D3B that woul=3D
>>>> d perhaps not match how C handles "long long" on the same<BR>>=3D3B =
>> platfor=3D
>>>> m (which is how=3D2C come to think of it?)=3D2C and that would =
>> require<BR>>=3D
>>>> =3D3B special linkage tricks.<BR>>=3D3B <BR>>=3D3B But what would =
>> be lost? Th=3D
>>>> e ability to type literals. <BR>>=3D3B <BR>>=3D3B You could get =
>> the same co=3D
>>>> de interface on 32- and 64-bit machine by<BR>>=3D3B =
>> defining<BR>>=3D3B <BR>=3D
>>>> >=3D3B TYPE FileOffset =3D3D ARRAY[0..1] OF [-16_80000000 .. =
>> +16_7fffffff ]<B=3D
>>>> R>>=3D3B <BR>>=3D3B and using that.<BR>>=3D3B <BR>>=3D3B =
>> <BR>>=3D3B Mika<BR=3D
>>>>> </body>
>>>> </html>=3D
>>>> =20
>>>> --_264cb69b-0215-44c3-807c-8b4d8ea0ea59_--
More information about the M3devel
mailing list