File: Ord.m3 Last Modified On Tue May 3 16:32:32 PDT 1994 By kalsow Modified On Sat Dec 8 00:54:19 1990 By muller
MODULE; IMPORT CallExpr, Expr, ExprRep, Type, Procedure, Int, LInt, Error; IMPORT IntegerExpr, EnumExpr, Target; VAR Z: CallExpr.MethodList; PROCEDURE Ord TypeOf (ce: CallExpr.T): Type.T = VAR t := Expr.TypeOf (ce.args[0]); BEGIN IF Type.IsSubtype (t, LInt.T) THEN RETURN LInt.T ELSE RETURN Int.T; END; END TypeOf; PROCEDURECheck (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; IF Type.IsSubtype (t, LInt.T) THEN ce.type := LInt.T; ELSE ce.type := Int.T; END; END Check; PROCEDURECompile (ce: CallExpr.T) = BEGIN Expr.Compile (ce.args[0]); END Compile; PROCEDUREFold (ce: CallExpr.T): Expr.T = VAR e: Expr.T; i: Target.Int; t: Type.T; BEGIN e := Expr.ConstValue (ce.args[0]); IF (e = NIL) THEN RETURN NIL; ELSIF EnumExpr.Split (e, i, t) THEN RETURN IntegerExpr.New (Int.T, i); ELSIF IntegerExpr.Split (e, i, t) THEN RETURN IntegerExpr.New (t, i); ELSE RETURN NIL; END; END Fold; PROCEDUREGetBounds (ce: CallExpr.T; VAR min, max: Target.Int) = BEGIN Expr.GetBounds (ce.args[0], min, max); END GetBounds; PROCEDUREInitialize () = BEGIN Z := CallExpr.NewMethodList (1, 1, TRUE, FALSE, TRUE, NIL, TypeOf, CallExpr.NotAddressable, Check, CallExpr.PrepArgs, Compile, CallExpr.NoLValue, CallExpr.NoLValue, CallExpr.NotBoolean, CallExpr.NotBoolean, Fold, GetBounds, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("ORD", Z, TRUE); END Initialize; BEGIN END Ord.