(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: NarrowExpr.m3 *) (* Last Modified On Sat Feb 10 20:06:47 1990 By kalsow *) (* Modified On Tue Oct 10 18:42:30 1989 By muller *) MODULE NarrowExpr; IMPORT Expr, ExprRep, Type, String, SetExpr, Emit, Error; IMPORT Refany, Null, ObjectType, Temp, Wr, Address; TYPE P = Expr.T OBJECT expr : Expr.T; tipe : Type.T; METHODS bind := Bind; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := EqCheck; getBounds := Bounder; isWritable := IsWritable; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (a: Expr.T; t: Type.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.expr := a; p.tipe := t; RETURN p; END New; PROCEDURE Bind (p: P) = BEGIN Expr.Bind (p.expr); p.tipe := Type.Bind (p.tipe); p.type := p.tipe; END Bind; PROCEDURE Check (p: P) = VAR t, u: Type.T; BEGIN Expr.TypeCheck (p.expr); Type.Check (p.tipe); u := Expr.TypeOf (p.expr); t := Type.Base (p.tipe); IF ObjectType.Is (t) THEN (* ok *) ELSIF ( NOT Type.IsSubtype (t, Refany.T)) THEN Error.Msg ("NARROW: must be a traced reference type"); ELSIF ( NOT Type.IsAssignable (t, u)) THEN Error.Msg ("NARROW: types must be assignable"); ELSE (* REF type *) (* ok *) END; END Check; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN Type.IsEqual (a.tipe, b.tipe) AND Expr.IsEqual (a.expr, b.expr); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE Compile (p: P): Temp.T = VAR t, u, z: Type.T; e: Expr.T; t1, t2: Temp.T; BEGIN e := p.expr; u := Expr.TypeOf (e); t := p.tipe; z := Type.Base (t); IF (Type.IsEqual (u, t)) OR (Type.IsEqual (t, Refany.T)) THEN t2 := Expr.Compile (e); ELSIF (Type.IsEqual (t, Null.T)) THEN t1 := Expr.Compile (e); t2 := Temp.Alloc (p); Emit.OpTT ("@ = ((char*) @) == NIL ? NIL : NARROWFAULT;\n", t2, t1); Temp.Free (t1); ELSE t1 := Expr.Compile (e); t2 := Temp.Alloc (p); Emit.OpTT ("@ = NARROW (@, ", t2, t1); Emit.OpII ("t@, TC@, ", Type.Name (t), Type.Name (t)); Emit.OpT ("@);\n", t2); Temp.Free (t1); END; RETURN t2; END Compile; PROCEDURE Fold (p: P): Expr.T = BEGIN RETURN Expr.ConstValue (p.expr); END Fold; PROCEDURE Bounder (p: P; VAR min, max: INTEGER) = VAR min1, max1: INTEGER; BEGIN Expr.GetBounds (p.expr, min, max); Type.GetBounds (p.tipe, min1, max1); min := MAX (min, min1); max := MIN (max, max1); END Bounder; (**************************************** PROCEDURE IsDesignator (p: P): BOOLEAN = BEGIN RETURN Expr.IsDesignator (p.expr); END IsDesignator; ******************************************) PROCEDURE IsWritable (p: P): BOOLEAN = BEGIN RETURN Expr.IsWritable (p.expr); END IsWritable; PROCEDURE FPrinter (p: P; map: Type.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "NARROW "); Expr.Fingerprint (p.expr, map, wr); Type.Fingerprint (p.tipe, map, wr); END FPrinter; BEGIN END NarrowExpr.