(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: DerefExpr.m3 *) (* Last modified on Tue Jun 30 09:04:54 PDT 1992 by kalsow *) (* modified on Thu Nov 29 06:04:10 1990 by muller *) MODULE DerefExpr; IMPORT Expr, ExprRep, RefType, Error, Type, Emit; IMPORT Temp, Void, NilChkExpr, MBuf, OpenArrayType; TYPE P = ExprRep.Ta BRANDED "DerefExpr.P" OBJECT OVERRIDES typeOf := TypeOf; check := Check; compile := Compile; evaluate := ExprRep.NoValue; fprint := FPrinter; write := Writer; isEqual := ExprRep.EqCheckA; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsAlways; isDesignator := ExprRep.IsAlways; isZeroes := ExprRep.IsNever; note_write := NoteWrites; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (a: Expr.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.a := NilChkExpr.New (a); p.origin := p.a.origin; RETURN p; END New; PROCEDURE SetOffset (e: Expr.T; n: INTEGER) = BEGIN TYPECASE e OF | NULL => (* nothing *) | P(p) => NilChkExpr.SetOffset (p.a, n); ELSE (* nothing *) END; END SetOffset; PROCEDURE TypeOf (p: P): Type.T = VAR ta, target: Type.T; BEGIN ta := Expr.TypeOf (p.a); target := Void.T; EVAL RefType.Split (ta, target); RETURN target; END TypeOf; PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, target: Type.T; BEGIN Expr.TypeCheck (p.a, cs); ta := Type.Base (Expr.TypeOf (p.a)); target := Void.T; IF NOT RefType.Split (ta, target) THEN Error.Msg ("cannot dereference a non-REF value"); ELSIF (target = NIL) THEN Error.Msg ("cannot dereference an open REF type"); ELSIF OpenArrayType.Is (target) THEN NilChkExpr.SetOffset (p.a, 0); (* since the element pointer is always used *) ELSE NilChkExpr.SetOffset (p.a, Type.Size (target)); END; p.type := target; END Check; PROCEDURE Compile (p: P): Temp.T = VAR t1, t2: Temp.T; BEGIN t1 := Expr.Compile (p.a); t2 := Temp.AllocMacro (p, TRUE); Temp.Depend (t2, t1); RETURN t2; END Compile; PROCEDURE Writer (p: P; t1: Temp.T; <*UNUSED*> t2: Temp.T) = BEGIN Emit.OpF ("(*((@*) ", p.type); Emit.OpT (" @))", t1); END Writer; PROCEDURE NoteWrites (p: P) = BEGIN Expr.NoteWrite (p.a); END NoteWrites; PROCEDURE FPrinter (p: P; map: Type.FPMap; wr: MBuf.T) = BEGIN MBuf.PutText (wr, "^ "); Expr.Fingerprint (p.a, map, wr); END FPrinter; BEGIN END DerefExpr.