(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: NamedExpr.m3 *) (* Last modified on Tue Sep 22 12:32:34 PDT 1992 by kalsow *) (* modified on Fri Dec 21 01:22:10 1990 by muller *) MODULE NamedExpr; IMPORT Expr, ExprRep, Value, String; IMPORT Type, Variable, VarExpr, ProcExpr, Scanner; IMPORT TypeExpr, Temp, MBuf, Scope, Int, Error; TYPE P = Expr.T BRANDED "Named Expr" OBJECT scope : Scope.T; name : String.T; value : Value.T; inFold : BOOLEAN; inIsZeroes : BOOLEAN; inGetBounds : BOOLEAN; OVERRIDES typeOf := TypeOf; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := EqCheck; getBounds := Bounder; isWritable := IsWritable; isDesignator := IsDesignator; isZeroes := IsZeroes; note_write := NoteWrites; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (name: String.T; value: Value.T): Expr.T = VAR p := NEW (P); BEGIN ExprRep.Init (p); p.scope := Scope.Top (); p.name := name; p.value := value; p.inFold := FALSE; p.inIsZeroes := FALSE; p.inGetBounds := FALSE; RETURN p; END New; PROCEDURE FromValue (value: Value.T): Expr.T = VAR p := NEW (P); BEGIN ExprRep.Init (p); p.scope := NIL; p.name := Value.CName (value); p.value := value; p.inFold := FALSE; p.inIsZeroes := FALSE; p.inGetBounds := FALSE; RETURN p; END FromValue; PROCEDURE Split (e: Expr.T; VAR name: String.T; VAR obj: Value.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(p) => IF (p.value = NIL) THEN Resolve (p) END; name := p.name; obj := p.value; RETURN TRUE; ELSE RETURN FALSE; END; END Split; PROCEDURE SplitName (e: Expr.T; VAR name: String.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(p) => name := p.name; RETURN TRUE; ELSE RETURN FALSE; END; END SplitName; PROCEDURE Resolve (p: P) = VAR save: INTEGER; BEGIN IF (p.value = NIL) THEN p.value := Scope.LookUp (p.scope, p.name, FALSE); IF (p.value = NIL) THEN save := Scanner.offset; Scanner.offset := p.origin; Error.Str (p.name, "undefined"); p.value := VarExpr.Obj (VarExpr.New (Int.T, p.name)); Scanner.offset := save; END; END; END Resolve; PROCEDURE TypeOf (p: P): Type.T = BEGIN IF (p.value = NIL) THEN Resolve (p) END; RETURN Value.TypeOf (p.value); END TypeOf; PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = BEGIN IF (p.value = NIL) THEN Resolve (p) END; Value.TypeCheck (p.value, cs); p.type := Value.TypeOf (p.value); p.value := Value.Base (p.value); END Check; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN IF (a.value = NIL) THEN Resolve (a) END; TYPECASE e OF | NULL => RETURN FALSE; | P(b) => IF (b.value = NIL) THEN Resolve (b) END; RETURN (Value.Base (a.value) = Value.Base (b.value)); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE Compile (p: P): Temp.T = BEGIN IF (p.value = NIL) THEN Resolve (p) END; RETURN Value.Load (p.value); END Compile; PROCEDURE Bounder (p: P; VAR min, max: INTEGER) = BEGIN IF (p.value = NIL) THEN Resolve (p) END; IF (p.inGetBounds) THEN Value.IllegalRecursion (p.value); END; p.inGetBounds := TRUE; CASE Value.ClassOf (p.value) OF | Value.Class.Expr => Expr.GetBounds (Value.ToExpr (p.value), min, max); | Value.Class.Var => Variable.GetBounds (p.value, min, max); ELSE EVAL Type.GetBounds (p.type, min, max); END; p.inGetBounds := FALSE; END Bounder; PROCEDURE Fold (p: P): Expr.T = VAR e: Expr.T; BEGIN IF (p.value = NIL) THEN Resolve (p) END; IF (p.inFold) THEN Value.IllegalRecursion (p.value); RETURN NIL END; p.inFold := TRUE; CASE Value.ClassOf (p.value) OF | Value.Class.Expr => e := Expr.ConstValue (Value.ToExpr (p.value)); | Value.Class.Procedure => e := ProcExpr.New (p.value); | Value.Class.Type => e := TypeExpr.New (Value.ToType (p.value)); ELSE e := NIL; END; p.inFold := FALSE; RETURN e; END Fold; PROCEDURE IsDesignator (p: P): BOOLEAN = BEGIN IF (p.value = NIL) THEN Resolve (p) END; RETURN (Value.ClassOf (p.value) = Value.Class.Var); END IsDesignator; PROCEDURE IsWritable (p: P): BOOLEAN = BEGIN IF (p.value = NIL) THEN Resolve (p) END; RETURN Value.IsWritable (p.value); END IsWritable; PROCEDURE IsZeroes (p: P): BOOLEAN = VAR b: BOOLEAN; BEGIN IF (p.value = NIL) THEN Resolve (p) END; IF (p.inIsZeroes) THEN Value.IllegalRecursion (p.value); RETURN TRUE END; p.inIsZeroes := TRUE; b := (Value.ClassOf (p.value) = Value.Class.Expr) AND Expr.IsZeroes (Value.ToExpr (p.value)); p.inIsZeroes := FALSE; RETURN b; END IsZeroes; PROCEDURE NoteWrites (p: P) = BEGIN IF (p.value = NIL) THEN Resolve (p) END; IF (Value.ClassOf (p.value) = Value.Class.Var) THEN Variable.ScheduleTrace (p.value); END; END NoteWrites; PROCEDURE FPrinter (p: P; map: Type.FPMap; wr: MBuf.T) = BEGIN IF (p.value = NIL) THEN Resolve (p) END; Value.Fingerprint (p.value, map, wr); END FPrinter; BEGIN END NamedExpr.