<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Hi all:<br>and even more I can tell you there is plenty of teaching material on Object Oriented software construction in Modula-3 for Meyer's book,  then what about pulishing it and rewriting it in scripts of Obliq, which is harder to learn from 0, I guess Modula-3, but even if we facilitate that, what else is missing here (mentor, zeus3D, Obliq3D examples). See the same mentioned linked page.<br>About Second comment on that page, I guess they talk about Model driven checking, from which there are tools that do that and are open source if they are so much we could adapt them to it. See Spec language.<br><br>Thanks in advance<br><br>--- El <b>lun, 23/5/11, Daniel Alejandro Benavides D. <i><dabenavidesd@yahoo.es></i></b> escribió:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>De: Daniel
 Alejandro Benavides D. <dabenavidesd@yahoo.es><br>Asunto: Re: [M3devel] range analysis?<br>Para: "Tony" <hosking@cs.purdue.edu>, "Jay K" <jay.krell@cornell.edu><br>CC: "m3devel" <m3devel@elegosoft.com><br>Fecha: lunes, 23 de mayo, 2011 17:54<br><br><div id="yiv1812973711"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td style="font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit;" valign="top">Hi all:<br>an this could be even more payable in embedded architectures, of course there is always more work, but the market, is moving towards that I mean, people are *really* worried about lock-free data structures, etc, when there are tools that tackle that automatically or treat them formally and in Modula-3,
 see:<br>http://www.eetimes.com/discussion/break-points/4027598/Executing-software-contracts<br><br>I'm thinking in this more seriously, and by the amount of time they devised modula-3 end (1996 if I may say so), which is at least 10 years ahead of its common use and the tools they did as was their goal in DEC SRC, we are still on the front or struggling if so (and off-time of 5 years still have some room to speak up). And could be more if you think in separate efforts on it.<br><br>As I heard from an old M3 friend, Obliq was  merely about to be
 the language standard for web and yet not one of them has the full technology of it as is (meaning it was the first agent language and it has type inference, and it's fast!). think in the  Java JS binomial, for example and alike.<br><br>I mean such an example, of usage and precedence in time is enough to say the quality in terms of the all package (Modula-3 and scripting language)<br><br>Ok, it would be interesting to see why did they to take such decision (old friend's wish).<br><br>Thanks in advance<br><br>--- El <b>lun, 23/5/11, Daniel Alejandro Benavides D. <i><dabenavidesd@yahoo.es></i></b> escribió:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>De: Daniel Alejandro Benavides D. <dabenavidesd@yahoo.es><br>Asunto: Re: [M3devel] range analysis?<br>Para: "Tony" <hosking@cs.purdue.edu>, "Jay K" <jay.krell@cornell.edu><br>CC: "m3devel"
 <m3devel@elegosoft.com><br>Fecha: lunes, 23 de mayo, 2011 15:44<br><br><div id="yiv1812973711"><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td style="font-family: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit;" valign="top">Hi all:<br>in one process it might be good to check for those optimization, but then you might want to abstract them all to allow to be pessimistic or to analyze them in ESC.<br>This should require some good knowledge of the compiler though, which is maybe a harder task than just build a VCG but perhaps is too slow for m3cg, maybe for native backends, is more justifiable if so. Perhaps there is enough good trade off to do so.<br><br>Thanks in advance<br><br>--- El <b>dom, 22/5/11, Jay K <i><jay.krell@cornell.edu></i></b> escribió:<br><blockquote style="border-left: 2px solid rgb(16, 16,
 255); margin-left: 5px; padding-left: 5px;"><br>De: Jay K <jay.krell@cornell.edu><br>Asunto: Re: [M3devel] range analysis?<br>Para: "Tony" <hosking@cs.purdue.edu><br>CC: "m3devel" <m3devel@elegosoft.com><br>Fecha: domingo, 22 de mayo, 2011
 18:18<br><br><div id="yiv1812973711">

<style><!--
#yiv1812973711   .yiv1812973711hmmessage P
{
margin:0px;padding:0px;}
#yiv1812973711   .yiv1812973711hmmessage
{
font-size:10pt;font-family:Tahoma;}
--></style>
Well, I can build the whole tree and see how many times it helps.<br>I think this is a pretty standard optimization technique.<br>Though it'd work better with compiler-derived additional information.<br><br>I initially happened upon this idea developing test cases.<br><br><span class="yiv1812973711ecxApple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"> > The code assumes the minimum of a type is less than or equal to its maximum.<br></span><br>I'll change it not have that problem -- to just fall back to usual pessimistic code for such types, I guess.<br><br> - Jay<br><br><br><hr id="yiv1812973711stopSpelling">Subject: Re: range analysis?<br>From: hosking@cs.purdue.edu<br>Date: Sun, 22 May
 2011 14:51:59 -0400<br>CC: m3devel@elegosoft.com<br>To: jay.krell@cornell.edu<br><br>
 
