[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