(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: OpaqueExpr.m3 *) (* Last modified on Sat Feb 10 20:07:42 1990 by kalsow *) (* modified on Thu Nov 2 21:05:15 1989 by muller *) MODULE OpaqueExpr; IMPORT Expr, ExprRep, Type, Error, Emit, Temp, Wr; TYPE P = Expr.T OBJECT expr : Expr.T; tipe : Type.T; data : BOOLEAN; METHODS bind := Bind; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := EqCheck; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; genLiteral := ExprRep.NoLiteral; END; PROCEDURE NewDataOffset (e: Expr.T; opaque: Type.T): Expr.T = VAR p: P; BEGIN IF (opaque = NIL) THEN RETURN e END; p := NEW (P); ExprRep.Init (p); p.expr := e; p.tipe := opaque; p.data := TRUE; RETURN p; END NewDataOffset; PROCEDURE NewMethodOffset (e: Expr.T; opaque: Type.T): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.expr := e; p.tipe := opaque; p.data := FALSE; RETURN p; END NewMethodOffset; PROCEDURE Bind (p: P) = BEGIN Expr.Bind (p.expr); p.tipe := Type.Bind (p.tipe); p.type := Expr.TypeOf (p.expr); END Bind; PROCEDURE Check (p: P) = BEGIN Type.Check (p.tipe); Expr.TypeCheck (p.expr); END Check; PROCEDURE Compile (p: P): Temp.T = VAR t1, t2: Temp.T; BEGIN t1 := Expr.Compile (p.expr); t2 := Temp.Alloc (p); IF (p.data) THEN Emit.OpTT ("@ = (char*)@ + ", t2, t1); Emit.OpI ("TC@->datasize;\n", Type.Name (p.tipe)); ELSE Emit.OpTT ("@ = (*(char**)@)", t2, t1); IF (p.tipe # NIL) THEN Emit.OpI (" + TC@->methodsize", Type.Name (p.tipe)); END; Emit.Op (";\n"); END; Temp.Free (t1); RETURN t2; END Compile; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN (a.data = b.data) AND Type.IsEqual (a.tipe, b.tipe) AND Expr.IsEqual (a.expr, b.expr); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE Fold (p: P): Expr.T = BEGIN RETURN Expr.ConstValue (p.expr); END Fold; PROCEDURE FPrinter (p: P; map: Type.Map; wr: Wr.T) = BEGIN IF (p.data) THEN Wr.PutText (wr, "Doffset ") ELSE Wr.PutText (wr, "Moffset ") END; Type.Fingerprint (p.tipe, map, wr); Expr.Fingerprint (p.expr, map, wr); END FPrinter; BEGIN END OpaqueExpr.