<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>