File: AndExpr.m3 Last modified on Fri Jul 8 09:48:48 PDT 1994 by kalsow modified on Thu Nov 29 03:30:36 1990 by muller
MODULE; IMPORT CG, Expr, ExprRep, Type, Bool, EnumExpr, Target, TInt, Value; TYPE P = ExprRep.Tab BRANDED "AndExpr.P" OBJECT tmp: CG.Val; OVERRIDES typeOf := ExprRep.NoType; check := Check; need_addr := ExprRep.NotAddressable; prep := Prep; compile := Compile; prepLV := ExprRep.NotLValue; compileLV := ExprRep.NotLValue; prepBR := PrepBR; compileBR := ExprRep.NoBranch; evaluate := Fold; isEqual := ExprRep.EqCheckAB; 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 AndExpr New (a, b: Expr.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.a := a; p.b := b; p.type := Bool.T; p.tmp := NIL; RETURN p; END New; PROCEDURECheck (p: P; VAR cs: Expr.CheckState) = VAR ta, tb: Type.T; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); ta := Type.Base (Expr.TypeOf (p.a)); tb := Type.Base (Expr.TypeOf (p.b)); IF (ta # Bool.T) OR (tb # Bool.T) THEN p.type := Expr.BadOperands ("AND", ta, tb); END; END Check; PROCEDUREPrep (p: P) = VAR false := CG.Next_label (); BEGIN Value.Load (Bool.False); p.tmp := CG.Pop_temp (); PrepBR (p, CG.No_label, false, CG.Maybe); Value.Load (Bool.True); CG.Store_temp (p.tmp); CG.Set_label (false); END Prep; PROCEDURECompile (p: P) = BEGIN CG.Push (p.tmp); CG.Free (p.tmp); p.tmp := NIL; END Compile; PROCEDUREPrepBR (p: P; true, false: CG.Label; freq: CG.Frequency) = VAR skip: CG.Label; BEGIN IF (true = CG.No_label) THEN Expr.PrepBranch (p.a, true, false, freq); Expr.CompileBranch (p.a, true, false, freq); Expr.PrepBranch (p.b, true, false, freq); Expr.CompileBranch (p.b, true, false, freq); ELSE (* false = NoLabel => fall through *) skip := CG.Next_label (); Expr.PrepBranch (p.a, CG.No_label, skip, CG.Always - freq); Expr.CompileBranch (p.a, CG.No_label, skip, CG.Always - freq); Expr.PrepBranch (p.b, true, CG.No_label, freq); Expr.CompileBranch (p.b, true, CG.No_label, freq); CG.Set_label (skip); END; END PrepBR; PROCEDUREFold (p: P): Expr.T = VAR e1, e2: Expr.T; i1, i2: Target.Int; t1, t2: Type.T; z1, z2: INTEGER; BEGIN e1 := Expr.ConstValue (p.a); e2 := Expr.ConstValue (p.b); IF (e1 = NIL) OR (e2 = NIL) OR (NOT EnumExpr.Split (e1, i1, t1)) OR (NOT EnumExpr.Split (e2, i2, t2)) OR (Type.Base (t1) # Bool.T) OR (Type.Base (t2) # Bool.T) OR NOT TInt.ToInt (i1, z1) OR NOT TInt.ToInt (i2, z2) THEN RETURN NIL; ELSE RETURN Bool.Map[(ORD (TRUE) = z1) AND (ORD (TRUE) = z2)]; END; END Fold; BEGIN END AndExpr.