gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A beginner's question


From: Rudolf Schubert
Subject: Re: A beginner's question
Date: Fri, 7 Apr 2023 20:21:32 +0200 (CEST)

Hi Benjamin,

thanks for your comments and suggestions! Just to summarize:

1. Of course you're right, it's not CR on Unix but LF. Fingers quicker than 
brain;-)

2. I see your suggested string handling looks quite powerful. Concerning my
question about my extra 'INTEGER len' which I introduced to be able to track
the length of 'schnur' you think, Gaius might have an answer?

3. Concerning the ISO IO library you would not completetly exclude that
it might show 'difficult' behaviour sometimes?


My goal was just to be able to compile my program both with GPM and GM2
with a minimal amount of changes/'porting work'. I would not say that more
elegant code than what is there now, is impossible;-)


BR

Rudolf


--
Rudolf Schubert                 \
Kirchstr. 18a                    \  mailto:rudolf@muc.de
82054 Sauerlach                   > http://www.dose.muc.de
Deutschland                      /
Tel. 08104/908311               /


On Sat, 8 Apr 2023, Benjamin Kowarsch wrote:

> Hi Rudolf,
> 
> On Fri, 7 Apr 2023 at 23:48, Rudolf Schubert wrote:
> 
>       Yes, I'm aware that the 'ISO-parts' in GPM and GM2 are different.
>       I could easily handle these differences, so my code can now be compiled 
> on
>       both GPM and GM2
> 
> 
> Still, I wouldn't rule out that the different behaviour may simply be down to 
> incompatibility.
> 
> Note that it is a common phenomenon that bugs show up in software when it is 
> ported even though it seemed to
> be working error free on the original target platform. This is one of the 
> reasons why it is a good idea to
> write portable code and test it on at least two different compilers and/or 
> targets, even if portability is
> not an actual requirement.
> 
>       WriteString(cid, 15C+12C);
> 
>       With GM2 compilation goes fine but when run I get:
> 
>       RTExceptions.mod:648:35: In invalidloc
>       RTExceptions.mod:648:35:invalid address referenced
> 
>       I did not dig too deep into this, perhaps the construct '15C+12C' here
>       is not quite 'legal'?
> 
> 
> ISO permits string constant concatenation, but I am not sure whether 
> character code literals are recognised
> as strings in that expression. It may well be recognised as an arithmetic 
> expression adding two character
> code values. I do remember that this was put forward as an argument against 
> using the plus operator for
> string concatenation at the ISO WG13 meeting in Milton Keynes. The proposed 
> alternative was ampersand, but
> computer scientists outnumbered mathematicians and so the plus operator was 
> adopted. Unfortunately.
> 
> Maybe Gaius (the implementer of GM2) can shed some light on the intended 
> behaviour of GM2 in this case.
> 
>  
>       But instead I now use this little helper and
>       everything is fine:
> 
>       PROCEDURE WriteLnCrLf(cid: ChanId);
>         VAR
>           schnur2:                    ARRAY[0..1] OF CHAR;
> 
>         BEGIN                         (* PROCEDURE WriteLnCrLf *)
>           schnur2:='  ';
>           schnur2[0]:=15C;            (* CR *)
>           schnur2[1]:=12C;            (* LF *)
>           WriteString(cid, schnur2);
>         END WriteLnCrLf;
> 
> 
> I wouldn't hard code that into the code. It is not portable. Even if you 
> think you don't need portability,
> as I mentioned above, it is always a good idea to write portable code and 
> test it on different
> compilers/platforms. That's where you find bugs you won't otherwise uncover.
> 
>       You might ask why not using WriteLn from TextIO instead? I found that
>       I do need CR and LF in my output and WriteLn produced either only
>       CR (on Linux) or CR and LF on Windoze.
> 
> 
> It is LF on Unix and Unix-like systems (including Linux), CR on legacy Macs, 
> and CRLF on OpenVMS, DOS and
> Windows.
>  
>       So WriteLnCrLf was my quick
>       answer to the small problem.
> 
> 
> Here is how I do this portably:
> 
> Module Newline defines a mode setting, which can be either CR, LF or CRLF.
> 
> https://github.com/m2sf/m2bsk/blob/master/src/lib/IO/Newline.def
> 
> Then you write your own WriteLn procedure that uses the mode setting to 
> decide when to write CR, LF or CRLF
> 
> https://github.com/m2sf/m2pp/blob/master/src/imp/Outfile.mod#L230
> 
> Your code always only calls WriteLn. In order to change the newline mode of 
> the program, all you need to do
> is call Newline.setMode().
> 
> 
>       But quickly: a (potentially) big input string 'schnur' should be 
> transformed
>       into a linked list of smaller strings of length mittellen. Don't ask 
> why I
>       used this method. I had many smaller strings but some very big ones and 
> I
>       wanted to store them all in some array but did not want to use the 
> biggest
>       possible string even for the small ones...)
> 
> 
> You can store strings efficiently (in space and time) by allocating the exact 
> length needed for the most
> frequently encountered lengths, and as they get longer by allocating a 
> slightly larger length so they can be
> grouped with other strings of similar lengths (thereby reducing the number of 
> cases).
> 
> My interned string library stores strings of lengths 1 to 80 in memory blocks 
> exactly of that length, and
> strings of lengths 81 to 4096 in nine groups of increasing size. Nevertheless 
> all these strings are of the
> same string type in the public interface.
> 
> https://github.com/m2sf/m2bsk/blob/master/src/lib/String.def
> https://github.com/m2sf/m2bsk/blob/master/src/lib/imp/String.pim.mod
> https://github.com/m2sf/m2bsk/blob/master/src/lib/imp/String.iso.mod
> 
> The library stores every string in a hash table, but only once. If a string 
> is already stored, it will not
> be allocated again, but the previously checked in string is returned. As a 
> nice side effect of this, strings
> can be compared with the equal operator (str1 = str2), because if two strings 
> are equal, their addresses are
> the same.
> 
>       4.      Perhaps a problem which might be related to 3. was the 
> following:
> 
>       Again when reading from my (text) file I used ReadInt from WholeIO.
>       But again this showed very strange results. I then replaced ReadInt
>       with a sequence of
> 
>       ReadToken
>       StrToInt
> 
>       and the problems were gone! Doesn't this sound strange?
> 
> 
> This sounds exactly like the kinds of issues you can expect when porting 
> code. The ISO IO library in
> particular is a minefield. For our bootstrap compiler we support some 13 or 
> 14 Modula-2 compilers as hosts,
> most of which are PIM but some are ISO compliant (or partially like GPM). To 
> ensure all the code compiles
> with the ISO IO library was a nightmare. The most difficult host was p1 
> Modula-2 though, not GM2. But still,
> anything using the ISO IO library was a royal pain in the back. By contrast, 
> our own simpler IO library can
> be easily hooked into the Unix system calls for IO and even though that 
> involved foreign function
> interfacing to C which is different on every single compiler, it was a walk 
> in the park compared to using
> the ISO IO library across compilers without having to fiddle with the code.
> 
> I can't comment on the other issues you raised, but maybe Gaius will take a 
> look.
> 
> regards
> benjamin
> 
> 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]