(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: DivideExpr.m3 *) (* Last modified on Fri May 25 02:49:26 1990 by muller *) (* modified on Sat Feb 10 17:34:27 1990 by kalsow *) MODULE DivideExpr; IMPORT Expr, ExprAB, ExprABC, ExprRep, Type, Error, Reel, Longreal; IMPORT SetExpr, RealExpr, LongrealExpr, Temp, Wr, Emit, SetType; CONST cREAL = 0; cLONG = 1; cSET = 2; TYPE P = ExprABC.T OBJECT METHODS bind := Bind; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := ExprAB.EqCheck; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (a, b: Expr.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.a := a; p.b := b; RETURN p; END New; PROCEDURE Bind (p: P) = BEGIN Expr.Bind (p.a); Expr.Bind (p.b); p.type := Type.Base (Expr.TypeOf (p.a)); END Bind; PROCEDURE Check (p: P) = VAR ta, tb, range: Type.T; BEGIN Expr.TypeCheck (p.a); Expr.TypeCheck (p.b); ta := Type.Base (Expr.TypeOf (p.a)); tb := Type.Base (Expr.TypeOf (p.b)); IF (tb = Reel.T) AND (ta = Reel.T) THEN p.class := cREAL; ELSIF (tb = Longreal.T) AND (ta = Longreal.T) THEN p.class := cLONG; ELSIF SetType.Split (ta, range) AND Type.IsEqual (ta, tb) THEN p.class := cSET; ELSE Error.Msg ("illegal operands for \'/\'"); p.class := cREAL; END; END Check; PROCEDURE Compile (p: P): Temp.T = VAR t1, t2, t3: Temp.T; BEGIN t1 := Expr.Compile (p.a); t2 := Expr.Compile (p.b); t3 := Temp.Alloc (p); IF (p.class # cSET) THEN Emit.OpTTT ("@ = @ / @;\n", t3, t1, t2); ELSE SetExpr.CompileDiv (t1, t2, t3, p.a.type); END; Temp.Free (t1); Temp.Free (t2); RETURN t3; END Compile; PROCEDURE Fold (p: P): Expr.T = VAR e1, e2, e3: Expr.T; BEGIN e1 := Expr.ConstValue (p.a); e2 := Expr.ConstValue (p.b); e3 := NIL; IF (e1 = NIL) OR (e2 = NIL) THEN ELSIF RealExpr.Divide (e1, e2, e3) THEN ELSIF LongrealExpr.Divide (e1, e2, e3) THEN ELSIF SetExpr.SymDifference (e1, e2, e3) THEN ELSE Error.Msg ("illegal operands for \'/\'"); END; RETURN e3; END Fold; PROCEDURE FPrinter (p: P; map: Type.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "/ "); Expr.Fingerprint (p.a, map, wr); Expr.Fingerprint (p.b, map, wr); END FPrinter; BEGIN END DivideExpr.