<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL.<BR>
 <BR>
  LONGINT + INTEGER => LONGINT <BR>
  LONGINT - INTEGER => LONGINT <BR>
  LONGINT * INTEGER => LONGINT <BR>
  LONGINT DIV INTEGER => LONGINT <BR>
  INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) <BR>
  INTEGER MOD LONGINT => INTEGER (subtle but I believe correct)  <BR>
  LONGINT MOD INTEGER => INTEGER (subtle but I believe correct)  <BR>
  MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER)  <BR>
  MAX(INTEGER, LONGINT) => LONGINT  <BR>
  LONGINT := INTEGER <BR>
 <BR>
Other mixes are less obvious and would require runtime checks.<BR>
 <BR>
I think the backend will just work but I haven't tried that yet.<BR>
 (Truth be told, I can only affectively edit files on NT...)<BR>
 <BR>
Thoughts?<BR>
 <BR>
 - Jay <BR>
 <BR>
Index: builtinOps/Dec.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v<BR>retrieving revision 1.9<BR>diff -u -r1.9 Dec.m3<BR>--- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9<BR>+++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -44,7 +44,7 @@<BR>     IF (NUMBER (ce.args^) > 1) THEN<BR>       IF Type.IsSubtype (t, LInt.T) THEN<BR>         t := Type.Base (Expr.TypeOf (ce.args[1]));<BR>-        IF (t # LInt.T) THEN<BR>+        IF t # LInt.T AND t # Int.T THEN<BR>           Error.Txt (name, "second argument must be a LONGINT");<BR>         END;<BR>       ELSE<BR>Index: builtinOps/Max.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v<BR>retrieving revision 1.3<BR>diff -u -r1.3 Max.m3<BR>--- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3<BR>+++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -25,11 +25,14 @@<BR> <BR> PROCEDURE DoCheck (name: TEXT;  ce: CallExpr.T) =<BR>   VAR ta, tb: Type.T;<BR>+      resultType: Type.T := NIL;<BR>   BEGIN<BR>     ta := Type.Base (Expr.TypeOf (ce.args[0]));<BR>     tb := Type.Base (Expr.TypeOf (ce.args[1]));<BR> <BR>-    IF (NOT Type.IsEqual (ta, tb, NIL)) THEN<BR>+    IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN<BR>+      resultType := LInt.T;<BR>+    ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN<BR>       Error.Txt (name, "incompatible argument types");<BR>     ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN<BR>       (* ok *)<BR>@@ -39,7 +42,11 @@<BR>       Error.Txt (name, "wrong argument types");<BR>       ta := Int.T;<BR>     END;<BR>-    ce.type := ta;<BR>+    IF resultType # NIL THEN<BR>+      ce.type := resultType;<BR>+    ELSE<BR>+      ce.type := ta;<BR>+    END;<BR>   END DoCheck;<BR> <BR> PROCEDURE Compile (ce: CallExpr.T) =<BR>Index: exprs/AddExpr.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v<BR>retrieving revision 1.3<BR>diff -u -r1.3 AddExpr.m3<BR>--- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3<BR>+++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -67,6 +67,7 @@<BR> <BR> PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =<BR>   VAR ta, tb, range: Type.T;<BR>+      resultType: Type.T := NIL;<BR>   BEGIN<BR>     Expr.TypeCheck (p.a, cs);<BR>     Expr.TypeCheck (p.b, cs);<BR>@@ -74,8 +75,9 @@<BR>     tb := Type.Base (Expr.TypeOf (p.b));<BR>     IF    (ta = Int.T)   AND (tb = Int.T)   THEN<BR>       p.class := Class.cINT;<BR>-    ELSIF (ta = LInt.T)  AND (tb = LInt.T) THEN<BR>-      p.class := Class.cLINT<BR>+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN<BR>+      p.class := Class.cLINT;<BR>+      resultType := LInt.T;<BR>     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN<BR>       p.class := Class.cREAL;<BR>     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN<BR>@@ -96,7 +98,11 @@<BR>     ELSE<BR>       ta := Expr.BadOperands ("\'+\'", ta, tb);<BR>     END;<BR>-    p.type := ta;<BR>+    IF resultType # NIL THEN<BR>+      p.type := resultType;<BR>+    ELSE<BR>+      p.type := ta;<BR>+    END;<BR>   END Check;<BR> <BR> PROCEDURE Prep (p: P) =<BR>Index: exprs/DivExpr.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v<BR>retrieving revision 1.5<BR>diff -u -r1.5 DivExpr.m3<BR>--- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5<BR>+++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -60,7 +60,7 @@<BR>     tb := Type.Base (Expr.TypeOf (p.b));<BR>     IF (ta = Int.T) AND (tb = Int.T) THEN<BR>       p.type := Int.T;<BR>-    ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN<BR>+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN<BR>       p.type := LInt.T;<BR>     ELSE<BR>       p.type := Expr.BadOperands ("DIV", ta, tb);<BR>Index: exprs/ModExpr.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v<BR>retrieving revision 1.5<BR>diff -u -r1.5 ModExpr.m3<BR>--- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5<BR>+++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -60,6 +60,7 @@<BR> <BR> PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =<BR>   VAR ta, tb: Type.T;<BR>+      resultType: Type.T := NIL;<BR>   BEGIN<BR>     Expr.TypeCheck (p.a, cs);<BR>     Expr.TypeCheck (p.b, cs);<BR>@@ -67,8 +68,18 @@<BR>     tb := Type.Base (Expr.TypeOf (p.b));<BR>     IF    (ta = Int.T)   AND (tb = Int.T)   THEN<BR>       p.class := Class.cINT;<BR>+<BR>     ELSIF (ta = LInt.T)  AND (tb = LInt.T)  THEN<BR>       p.class := Class.cLINT;<BR>+<BR>+    (* The result of MOD cannot be higher than either of its inputs.<BR>+     * small divided by big is 0 remainder small<BR>+     * big divided by small has a remainder of at most small<BR>+     *)<BR>+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN<BR>+      p.class := Class.cINT;<BR>+      resultType := Int.T;<BR>+<BR>     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN<BR>       p.class := Class.cREAL;<BR>     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN<BR>@@ -78,7 +89,11 @@<BR>     ELSE p.class := Class.cERR;  ta := Int.T;<BR>       ta := Expr.BadOperands ("MOD", ta, tb);<BR>     END;<BR>-    p.type := ta;<BR>+    IF resultType # NIL THEN<BR>+      p.type := resultType;<BR>+    ELSE<BR>+      p.type := ta;<BR>+    END;<BR>   END Check;<BR> <BR> PROCEDURE Prep (p: P) =<BR>Index: exprs/MultiplyExpr.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v<BR>retrieving revision 1.3<BR>diff -u -r1.3 MultiplyExpr.m3<BR>--- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3<BR>+++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -66,6 +66,7 @@<BR> <BR> PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =<BR>   VAR ta, tb, range: Type.T;<BR>+      resultType: Type.T := NIL;<BR>   BEGIN<BR>     Expr.TypeCheck (p.a, cs);<BR>     Expr.TypeCheck (p.b, cs);<BR>@@ -73,8 +74,9 @@<BR>     tb := Type.Base (Expr.TypeOf (p.b));<BR>     IF    (tb = Int.T)   AND (ta = Int.T)   THEN<BR>       p.class := cINT;<BR>-    ELSIF (tb = LInt.T)  AND (ta = LInt.T)  THEN<BR>+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN<BR>       p.class := cLINT;<BR>+      resultType := LInt.T;<BR>     ELSIF (tb = Reel.T)  AND (ta = Reel.T)  THEN<BR>       p.class := cREAL;<BR>     ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN<BR>@@ -90,7 +92,11 @@<BR>       ta := Expr.BadOperands ("\'*\'", ta, tb);<BR>       p.class := cINT;<BR>     END;<BR>-    p.type := ta;<BR>+    IF resultType # NIL THEN<BR>+      p.type := resultType;<BR>+    ELSE<BR>+      p.type := ta;<BR>+    END;<BR>   END Check;<BR> <BR> PROCEDURE Prep (p: P) =<BR>Index: exprs/SubtractExpr.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v<BR>retrieving revision 1.4<BR>diff -u -r1.4 SubtractExpr.m3<BR>--- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4<BR>+++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -73,6 +73,7 @@<BR> <BR> PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =<BR>   VAR ta, tb, range: Type.T;<BR>+      resultType: Type.T := NIL;<BR>   BEGIN<BR>     Expr.TypeCheck (p.a, cs);<BR>     Expr.TypeCheck (p.b, cs);<BR>@@ -80,8 +81,9 @@<BR>     tb := Type.Base (Expr.TypeOf (p.b));<BR>     IF    (ta = Int.T)   AND (tb = Int.T)   THEN<BR>       p.class := Class.cINT;<BR>-    ELSIF (ta = LInt.T)  AND (tb = LInt.T)  THEN<BR>+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN<BR>       p.class := Class.cLINT;<BR>+      resultType := LInt.T;<BR>     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN<BR>       p.class := Class.cREAL;<BR>     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN<BR>@@ -113,7 +115,11 @@<BR>       ta := Expr.BadOperands ("\'-\'", ta, tb);<BR>       p.class := Class.cINT;<BR>     END;<BR>-    p.type := ta;<BR>+    IF resultType # NIL THEN<BR>+      p.type := resultType;<BR>+    ELSE<BR>+      p.type := ta;<BR>+    END;<BR>   END Check;<BR> <BR> PROCEDURE Prep (p: P) =<BR>Index: types/Type.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v<BR>retrieving revision 1.8<BR>diff -u -r1.8 Type.m3<BR>--- types/Type.m3 4 May 2008 11:03:49 -0000 1.8<BR>+++ types/Type.m3 8 Jan 2010 07:35:43 -0000<BR>@@ -543,6 +543,10 @@<BR>     IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN<BR>       RETURN TRUE;<BR>     ELSIF IsOrdinal (a) THEN<BR>+      (* INTEGER is assignable to LONGINT *)<BR>+      IF a = LInt.T AND b = Int.T THEN<BR>+        RETURN TRUE;<BR>+      END;<BR>       (* ordinal types:  OK if there is a common supertype<BR>          and they have at least one member in common. *)<BR>       IF IsEqual (Base(a), Base(b), NIL)<BR><BR><BR><BR><BR><BR><BR>                                       </body>
</html>