(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: Expr.m3 *) (* Last Modified On Tue Apr 10 11:21:33 1990 By muller *) (* Modified On Sat Feb 10 17:27:35 1990 By kalsow *) MODULE Expr EXPORTS Expr, ExprRep; IMPORT Module, Procedure, Type, Void, Wr, Token; IMPORT String, Error, Scanner, Temp; IMPORT AddExpr, AndExpr, CallExpr, CompareExpr, ConsExpr; IMPORT DerefExpr, DivExpr, DivideExpr, EqualExpr, InExpr, LongrealExpr; IMPORT ModExpr, MultiplyExpr, NamedExpr, NegateExpr, ExprParse; IMPORT NotExpr, OrExpr, PlusExpr, QualifyExpr, RangeExpr, RealExpr; IMPORT SubscriptExpr, SubtractExpr, TextExpr, TypeExpr, ConcatExpr; IMPORT CheckExpr, NarrowExpr, KeywordExpr, EnumExpr, VarExpr, SetExpr; IMPORT RecordExpr, ArrayExpr, IntegerExpr, AddressExpr, ProcExpr; IMPORT OpaqueExpr, OpenArrayExpr, CastExpr; PROCEDURE Initialize () = BEGIN END Initialize; (********************************************************************) PROCEDURE Parse (READONLY fail: Token.Set): T = BEGIN RETURN ExprParse.E0 (fail); END Parse; (********************************************************************) PROCEDURE Init (t: T) = BEGIN t.origin := Scanner.offset; t.type := NIL; t.bound := FALSE; t.inCheck := FALSE; t.checked := FALSE; END Init; PROCEDURE Bind (t: T) = BEGIN IF (t # NIL) AND (NOT t.bound) THEN t.bind (); t.bound := TRUE; IF (t.type = NIL) THEN t.type := Void.T END; END; END Bind; PROCEDURE TypeOf (t: T): Type.T = BEGIN IF (t = NIL) THEN RETURN Void.T END; <* ASSERT t.bound *> RETURN t.type; END TypeOf; (********************************************************************) PROCEDURE ConstValue (t: T): T = BEGIN IF (t = NIL) THEN RETURN NIL END; RETURN t.evaluate (); END ConstValue; PROCEDURE GetBounds (t: T; VAR min, max: INTEGER) = BEGIN IF (t = NIL) THEN min := 0; max := -1; RETURN END; t.getBounds (min, max); END GetBounds; PROCEDURE IsDesignator (t: T): BOOLEAN = BEGIN RETURN (t = NIL) OR t.isDesignator (); END IsDesignator; PROCEDURE IsWritable (t: T): BOOLEAN = BEGIN RETURN (t = NIL) OR t.isWritable () END IsWritable; PROCEDURE IsZeroes (t: T): BOOLEAN = BEGIN RETURN (t = NIL) OR t.isZeroes () END IsZeroes; (********************************************************************) PROCEDURE TypeCheck (t: T) = BEGIN IF (t # NIL) AND (NOT t.checked) THEN <* ASSERT t.bound AND NOT t.inCheck *> t.inCheck := TRUE; t.check (); t.inCheck := FALSE; t.checked := TRUE; END; END TypeCheck; PROCEDURE Fingerprint (t: T; map: Type.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "("); IF (t # NIL) THEN <* ASSERT t.checked *> t.fprint (map, wr); END; Wr.PutText (wr, ")"); END Fingerprint; (********************************************************************) PROCEDURE Compile (t: T): Temp.T = VAR tmp: Temp.T; BEGIN IF (t = NIL) THEN RETURN Temp.FromExpr (NIL) END; <* ASSERT t.checked *> IF NOT Temp.LookUp (t, FALSE, tmp) THEN tmp := t.compile () END; RETURN tmp; END Compile; PROCEDURE CompileLValue (t: T): Temp.T = VAR tmp: Temp.T; BEGIN IF (t = NIL) THEN RETURN Temp.FromExpr (NIL) END; <* ASSERT t.checked *> IF NOT Temp.LookUp (t, TRUE, tmp) THEN tmp := t.compile (); <* ASSERT Temp.IsLValue (tmp) *> END; RETURN tmp; END CompileLValue; PROCEDURE Write (t: T; t1, t2: Temp.T) = BEGIN t.write (t1, t2); END Write; PROCEDURE IsEqual (a, b: T): BOOLEAN = BEGIN IF (a = b) THEN RETURN TRUE END; IF (a = NIL) OR (b = NIL) THEN RETURN FALSE END; RETURN a.isEqual (b); END IsEqual; PROCEDURE GenLiteral (t: T) = BEGIN IF (t = NIL) THEN RETURN END; <* ASSERT t.checked *> t.genLiteral (); END GenLiteral; (******************** default methods ************************************) PROCEDURE NoBind (t: T) = BEGIN <* ASSERT t.type # NIL *> END NoBind; PROCEDURE NoCheck (<*UNUSED*> t: T) = BEGIN END NoCheck; PROCEDURE NoValue (<*UNUSED*> t: T): T = BEGIN RETURN NIL; END NoValue; PROCEDURE Self (t: T): T = BEGIN RETURN t; END Self; PROCEDURE NoBounds (t: T; VAR min, max: INTEGER) = BEGIN Type.GetBounds (t.type, min, max); END NoBounds; PROCEDURE IsNever (<*UNUSED*> t: T): BOOLEAN = BEGIN RETURN FALSE; END IsNever; PROCEDURE IsAlways (<*UNUSED*> t: T): BOOLEAN = BEGIN RETURN TRUE; END IsAlways; PROCEDURE NeverEq (<*UNUSED*> a, b: T): BOOLEAN = BEGIN RETURN FALSE; END NeverEq; PROCEDURE NoWriter (<*UNUSED*> t: T; <*UNUSED*> t1, t2: Temp.T) = BEGIN <* ASSERT FALSE *> END NoWriter; PROCEDURE NoLiteral (<*UNUSED*> t: T) = BEGIN <* ASSERT FALSE *> END NoLiteral; BEGIN END Expr.