[Top][All Lists]
[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