[M3devel] INTEGER

Mika Nystrom mika at async.async.caltech.edu
Sun Apr 18 21:59:01 CEST 2010


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&nbsp=3D3B32bit system =
>is very c=3D
>>> lose to LONGINT.<BR>
>>> &nbsp=3D3BPlus treating it opaquely and providing a bunch of =
>functions to ope=3D
>>> rate on it.<BR>
>>> &nbsp=3D3BJust as well therefore could be RECORD hi=3D2Clo:LONGINT =
>END (see LAR=3D
>>> GE_INTEGER and ULARGE_INTEGER in winnt.h)<BR>
>>> &nbsp=3D3B<BR>
>>> Differences that come to mind:<BR>
>>> &nbsp=3D3B&nbsp=3D3Binfix operators&nbsp=3D3B &lt=3D3B=3D3D=3D3D=3D3D =
><BR>
>>> &nbsp=3D3B possibly passed differently&nbsp=3D3Bas a parameter<BR>
>>> &nbsp=3D3B or returned differently as a result<BR>
>>> &nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &nbsp=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>
>>> &nbsp=3D3B&nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &nbsp=3D3B<BR>
>>> We also have subranges of LONGINT.<BR>
>>> I'm not sure what the generalization of subranges are=3D2C =
>granted.<BR>
>>> &nbsp=3D3BMaybe some sort of C++ template that takes constants in the =
>templat=3D
>>> e and does range checks at runtime. Yeah=3D2C maybe.<BR>
>>> &nbsp=3D3B<BR>
>>> &nbsp=3D3B<BR>
>>> And as you point out=3D2C convenient literal syntax.<BR>
>>> &nbsp=3D3B<BR>
>>> &nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &gt=3D3B that would perhaps not match how C handles "long long" on =
>the same<B=3D
>>> R>&gt=3D3B platform (which is how=3D2C come to think of it?)=3D2C and =
>that would =3D
>>> require<BR><BR>
>>> &nbsp=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"&nbsp=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&nbsp=3D3Breally an "incorrect" way.&nbsp=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&nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &nbsp=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>
>>> &nbsp=3D3B<BR>
>>> &nbsp=3D3B- Jay<BR><BR>&nbsp=3D3B<BR>&gt=3D3B To: =
>hosking at cs.purdue.edu<BR>&gt=3D3B=3D
>>> Date: Sat=3D2C 17 Apr 2010 19:47:03 -0700<BR>&gt=3D3B From: =
>mika at async.async.c=3D
>>> altech.edu<BR>&gt=3D3B CC: m3devel at elegosoft.com<BR>&gt=3D3B Subject: =
>Re: [M3de=3D
>>> vel] INTEGER<BR>&gt=3D3B <BR>&gt=3D3B Tony Hosking writes:<BR>&gt=3D3B =
>&gt=3D3B<BR>=3D
>>> &gt=3D3B ...<BR>&gt=3D3B &gt=3D3B<BR>&gt=3D3B &gt=3D3B&gt=3D3B We =
>need it to match 64-b=3D
>>> it integers on 32-bit machines? That seems =3D3D<BR>&gt=3D3B =
>&gt=3D3Blike<BR>&gt=3D
>>> =3D3B &gt=3D3B&gt=3D3B a very weak rationale indeed=3D2C if the same =
>functionality =3D
>>> could be =3D3D<BR>&gt=3D3B &gt=3D3Bprovided<BR>&gt=3D3B &gt=3D3B&gt=3D3=
>B through some o=3D
>>> ther mechanism (e.g.=3D2C ARRAY [0..1] OF INTEGER---even =
>=3D3D<BR>&gt=3D3B &gt=3D3B=3D
>>> with<BR>&gt=3D3B &gt=3D3B&gt=3D3B a pragma e.g. =
>&lt=3D3B*CLONGLONG*&gt=3D3B.. if it i=3D
>>> s necessary to tell the compiler =3D3D<BR>&gt=3D3B =
>&gt=3D3Bthat<BR>&gt=3D3B &gt=3D3B&=3D
>>> gt=3D3B a special linkage convention is needed).<BR>&gt=3D3B =
>&gt=3D3B<BR>&gt=3D3B &=3D
>>> gt=3D3BThere's no special linkage convention. Not sure what you mean =
>here.<BR=3D
>>>> &gt=3D3B &gt=3D3B<BR>&gt=3D3B <BR>&gt=3D3B I just mean if we =
>had<BR>&gt=3D3B <BR>&gt=3D
>>> =3D3B TYPE LONGINT =3D3D ARRAY [0..1] OF INTEGER<BR>&gt=3D3B =
><BR>&gt=3D3B that woul=3D
>>> d perhaps not match how C handles "long long" on the same<BR>&gt=3D3B =
>platfor=3D
>>> m (which is how=3D2C come to think of it?)=3D2C and that would =
>require<BR>&gt=3D
>>> =3D3B special linkage tricks.<BR>&gt=3D3B <BR>&gt=3D3B But what would =
>be lost? Th=3D
>>> e ability to type literals. <BR>&gt=3D3B <BR>&gt=3D3B You could get =
>the same co=3D
>>> de interface on 32- and 64-bit machine by<BR>&gt=3D3B =
>defining<BR>&gt=3D3B <BR>=3D
>>> &gt=3D3B TYPE FileOffset =3D3D ARRAY[0..1] OF [-16_80000000 .. =
>+16_7fffffff ]<B=3D
>>> R>&gt=3D3B <BR>&gt=3D3B and using that.<BR>&gt=3D3B <BR>&gt=3D3B =
><BR>&gt=3D3B Mika<BR=3D
>>>> 		 	   		  </body>
>>> </html>=3D
>>>=20
>>> --_264cb69b-0215-44c3-807c-8b4d8ea0ea59_--



More information about the M3devel mailing list