<base>So, one question is: what benefit does this really give?  Your examples seem a little contrived.<div><br><div>
<br><div><div>On May 22, 2011, at 4:26 AM, Jay K wrote:</div><br class="yiv1812973711ecxApple-interchange-newline"><blockquote><span class="yiv1812973711ecxApple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><div class="yiv1812973711ecxhmmessage" style="font-size: 10pt; font-family: Tahoma;">I've been sitting on this diff a long while.<br><br>In some places the frontend knows the bounds of a type/value and<br>will optimize away range checks. I'm pretty sure.<br><br><br><br>This makes it do that more.<br><br><br>I haven't looked at or tested this in ages.<br>But the basic idea seems sound, simple, easy enough to get a few small wins from.<br><br>For example if you have:<br><br>a: [-10..-1];<br>b:
 [1..10];<br><br>then all comparisons between a and b are compile-time constant.<br><br>Comparisons of cardinals to negative numbers, likewise.<br><br>One thing maybe missing below is handling of empty ranges like<br>a: [1..-1];<br><br>The code assumes the minimum of a type is less than or equal to its maximum.<br><br><br>Index: m3-sys/m3front/src/misc/CG.i3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/CG.i3,v<br>retrieving revision 1.15<br>diff -r1.15 CG.i3<br>11c11<br>< IMPORT Target, M3CG, M3;<br>---<br>> IMPORT Target, M3CG, M3, TInt;<br>402c402,406<br>< PROCEDURE Load (v: Var;  o: Offset;  s: Size;  a: Alignment;  t: Type);<br>---<br>> PROCEDURE Load (v: Var;  o: Offset;  s: Size;  a: Alignment;  t: Type;<br>>                 min_valid:
 BOOLEAN := FALSE;<br>>                 max_valid: BOOLEAN := FALSE;<br>>                 min: Target.Int := TInt.Zero;<br>>                 max: Target.Int := TInt.Zero);<br>414,415c418,423<br>< PROCEDURE Load_int (t: IType;  v: Var;  o: Offset := 0);<br>< (* == Load (v, o, t.size, t.align, t) *)<br>---<br>> PROCEDURE Load_int (t: IType;  v: Var;  o: Offset := 0;<br>>                     min_valid: BOOLEAN := FALSE;<br>>                     max_valid: BOOLEAN :=
 FALSE;<br>>                     min: Target.Int := TInt.Zero;<br>>                     max: Target.Int := TInt.Zero);<br>> (* == Load (v, o, t.size, t.align, t, min/max...) *)<br>Index: m3-sys/m3front/src/misc/CG.m3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/CG.m3,v<br>retrieving revision 1.40<br>diff -r1.40 CG.m3<br>13c13<br>< IMPORT M3, M3CG, M3CG_Ops, M3CG_Check;<br>---<br>> IMPORT M3, M3CG, M3CG_Ops, M3CG_Check, RTIO, RTParams;<br>45a46,49<br>>     min_valid : BOOLEAN := FALSE; (* whether or not min is valid *)<br>>     max_valid : BOOLEAN := FALSE; (* whether or not max is valid *)<br>>    
 min       : Target.Int := TInt.Zero; (* the minimum possible value *)<br>>     max       : Target.Int := TInt.Zero; (* the maximum possible value *)<br>80c84,85<br>< VAR<br>---<br>> VAR<br>>   debug := FALSE;<br>604a610,614<br>>     v.min       := TInt.Zero;<br>>     v.max       := TInt.Zero;<br>>     v.min_valid := FALSE;<br>>     v.max_valid := FALSE;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>766a777,780<br>>     x.min       := TInt.Zero;<br>>     x.max       := TInt.Zero;<br>>     x.min_valid := FALSE;<br>>    
 x.max_valid := FALSE;<br>978a993,995<br>>       IF debug THEN<br>>         RTIO.PutText("m3front:cg:Init_int:NOT in_init: o: " & Fmt.Int(o) & " s:" & Fmt.Int(s) & " value:" & TInt.ToText(value) & "\n"); RTIO.Flush();<br>>       END;<br>980a998,1001<br>>     END;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>     IF debug THEN<br>>       RTIO.PutText("m3front:cg:Init_int:in_init: o: " & Fmt.Int(o) & " s:" & Fmt.Int(s) & " value:" & TInt.ToText(value) & "\n"); RTIO.Flush();<br>1266c1287,1291<br>< PROCEDURE Load (v: Var;  o: Offset;  s: Size;  a: Alignment;  t: Type) =<br>---<br>> PROCEDURE Load (v: Var;  o: Offset;  s: Size;  a: Alignment;  t:
 Type;<br>>                 min_valid: BOOLEAN := FALSE;<br>>                 max_valid: BOOLEAN := FALSE;<br>>                 min: Target.Int := TInt.Zero;<br>>                 max: Target.Int := TInt.Zero) =<br>1276c1301<br><       SimpleLoad (v, o, t);<br>---<br>>       SimpleLoad (v, o, t, min_valid, max_valid, min, max);<br>1291c1316<br><         SimpleLoad (v, o, best_type);<br>---<br>>         SimpleLoad (v, o, best_type, min_valid, max_valid, min,
 max);<br>1312c1337,1341<br>< PROCEDURE SimpleLoad (v: Var;  o: Offset;  t: Type) =<br>---<br>> PROCEDURE SimpleLoad (v: Var;  o: Offset;  t: Type;<br>>                       min_valid: BOOLEAN := FALSE;<br>>                       max_valid: BOOLEAN := FALSE;<br>>                       min: Target.Int := TInt.Zero;<br>>                       max: Target.Int := TInt.Zero) =<br>1323a1353,1356<br>>       x.min_valid :=
 min_valid;<br>>       x.max_valid := max_valid;<br>>       x.min       := min;<br>>       x.max       := max;<br>1339a1373,1376<br>>       x.min       := TInt.Zero;<br>>       x.max       := TInt.Zero;<br>>       x.min_valid := FALSE;<br>>       x.max_valid := FALSE;<br>1347a1385,1388<br>>     stack[tos-1].min       := TInt.Zero;<br>>     stack[tos-1].max       := TInt.Zero;<br>>     stack[tos-1].min_valid := FALSE;<br>>     stack[tos-1].max_valid :=
 FALSE;<br>1350c1391,1395<br>< PROCEDURE Load_int (t: IType;  v: Var;  o: Offset := 0) =<br>---<br>> PROCEDURE Load_int (t: IType;  v: Var;  o: Offset := 0;<br>>                     min_valid: BOOLEAN := FALSE;<br>>                     max_valid: BOOLEAN := FALSE;<br>>                     min: Target.Int := TInt.Zero;<br>>                     max: Target.Int := TInt.Zero) =<br>1352c1397<br><     SimpleLoad (v, o, t);<br>---<br>>     SimpleLoad (v, o, t, min_valid, max_valid, min,
 max);<br>1815a1861,1864<br>>       x.min_valid := TRUE;<br>>       x.max_valid := TRUE;<br>>       x.min := i;<br>>       x.max := i;<br>1832,1834c1881,2007<br><   BEGIN<br><     IF Force_pair (commute := TRUE) THEN<br><       op := M3CG.SwappedCompare [op];<br>---<br>>   VAR always_true: BOOLEAN;<br>>       always_false: BOOLEAN;<br>>       left_type: Type;<br>>       right_type: Type;<br>>       left_min: Target.Int;<br>>       left_max: Target.Int;<br>>       right_min: Target.Int;<br>>       right_max:
 Target.Int;<br>>       left_signed: BOOLEAN;<br>>       right_signed: BOOLEAN;<br>>   BEGIN<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>     always_true := FALSE;<br>>     always_false := FALSE;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>     WITH left  = stack [SCheck (2, "Compare-left")],<br>>          right = stack [SCheck (1, "Compare-right")] DO<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>       left_type := left.type;<br>>       right_type := right.type;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>      
 IF      left.min_valid<br>>           AND left.max_valid<br>>           AND right.min_valid<br>>           AND right.max_valid<br>>           AND Target.OrdinalType[left_type]<br>>           AND Target.OrdinalType[right_type] THEN<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>         left_min := left.min;<br>>         left_max := left.max;<br>>         right_min := right.min;<br>>         right_max := right.max;<br>>        
 left_signed := Target.SignedType[left_type];<br>>         right_signed := Target.SignedType[right_type];<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>         (* First handle types that match in signedness. *)<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>         IF left_signed = right_signed THEN<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           (* Check for ranges with no overlap. *)<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           IF left_signed (* and right_signed *) THEN<br>>             IF TInt.LT(left_max,
 right_min) THEN<br>>               always_true := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.EQ};<br>>             ELSIF TInt.GT(left_min, right_max) THEN<br>>               always_true := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.EQ};<br>>             END;<br>>           ELSE (* left_signed and right_signed both false
 *)<br>>             IF TWord.LT(left_max, right_min) THEN<br>>               always_true := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.EQ};<br>>             ELSIF TWord.GT(left_min, right_max) THEN<br>>               always_true := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.EQ};<br>>            
 END;<br>>           END;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           (* Check for overlap just on the edge, e.g. [0..1] compared to [1..2]. *)<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           IF NOT (always_true OR always_false) THEN<br>>             IF TInt.EQ(left_max, right_min) THEN<br>>               always_true := op = Cmp.LE;<br>>               always_false := op = Cmp.GT;<br>>             ELSIF TInt.EQ(left_min, right_max)
 THEN<br>>               always_true := op = Cmp.GE;<br>>               always_false := op = Cmp.LT;<br>>             END;<br>>           END;<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           (* Handle equal subranges with one element, not likely to occur. *)<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           IF NOT (always_true OR always_false) THEN<br>>             IF      TInt.EQ(left_max,
 left_min)<br>>                 AND TInt.EQ(left_max, right_max)<br>>                 AND TInt.EQ(left_max, right_min) THEN<br>>               always_true  := op IN SET OF Cmp{Cmp.GE, Cmp.LE, Cmp.EQ};<br>>               always_false := op IN SET OF Cmp{Cmp.LT, Cmp.GT, Cmp.NE};<br>>             END;<br>>           END;<br>>         ELSE<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           (* Now deal
 with mixed up types (signed compared to unsigned).<br>>            * We may be able to merge these by setting some min/max<br>>            * to zero. That is, the minimum of an unsigned type is zero.<br>>            * However we want to be sure not to interpret unsigned min/max<br>>            * as signed.<br>>            *)<br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>           IF left_signed THEN<br>>             IF TInt.LT(left_max, TInt.Zero)
 THEN<br>>               always_true  := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.EQ};<br>>             ELSIF TInt.EQ(left_max, TInt.Zero) THEN<br>>               always_true  := op = Cmp.LE;<br>>               always_false := op = Cmp.GT;<br>>             END;<br>>           ELSE (* right is signed *)<br>>             IF TInt.LT(right_max,
 TInt.Zero) THEN<br>>               always_true  := op IN SET OF Cmp{Cmp.GT, Cmp.GE, Cmp.NE};<br>>               always_false := op IN SET OF Cmp{Cmp.LT, Cmp.LE, Cmp.EQ};<br>>             ELSIF TInt.EQ(right_max, TInt.Zero) THEN<br>>               always_true := op = Cmp.GE;<br>>               always_false := op = Cmp.LT;<br>>             END;<br>>           END;<br>>         END;<br>>      
 END;<br>> <span class="yiv1812973711ecxApple-converted-space"> </span><br>>       <* ASSERT NOT (always_true AND always_false) *><br>><span class="yiv1812973711ecxApple-converted-space"> </span><br>>       IF always_true OR always_false THEN<br>>         Discard(right_type);<br>>         Discard(left_type);<br>>         IF always_true THEN<br>>           cg.load_integer (Target.Integer.cg_type, TInt.One);<br>>         ELSE<br>>           cg.load_integer (Target.Integer.cg_type, TInt.Zero);<br>>        
 END<br>>       ELSE<br>>         IF Force_pair (commute := TRUE) THEN<br>>           op := M3CG.SwappedCompare [op];<br>>         END;<br>>         cg.compare (t, Target.Integer.cg_type, op);<br>>         SPop (2, "Compare");<br>>       END;<br>1836,1837d2008<br><     cg.compare (t, Target.Integer.cg_type, op);<br><     SPop (2, "Compare");<br>2880a3052,3055<br>>       x.min       := TInt.Zero;<br>>       x.max       := TInt.Zero;<br>>       x.min_valid :=
 FALSE;<br>>       x.max_valid := FALSE;<br>2977c3152,3153<br>< BEGIN<br>---<br>> BEGIN<br>>   debug := debug OR RTParams.IsPresent ("m3front_cg_debug");<br>Index: m3-sys/m3front/src/values/Variable.m3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/values/Variable.m3,v<br>retrieving revision 1.13<br>diff -r1.13 Variable.m3<br>362a363,365<br>>   VAR min: Target.Int;<br>>       max: Target.Int;<br>>       bounds_valid: BOOLEAN;<br>395c398,401<br><         CG.Load (t.cg_var, t.offset, t.size, t.cg_align, t.stk_type);<br>---<br>>         (*GetBounds (t, min, max);<br>>         bounds_valid := TInt.LE(min,
 max);*)<br>>         bounds_valid := t.tipe # NIL AND Type.GetBounds(t.tipe, min, max) AND TInt.LE(min, max);<br>>         CG.Load (t.cg_var, t.offset, t.size, t.cg_align, t.stk_type, bounds_valid, bounds_valid, min, max);<br><br><br><br><br><br></div></span></blockquote></div><br></div></div>                                           
</div></blockquote></td></tr></tbody></table></div></blockquote></td></tr></tbody></table></div></blockquote></td></tr></table>