[M3devel] latest longint file size diffs
Rodney M. Bates
rodney_bates at lcwb.coop
Sun Jan 10 03:44:26 CET 2010
Jay K wrote:
> Uh, maybe all ordinal types that overlap in any values are assignable?
>
Yes, exactly. From 2.3.1:
"A type T is _assignable_ to a type U if:
.. <two other cases,> ..
or T and U are ordinal types with at least one member in common."
For an _expression_ to be assignable to T, some additional things must
be checked, some of them at runtime.
>
> 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 <mailto:hosking at cs.purdue.edu>
> > Date: Sat, 9 Jan 2010 00:37:42 -0500
> > To: jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>
> > CC: m3devel at elegosoft.com <mailto: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>
> >
>
>
More information about the M3devel
mailing list