(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: OffsetExpr.m3 *) (* Last modified on Tue Jun 30 11:52:37 PDT 1992 by kalsow *) (* modified on Tue Feb 19 01:32:23 1991 by muller *) MODULE OffsetExpr; IMPORT Expr, ExprRep, Type, Emit, NilChkExpr, ObjectType, Temp, MBuf, Target; TYPE P = Expr.T BRANDED "OffsetExpr.T" OBJECT base : Expr.T; offset : Type.T; methods : BOOLEAN; OVERRIDES typeOf := TypeOf; check := Check; compile := Compile; evaluate := ExprRep.NoValue; fprint := FPrinter; write := Writer; isEqual := EqCheck; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; note_write := NoteWrites; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (base: Expr.T; offset: Type.T; methods: BOOLEAN): Expr.T = VAR p := NEW (P); i: INTEGER; BEGIN ExprRep.Init (p); p.base := NilChkExpr.New (base); p.offset := offset; p.methods := methods; IF (methods) THEN NilChkExpr.SetOffset (p.base, 0); ELSE i := ObjectType.FieldSize (offset); IF (i >= 0) THEN NilChkExpr.SetOffset (p.base, i) END; END; RETURN p; END New; PROCEDURE TypeOf (p: P): Type.T = BEGIN RETURN Expr.TypeOf (p.base); END TypeOf; PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = BEGIN Type.Check (p.offset); Expr.TypeCheck (p.base, cs); END Check; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN (a.methods = b.methods) AND Expr.IsEqual (a.base, b.base) AND Type.IsEqual (a.offset, b.offset, NIL); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE CompileMethod (e: Expr.T; VAR obj: Temp.T): Temp.T = VAR t1: Temp.T; p: P := e; BEGIN Type.Compile (p.offset); obj := Expr.Compile (p.base); t1 := Temp.AllocMacro (p, FALSE); Temp.Depend (t1, obj); RETURN t1; END CompileMethod; PROCEDURE Compile (p: P): Temp.T = VAR t1, t2: Temp.T; BEGIN Type.Compile (p.offset); t2 := Expr.Compile (p.base); t1 := Temp.AllocMacro (p, FALSE); Temp.Depend (t1, t2); RETURN t1; END Compile; PROCEDURE Writer (p: P; t1: Temp.T; <*UNUSED*> t2: Temp.T) = VAR x: INTEGER; BEGIN IF (p.methods) THEN Emit.OpF ("((@_methods*)", p.offset); Emit.OpT ("((*(_ADDRESS*)@)+", t1); x := ObjectType.MethodOffset (p.offset); IF (x < 0) THEN Emit.OpF ("@_TC->methodOffset))", p.offset); ELSE Emit.OpI ("@))", x DIV Target.CHARSIZE); END; ELSE Emit.OpF ("((@_fields*)", p.offset); Emit.OpT ("(((_ADDRESS)@)+", t1); x := ObjectType.FieldOffset (p.offset); IF (x < 0) THEN Emit.OpF ("@_TC->dataOffset))", p.offset); ELSE Emit.OpI ("@))", x DIV Target.CHARSIZE); END; END; END Writer; PROCEDURE NoteWrites (p: P) = BEGIN Expr.NoteWrite (p.base); END NoteWrites; PROCEDURE FPrinter (p: P; map: Type.FPMap; wr: MBuf.T) = BEGIN MBuf.PutText (wr, "OFFSET "); IF (p.methods) THEN MBuf.PutText (wr, "METHODS ") END; Expr.Fingerprint (p.base, map, wr); Type.Fingerprint (p.offset, map, wr); END FPrinter; BEGIN END OffsetExpr.