gm2
[Top][All Lists]
Advanced

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

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


From: gaius
Subject: Re: [Gm2] Re: LENGTH() on Solaris 10/sparc
Date: Mon, 02 Aug 2010 06:09:28 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)

"Fischlin  Andreas" <address@hidden> writes:

> 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.

Hi Andreas,

M2RTS.Length is use to implement LENGTH when the string is only know at runtime.
For example LENGTH('hello world') is calculated as 11 by the compiler at compile
time whereas:

LENGTH(a)

will expand to a call to M2RTS.Length and be evaluated at runtime.
M2RTS.Length could be implemented as an inlined procedure function
post gm2 1.0, but I thought it easier to debug gm2 by using libraries
where possible.  (This is also how large sets are implemented at present).


> 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) ;

ok - I'll change this - probably to use a procedure function returning
TRUE on success.

> 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;

I'll rename Terminate to ExecuteTerminationProcedures.  Maybe we need
a procedure function to determine whether we are in the Termination
phase as well.

> 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;

sure I'll implement this - the ExecuteInitProcedures will be called by
default just before the main program module BEGIN code.

> 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;

I believe the StrLib.StrEqual code behaves in the same way as StrEqual
above.  (It uses StrLen to determine the length of the strings under
comparison which handles the ASCII.nul case).  Unless I've
misunderstood something?

regards,
Gaius


>
>
> 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
>
>
> _______________________________________________
> gm2 mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/gm2



reply via email to

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