[M3devel] mixing INTEGER and LONGINT?

Jay K jay.krell at cornell.edu
Fri Jan 8 08:44:53 CET 2010


This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL.

 

  LONGINT + INTEGER => LONGINT 

  LONGINT - INTEGER => LONGINT 

  LONGINT * INTEGER => LONGINT 

  LONGINT DIV INTEGER => LONGINT 

  INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) 

  INTEGER MOD LONGINT => INTEGER (subtle but I believe correct)  

  LONGINT MOD INTEGER => INTEGER (subtle but I believe correct)  

  MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER)  

  MAX(INTEGER, LONGINT) => LONGINT  

  LONGINT := INTEGER 

 

Other mixes are less obvious and would require runtime checks.

 

I think the backend will just work but I haven't tried that yet.

 (Truth be told, I can only affectively edit files on NT...)

 

Thoughts?

 

 - Jay 

 

Index: builtinOps/Dec.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v
retrieving revision 1.9
diff -u -r1.9 Dec.m3
--- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9
+++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000
@@ -44,7 +44,7 @@
     IF (NUMBER (ce.args^) > 1) THEN
       IF Type.IsSubtype (t, LInt.T) THEN
         t := Type.Base (Expr.TypeOf (ce.args[1]));
-        IF (t # LInt.T) THEN
+        IF t # LInt.T AND t # Int.T THEN
           Error.Txt (name, "second argument must be a LONGINT");
         END;
       ELSE
Index: builtinOps/Max.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v
retrieving revision 1.3
diff -u -r1.3 Max.m3
--- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3
+++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000
@@ -25,11 +25,14 @@
 
 PROCEDURE DoCheck (name: TEXT;  ce: CallExpr.T) =
   VAR ta, tb: Type.T;
+      resultType: Type.T := NIL;
   BEGIN
     ta := Type.Base (Expr.TypeOf (ce.args[0]));
     tb := Type.Base (Expr.TypeOf (ce.args[1]));
 
-    IF (NOT Type.IsEqual (ta, tb, NIL)) THEN
+    IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN
+      resultType := LInt.T;
+    ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN
       Error.Txt (name, "incompatible argument types");
     ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN
       (* ok *)
@@ -39,7 +42,11 @@
       Error.Txt (name, "wrong argument types");
       ta := Int.T;
     END;
-    ce.type := ta;
+    IF resultType # NIL THEN
+      ce.type := resultType;
+    ELSE
+      ce.type := ta;
+    END;
   END DoCheck;
 
 PROCEDURE Compile (ce: CallExpr.T) =
Index: exprs/AddExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v
retrieving revision 1.3
diff -u -r1.3 AddExpr.m3
--- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3
+++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000
@@ -67,6 +67,7 @@
 
 PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =
   VAR ta, tb, range: Type.T;
+      resultType: Type.T := NIL;
   BEGIN
     Expr.TypeCheck (p.a, cs);
     Expr.TypeCheck (p.b, cs);
@@ -74,8 +75,9 @@
     tb := Type.Base (Expr.TypeOf (p.b));
     IF    (ta = Int.T)   AND (tb = Int.T)   THEN
       p.class := Class.cINT;
-    ELSIF (ta = LInt.T)  AND (tb = LInt.T) THEN
-      p.class := Class.cLINT
+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN
+      p.class := Class.cLINT;
+      resultType := LInt.T;
     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN
       p.class := Class.cREAL;
     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN
@@ -96,7 +98,11 @@
     ELSE
       ta := Expr.BadOperands ("\'+\'", ta, tb);
     END;
-    p.type := ta;
+    IF resultType # NIL THEN
+      p.type := resultType;
+    ELSE
+      p.type := ta;
+    END;
   END Check;
 
 PROCEDURE Prep (p: P) =
Index: exprs/DivExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v
retrieving revision 1.5
diff -u -r1.5 DivExpr.m3
--- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5
+++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000
@@ -60,7 +60,7 @@
     tb := Type.Base (Expr.TypeOf (p.b));
     IF (ta = Int.T) AND (tb = Int.T) THEN
       p.type := Int.T;
-    ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN
+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN
       p.type := LInt.T;
     ELSE
       p.type := Expr.BadOperands ("DIV", ta, tb);
Index: exprs/ModExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v
retrieving revision 1.5
diff -u -r1.5 ModExpr.m3
--- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5
+++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000
@@ -60,6 +60,7 @@
 
 PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =
   VAR ta, tb: Type.T;
+      resultType: Type.T := NIL;
   BEGIN
     Expr.TypeCheck (p.a, cs);
     Expr.TypeCheck (p.b, cs);
@@ -67,8 +68,18 @@
     tb := Type.Base (Expr.TypeOf (p.b));
     IF    (ta = Int.T)   AND (tb = Int.T)   THEN
       p.class := Class.cINT;
+
     ELSIF (ta = LInt.T)  AND (tb = LInt.T)  THEN
       p.class := Class.cLINT;
+
+    (* The result of MOD cannot be higher than either of its inputs.
+     * small divided by big is 0 remainder small
+     * big divided by small has a remainder of at most small
+     *)
+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN
+      p.class := Class.cINT;
+      resultType := Int.T;
+
     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN
       p.class := Class.cREAL;
     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN
@@ -78,7 +89,11 @@
     ELSE p.class := Class.cERR;  ta := Int.T;
       ta := Expr.BadOperands ("MOD", ta, tb);
     END;
-    p.type := ta;
+    IF resultType # NIL THEN
+      p.type := resultType;
+    ELSE
+      p.type := ta;
+    END;
   END Check;
 
 PROCEDURE Prep (p: P) =
Index: exprs/MultiplyExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v
retrieving revision 1.3
diff -u -r1.3 MultiplyExpr.m3
--- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3
+++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000
@@ -66,6 +66,7 @@
 
 PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =
   VAR ta, tb, range: Type.T;
+      resultType: Type.T := NIL;
   BEGIN
     Expr.TypeCheck (p.a, cs);
     Expr.TypeCheck (p.b, cs);
@@ -73,8 +74,9 @@
     tb := Type.Base (Expr.TypeOf (p.b));
     IF    (tb = Int.T)   AND (ta = Int.T)   THEN
       p.class := cINT;
-    ELSIF (tb = LInt.T)  AND (ta = LInt.T)  THEN
+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN
       p.class := cLINT;
+      resultType := LInt.T;
     ELSIF (tb = Reel.T)  AND (ta = Reel.T)  THEN
       p.class := cREAL;
     ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN
@@ -90,7 +92,11 @@
       ta := Expr.BadOperands ("\'*\'", ta, tb);
       p.class := cINT;
     END;
-    p.type := ta;
+    IF resultType # NIL THEN
+      p.type := resultType;
+    ELSE
+      p.type := ta;
+    END;
   END Check;
 
 PROCEDURE Prep (p: P) =
Index: exprs/SubtractExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v
retrieving revision 1.4
diff -u -r1.4 SubtractExpr.m3
--- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4
+++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000
@@ -73,6 +73,7 @@
 
 PROCEDURE Check (p: P;  VAR cs: Expr.CheckState) =
   VAR ta, tb, range: Type.T;
+      resultType: Type.T := NIL;
   BEGIN
     Expr.TypeCheck (p.a, cs);
     Expr.TypeCheck (p.b, cs);
@@ -80,8 +81,9 @@
     tb := Type.Base (Expr.TypeOf (p.b));
     IF    (ta = Int.T)   AND (tb = Int.T)   THEN
       p.class := Class.cINT;
-    ELSIF (ta = LInt.T)  AND (tb = LInt.T)  THEN
+    ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN
       p.class := Class.cLINT;
+      resultType := LInt.T;
     ELSIF (ta = Reel.T)  AND (tb = Reel.T)  THEN
       p.class := Class.cREAL;
     ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN
@@ -113,7 +115,11 @@
       ta := Expr.BadOperands ("\'-\'", ta, tb);
       p.class := Class.cINT;
     END;
-    p.type := ta;
+    IF resultType # NIL THEN
+      p.type := resultType;
+    ELSE
+      p.type := ta;
+    END;
   END Check;
 
 PROCEDURE Prep (p: P) =
Index: types/Type.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v
retrieving revision 1.8
diff -u -r1.8 Type.m3
--- types/Type.m3 4 May 2008 11:03:49 -0000 1.8
+++ types/Type.m3 8 Jan 2010 07:35:43 -0000
@@ -543,6 +543,10 @@
     IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN
       RETURN TRUE;
     ELSIF IsOrdinal (a) THEN
+      (* INTEGER is assignable to LONGINT *)
+      IF a = LInt.T AND b = Int.T THEN
+        RETURN TRUE;
+      END;
       (* ordinal types:  OK if there is a common supertype
          and they have at least one member in common. *)
       IF IsEqual (Base(a), Base(b), NIL)






 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100108/49a9d43f/attachment-0001.html>


More information about the M3devel mailing list