MODULE; IMPORT M3, Expr, ExprRep, Type, Narrow, CG, Host, Target; TYPE P = Expr.T BRANDED "NarrowExpr" OBJECT expr : Expr.T; tipe : Type.T; tmp : CG.Val; OVERRIDES typeOf := ExprRep.NoType; check := Check; need_addr := NeedsAddress; prep := Prep; compile := Compile; prepLV := ExprRep.NotLValue; compileLV := ExprRep.NotLValue; prepBR := ExprRep.PrepNoBranch; compileBR := ExprRep.NoBranch; evaluate := Fold; isEqual := EqCheck; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; genFPLiteral := ExprRep.NoFPLiteral; prepLiteral := ExprRep.NoPrepLiteral; genLiteral := ExprRep.NoLiteral; note_write := ExprRep.NotWritable; END; PROCEDURE NarrowExpr New (a: Expr.T; t: Type.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.origin := a.origin; p.expr := a; p.tipe := t; p.type := t; p.tmp := NIL; RETURN p; END New; PROCEDURECheck (p: P; VAR cs: Expr.CheckState) = VAR info: Type.Info; BEGIN Expr.TypeCheck (p.expr, cs); p.tipe := Type.CheckInfo (p.tipe, info); END Check; PROCEDUREEqCheck (a: P; e: Expr.T; x: M3.EqAssumption): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN Type.IsEqual (a.tipe, b.tipe, x) AND Expr.IsEqual (a.expr, b.expr, x); ELSE RETURN FALSE; END; END EqCheck; PROCEDURENeedsAddress (p: P) = BEGIN Expr.NeedsAddress (p.expr); END NeedsAddress; PROCEDUREPrep (p: P) = BEGIN Expr.Prep (p.expr); Expr.Compile (p.expr); IF Host.doNarrowChk THEN Narrow.Emit (p.tipe, Expr.TypeOf (p.expr)); END; p.tmp := CG.Pop (); END Prep; PROCEDURECompile (p: P) = (* all the work was done by "Prep" *) BEGIN CG.Push (p.tmp); CG.Boost_alignment (Target.Address.align); CG.Free (p.tmp); p.tmp := NIL; END Compile; PROCEDUREFold (p: P): Expr.T = VAR e: Expr.T; BEGIN e := Expr.ConstValue (p.expr); IF (e = NIL) THEN RETURN NIL END; p.expr := e; IF NOT Host.doNarrowChk OR Type.IsSubtype (Expr.TypeOf (e), p.tipe) THEN RETURN e; END; RETURN p; END Fold; BEGIN END NarrowExpr.