Index: Ord.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Ord.m3,v retrieving revision 1.4 diff -u -r1.4 Ord.m3 --- Ord.m3 18 Sep 2007 20:25:36 -0000 1.4 +++ Ord.m3 14 Jan 2010 12:23:25 -0000 @@ -9,52 +9,26 @@ MODULE Ord; IMPORT CallExpr, Expr, ExprRep, Type, Procedure, Int, LInt, Error; -IMPORT IntegerExpr, EnumExpr, CheckExpr, Target, TInt, CG; +IMPORT IntegerExpr, EnumExpr, Target; VAR Z: CallExpr.MethodList; -PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) = - VAR e := ce.args[0]; t := Expr.TypeOf (e); - emin, emax: Target.Int; +PROCEDURE Check (ce: CallExpr.T; <*UNUSED*> VAR cs: Expr.CheckState) = + VAR t: Type.T; BEGIN + t := Expr.TypeOf (ce.args[0]); IF NOT Type.IsOrdinal (t) THEN Error.Msg ("ORD: argument must be an ordinal"); END; - ce.type := Int.T; - IF Type.IsSubtype (t, LInt.T) AND ce.type = Int.T THEN - (* must bound check the result *) - Expr.GetBounds (e, emin, emax); - IF TInt.LT (emin, Target.Integer.min) THEN - (* we need a lower bound check *) - IF TInt.LT (Target.Integer.max, emax) THEN - (* we also need an upper bound check *) - e := CheckExpr.New (e, Target.Integer.min, Target.Integer.max, - CG.RuntimeError.ValueOutOfRange); - Expr.TypeCheck (e, cs); - ce.args[0] := e; - ELSE - e := CheckExpr.NewLower (e, Target.Integer.min, - CG.RuntimeError.ValueOutOfRange); - Expr.TypeCheck (e, cs); - ce.args[0] := e; - END; - ELSIF TInt.LT (Target.Integer.max, emax) THEN - (* we need an upper bound check *) - e := CheckExpr.NewUpper (e, Target.Integer.max, - CG.RuntimeError.ValueOutOfRange); - Expr.TypeCheck (e, cs); - ce.args[0] := e; - END; + IF Type.IsSubtype (t, LInt.T) + THEN ce.type := LInt.T; + ELSE ce.type := Int.T; END; END Check; PROCEDURE Compile (ce: CallExpr.T) = - VAR e := ce.args[0]; t := Expr.TypeOf (e); BEGIN - Expr.Compile (e); - IF Type.IsSubtype (t, LInt.T) THEN - CG.Loophole (Target.Longint.cg_type, Target.Integer.cg_type); - END; + Expr.Compile (ce.args[0]); END Compile; PROCEDURE Fold (ce: CallExpr.T): Expr.T = @@ -66,18 +40,15 @@ ELSIF EnumExpr.Split (e, i, t) THEN RETURN IntegerExpr.New (Int.T, i); ELSIF IntegerExpr.Split (e, i, t) THEN - RETURN IntegerExpr.New (Int.T, i); + RETURN IntegerExpr.New (t, i); ELSE RETURN NIL; END; END Fold; PROCEDURE GetBounds (ce: CallExpr.T; VAR min, max: Target.Int) = - VAR e := ce.args[0]; BEGIN - Expr.GetBounds (e, min, max); - IF TInt.LT (min, Target.Integer.min) THEN min := Target.Integer.min END; - IF TInt.LT (Target.Integer.max, max) THEN max := Target.Integer.max END; + Expr.GetBounds (ce.args[0], min, max); END GetBounds; PROCEDURE Initialize () = Index: Val.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Val.m3,v retrieving revision 1.4 diff -u -r1.4 Val.m3 --- Val.m3 18 Sep 2007 20:25:36 -0000 1.4 +++ Val.m3 14 Jan 2010 12:23:25 -0000 @@ -26,10 +26,14 @@ VAR t, u: Type.T; mint, maxt, minu, maxu: Target.Int; BEGIN u := Expr.TypeOf (ce.args[0]); - t := Int.T; - IF NOT Type.IsSubtype (u, Int.T) THEN - Error.Msg ("VAL: first argument must be an INTEGER"); - ELSIF NOT TypeExpr.Split (ce.args[1], t) THEN + IF Type.IsSubtype (u, LInt.T) THEN + t := LInt.T; + ELSIF Type.IsSubtype (u, Int.T) THEN + t := Int.T + ELSE + Error.Msg ("VAL: first argument must be an integer"); + END; + IF NOT TypeExpr.Split (ce.args[1], t) THEN Error.Msg ("VAL: second argument must be a type"); ELSIF NOT Type.IsOrdinal (t) THEN Error.Msg ("VAL: second argument must be an ordinal type"); @@ -64,12 +68,21 @@ END Prep; PROCEDURE Compile (ce: CallExpr.T) = - VAR t: Type.T; + VAR t, u: Type.T; BEGIN + u := Expr.TypeOf (ce.args[0]); IF TypeExpr.Split (ce.args[1], t) THEN Type.Compile (t) END; Expr.Compile (ce.args[0]); IF Type.IsSubtype (t, LInt.T) THEN - CG.Loophole (Target.Integer.cg_type, Target.Longint.cg_type); + (* definitely not an enumeration *) + IF Type.IsSubtype (u, Int.T) THEN + CG.Loophole (Target.Integer.cg_type, Target.Longint.cg_type); + END; + ELSE + (* base type Int.T or enumeration *) + IF Type.IsSubtype (u, LInt.T) THEN + CG.Loophole (Target.Longint.cg_type, Target.Integer.cg_type); + END; END; END Compile;