[M3devel] latest longint file size diffs

Tony Hosking hosking at cs.purdue.edu
Sat Jan 9 19:24:08 CET 2010


The patch I sent to you yesterday will achieve checked assignment of LONGINT to/from INTEGER.

On 9 Jan 2010, at 04:04, Jay K wrote:

> Uh, maybe all ordinal types that overlap in any values are assignable?
>  
>  
> PROCEDURE IsAssignable (a, b: T): BOOLEAN =
>   VAR i, e: T;  min_a, max_a, min_b, max_b, min, max: Target.Int;
>   BEGIN
>     IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN
>       RETURN TRUE;
>     ELSIF IsOrdinal (a) THEN
>       (* ordinal types:  OK if they have at least one member in common. *)
>       IF GetBounds (a, min_a, max_a)
>          AND GetBounds (b, min_b, max_b) THEN
>         (* check for a non-empty intersection *)
>         min := min_a;  IF TInt.LT (min, min_b) THEN min := min_b; END;
>         max := max_a;  IF TInt.LT (max_b, max) THEN max := max_b; END;
>         RETURN TInt.LE (min, max);
>       ELSE
>         RETURN FALSE;
>       END;
>     ELSIF IsSubtype (a, b) THEN
>       (* may be ok, but must narrow rhs before doing the assignment *)
>       RETURN IsSubtype (b, Reff.T)
>           OR ArrayType.Split (b, i, e)
>           OR (IsSubtype (b, Addr.T)
>               AND (NOT Module.IsSafe() OR NOT IsEqual (b, Addr.T, NIL)));
>     ELSE
>       RETURN FALSE;
>     END;
>   END IsAssignable;
> 
>  
> ?
> I'll try it out.
>  
>  
> What is an ordinal type?, I wonder, the compiler implementation:
>  
>  
> PROCEDURE IsOrdinal (t: T): BOOLEAN =
>   VAR u := Check (t);  c := u.info.class;
>   BEGIN
>     RETURN (c = Class.Integer) OR (c = Class.Longint) OR (c = Class.Subrange)
>            OR (c = Class.Enum) OR (c = Class.Error)
>            OR ((c = Class.Packed) AND IsOrdinal (StripPacked (t)));
>   END IsOrdinal;
> 
>  
>  - Jay
> 
> 
> 
> 
> 
>  
> From: jay.krell at cornell.edu
> To: hosking at cs.purdue.edu
> CC: m3devel at elegosoft.com
> Subject: RE: [M3devel] latest longint file size diffs
> Date: Sat, 9 Jan 2010 07:52:29 +0000
> 
> ok, yeah, it does bug me.
> 
> With 8 bit integer, 16 bit longint.
> 
> Let's replace 128 with 127 + 1.
> 
>  (127 + 1) > 127 
> 
> either:
>   is true
>   or false 
>   or raises an exception 
> 
> "Obviously" it should be true, but implementing that is..uncertain.
> Though, again, it should really raise the exception before the comparison is made.
>   Maybe it does.
> 
> Where (127 + 1L) > 127 
> 
> is simply true, no controversy..except for the difference with 127 + 1.
> 
> But Rodney said something..that mixed operations fall out of
> assignability. Right??
> 
> 
> I have an idea..I mean..an obvious guess/experiment.
> I can try providing only for bidirectional assignability
> and see what the affect on rd/wr is.
> Maybe bidirectional assignability is enough to
> keep the diff small?
> Or, maybe my initial big diff with ORD/VAL everywhere is acceptable?
>    Clearly it will be allowed by any of the proposals, it
>    just might not be necessary.
> 
> 
> Also, btw, I think we should warn for truncating assignment.
> Any time a range check is put in, perhaps.
> Except maybe not on array indexing.
> Which might leave this suggestion completely ambiguous as
> to when a warning should be issued.
> 
> But as has been pointed out, while it may be "annoying" and
> "inconvenient" to put ORD and VAL everywhere, or at least ORD,
> it does force us to revisit all those locations where a change
> is being induced.
> 
> Notice that that the warning may or may not be platform specific.
> It might trigger only on 32bit platforms.
> Or the compiler targeting 64bit platforms might "know" about
> the truncation potential on other platforms and warn.
> In a specific concrete way, assignment of LONGINT to INTEGER
> might warn, no matter their current exact sizes.
> 
> 
> Extending that rule to subranges might be tricky.
> TYPE A = [0..LAST(INTEGER)/2];
> TYPE B = [0..LAST(LONGINT)/2];
> VAR a: A; b:B;
> 
> a := b;   warn?
> 
> Implementing that, maybe, would require, like a bit carried along
> with type definitions in the compiler, as to if the definition
> contains a platform independent size in it...er..
> if the size is dependent on bitsize(integer) or not, and
> mixing of that type with any? other type is a warning?
> Clearly no. Mixing with a type dependent on bitsize(longint)?
> Maybe.
> 
> I'm not sure what the rule is, but, you know, it'd be nice
> if above code did warn on 64bit targets, in order to
> encourage portability to 32bit targets.
> 
> 
>  - Jay
> 
> From: jay.krell at cornell.edu
> To: hosking at cs.purdue.edu
> Date: Sat, 9 Jan 2010 07:01:47 +0000
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] latest longint file size diffs
> 
>  > (LAST(INTEGER) + 1) = FIRST(INTEGER)
> 
> ps: a beginner wouldn't necessarily expect this.
> He might expect an error or widening of precision as needed.
> Eventually faced with the cruel realities of what can be efficiently implemented,
> he might accept any of our answers. :)
> 
>  - Jay
> 
> From: jay.krell at cornell.edu
> To: hosking at cs.purdue.edu
> CC: m3devel at elegosoft.com
> Subject: RE: [M3devel] latest longint file size diffs
> Date: Sat, 9 Jan 2010 06:59:52 +0000
> 
> I'll admit to being a little unsure.
> 
> 
> I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3.
> 
> 
> You might classify me more as a lazy user than a language designing deep thinker.
> 
> 
> But I'm curious even about your assertion.
> 
> 
> Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok?
> It is easier for me.
> 
> 
>   INTEGER max := 16_7F;   
>   INTEGER first := 16_80; 
>   INTEGER p1 := max + 1; 
>   LONGINT p1L := max + 1L; 
> 
> 
> So, what happens if we compare p1 with first and p1L with first?
> Again remember INTEGER is 8 bits, LONGINT is 16 bits.
> 
> p1 will be -128, 0x80.
> p1L will be 128, 0x0080.
> 
> 
> What then happens when you compare 0x0080 to 0x80?
> Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)?
> 
> 
> And heck, shouldn't max + 1 already throw an exception?
> 
> 
>  - Jay
> 
> 
> From: hosking at cs.purdue.edu
> Date: Sat, 9 Jan 2010 01:03:08 -0500
> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] latest longint file size diffs
> 
> On 9 Jan 2010, at 00:50, Jay K wrote:
> 
> I don't know the precedence but agreed:
> 
> 
> > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL))
> > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)))
> 
> I was being sort of lazy.
> I've never touched the front end and it was critical I be able to make
> a small change and see fairly precisely the expected change, even
> if I didn't get all cases.
> 
> This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32"
> in the Win32 code to INTEGER or LONGINT.
> 
> Yes, that would be why.
> 
> Also, I really think mixed arithmetic is ok.
> 
> But are you ok with:
> 
> (LAST(INTEGER) + 1) = FIRST(INTEGER)
> 
> while
> 
> (LAST(INTEGER) + 1L) # FIRST(INTEGER)
> 
> ?
> 
> I find such things to be difficult to explain to the novice programmer.  Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising!
> 
> 
>  - Jay
> 
> 
> > From: hosking at cs.purdue.edu
> > Date: Sat, 9 Jan 2010 00:37:42 -0500
> > To: jay.krell at cornell.edu
> > CC: m3devel at elegosoft.com
> > Subject: Re: [M3devel] latest longint file size diffs
> > 
> > Looking at your code, I think the assignability test for ordinals should be more like:
> > 
> > IF (IsEqual (Base(a), Base(b), NIL)
> > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)
> > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))
> > AND GetBounds (a, min_a, max_a)
> > AND GetBounds (b, min_b, max_b) THEN
> > (* check for a non-empty intersection *)
> > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END;
> > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END;
> > RETURN TInt.LE (min, max);
> > ELSE
> > RETURN FALSE;
> > END;
> > 
> > That way CARDINAL and other subranges fall right out.
> > 
> > Antony Hosking | Associate Professor | Computer Science | Purdue University
> > 305 N. University Street | West Lafayette | IN 47907 | USA
> > Office +1 765 494 6001 | Mobile +1 765 427 5484
> > 
> > 
> > 
> > 
> > On 8 Jan 2010, at 06:13, Jay K wrote:
> > 
> > > Attached is my latest work here.
> > > With the compiler changes (in the diff), I was able to
> > > elminate most uses of VAL(expr, LONGINT).
> > > There's something slightly off such that I had
> > > to add a very small number, like two.
> > > 
> > > 
> > > The compiler change is newer than earlier.
> > > For example you can now assign CARDINAL to LONGINT.
> > > I didn't do it, but you should also be able to add/subtract/etc.
> > > mixing CARDINAL and LONGINT.
> > > 
> > > 
> > > FOR statements also don't allow the level of mixing
> > > that they should.
> > > 
> > > 
> > > I'm hoping to get agreement soon just from the diffs
> > > but if necessary I'll look how to create a branch.
> > > My general worry about branches is developers just
> > > go off on their own in a branch and it's impossible to
> > > get anyone to look at it, they are busy enough with one branch,
> > > let alone multiple..
> > > 
> > > 
> > > - Jay
> > > <dif8.txt>
> > 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100109/f559ce4c/attachment-0002.html>


More information about the M3devel mailing list