gm2
[Top][All Lists]
Advanced

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

[Gm2] Re: LENGTH() on Solaris 10/sparc


From: Fischlin Andreas
Subject: [Gm2] Re: LENGTH() on Solaris 10/sparc
Date: Wed, 28 Jul 2010 11:13:39 +0000

Dear John,

Thanks for the explanations.

BTW, I do not see any purpose in having such LENGTH/Length routines as you seem 
to explain. Why having two routines LENGTH and Length, both merely returning 
the number of characters available to store in the string variable? If that's 
really true I would suggest it is best to  discard both routines, since in 
Modula-2 there is a routine HIGH available. Then I would like to remind you 
that we must not get in conflict with ISO Modula-2 where the standard function 
LENGTH is doing AFAIK what I described and which has nothing to do with HIGH. 
Yes, it uses HIGH, but its purpose is an entirely different one. 

Since I was still confused from your arguments I had a look at the source code 
and one can easily see in M2RTS what the problem is: RTMS.Length is doing 
exactly what I described. Thus I have still wrongly understood your explanation 
and the routines LENGTH and RTMS.Length actually return the number of 
characters defined in the string variable. If it always returns only 1 for any 
string variable of any different storage length or value length then it is 
clear that HIGH is simply buggy and does not return the correct value. 

However, I see still no purpose in having Length in this module. Such a 
procedure does not make sense to be exported from here and the standard ISO 
procedure LENGTH will do or StrLib.StrLen. Moreover, I would highly recommend 
to make standard procedure LENGTH as efficient as possible by not calling 
RTMS.Length. That's unnecessary and I strongly recommend to implement it as a 
stand-alone standard procedure without using another module, let alone one like 
RTMS. I would call such a module dependency rather a poor design. I also have 
difficulties with using ASCII.nul instead of the local 0C. Why making a 
reference to another module for such a constant? That would only make sense if 
one considers changing the definition of the string terminator beeing something 
else than 0C but I would highly argue against such attempts. Yes, perhaps this 
is not particular costly, but in my experience favoring module 
self-sufficiency, in particular for low level modules is preferable in terms of 
maintaining a library.

Then I can offer some further, more general comments on the design of M2RTS:

I think it is a mistake to offer installation procedures without being able to 
learn about the fact whether the postcondition has been reached or not. The 
routine 

        PROCEDURE InstallTerminationProcedure (p: PROC) ;

should be defined as

        PROCEDURE InstallTerminationProcedure (p: PROC; VAR done: BOOLEAN) ;

To merely throw an error message is an awful practice at such a low program 
level and gives the programmer no means to handle the error properly. I expect 
a routine such as InstallTerminationProcedure to be of the quiet kind. Since 
TerminationProc are typically installed by library modules, it is very 
difficult for the programmer of an end-user program to debug such a situation 
unless the library module programmer handles the error properly.

Then I am missing for sure following procedure being exported from RTMS:

        PROCEDURE ExecuteTerminationProcedures;

Agreed there is no dynamic module loading possible, since our times entrench on 
us the stone age of only static linking and unmodular programming style, but 
nevertheless I am not sure whether it would not be beneficial for having the 
symmetrical procedures available as well.

        PROCEDURE InstallInitProcedure (p: PROC; VAR done: BOOLEAN) ;
        PROCEDURE ExecuteInitProcedures;

If you wanna see some examples of such a module, based on the Modula-2 ETH 
tradition of dynamic linking-loading see our module DMSystem at 
http://se-server.ethz.ch/RAMSES/Objects/DM/DMSystem.html#DMSystem

Then I has a quick look at StrLib and have seen that routine StrEqual is 
wrongly implemented and requires two string variables to have an identical 
history to succeed. It fails to test for 0C (or ASCII.nul) presence and needs 
to be fixed. Here some code replacing it: 

    PROCEDURE SameStrings(VAR (*speed-up*) s1: ARRAY OF CHAR; s2: ARRAY OF 
CHAR): BOOLEAN;
      VAR n1,n2,i: INTEGER; same: BOOLEAN;
    BEGIN (* SameStrings *)
      n1 := HIGH(s1); n2 := HIGH(s2);
      i := 0; same := s1[i] = s2[i];
      WHILE (i<=n1) AND (i<=n2) AND (s1[i]<>0C) AND (s2[i]<>0C) DO
        same := same AND (s1[i] = s2[i]);
        INC(i);
      END(*WHILE*);
      IF (i<=n1) THEN same := same AND (s1[i] = 0C) END(*IF*);
      IF (i<=n2) THEN same := same AND (s2[i] = 0C) END(*IF*);
      RETURN same
    END SameStrings;    

or

  PROCEDURE StrEqual (s1,s2: ARRAY OF CHAR): BOOLEAN;
    VAR i,n1,n2: INTEGER;
  BEGIN (* StrEqual *)
    n1 := HIGH(s1); n2 := HIGH(s2);
    i := 0;
    WHILE (i<=n1) AND (i<=n2) AND (s1[i]<>0C) AND (s2[i]<>0C) AND (s1[i]=s2[i]) 
DO
      INC(i)
    END(*WHILE*);
    RETURN (i>n1) OR (i>n2) OR ((i<=n1) AND (s1[i]=0C)) OR ((i<=n2) AND 
(s2[i]=0C))
  END StrEqual;


Regards,
Andreas


ETH Zurich
Prof. Dr. Andreas Fischlin
Systems Ecology - Institute of Integrative Biology
CHN E 21.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND

address@hidden
www.sysecol.ethz.ch

+41 44 633-6090 phone
+41 44 633-1136 fax
+41 79 221-4657 mobile

             Make it as simple as possible, but distrust it!
________________________________________________________________________



On 25/Jul/2010, at 03:00 , john o goyo wrote:

> Andreas:
> 
> On 24-Jul-10, at 2:20 PM, Fischlin Andreas wrote:
>> Hi John,
>> 
>> Sorry, I don't quite get your issue.
>> 
>> On 24/Jul/2010, at 04:27 , john o goyo wrote:
>>> Examination of the failed test cases shows a real oddity.
>>> 
>>> In a call to LENGTH(s), where s is a string, HIGH(s) is passed as zero and 
>>> LENGTH(s) is always 1.
>>> 
>> 
>> HIGH(s) is passed as zero has nothing to do with LENGTH(s).
> [..]
>> 
>> Perhaps you are actually talking about something else, but then you should 
>> explain better what kind of oddity you actually mean.
> 
> I wrote the above in the context of gm2, specifically, in the context of the 
> failed test cases of Length().  I shall elucidate.
> 
> In gm2, LENGTH() is defined in terms of Length() under certain circumstances. 
>  If you read the comment before the function Length() in M2RTS.mod, you will 
> find the following.
> 
> (*
>    Length - returns the length of a string, a. This is called whenever
>            the user calls LENGTH and the parameter cannot be calculated
>            at compile time.
> *)
> 
> In the failed test case iso/run/pass/tstLength.mod, the value of LENGTH(s) is 
> compared to the value of Length(s), where "s" is an array of characters.  The 
> former is converted into a call to the latter and the latter uses HIGH(s) in 
> its count.  Unfortunately, as I wrote above, HIGH(s) is zero and consequently 
> Length(s) returns 1, hence LENGTH(s) returns 1.
> 
> john




reply via email to

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