(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: AddressExpr.m3 *) (* Last modified on Fri Dec 13 08:35:05 PST 1991 by kalsow *) (* modified on Fri Apr 27 07:34:00 1990 by muller *) MODULE AddressExpr; IMPORT Expr, ExprRep, Type, Addr, Null, IntegerExpr, Emit, Temp, MBuf; TYPE P = Expr.T OBJECT value : INTEGER; OVERRIDES typeOf := ExprRep.NoType; check := ExprRep.NoCheck; compile := Compile; evaluate := ExprRep.Self; fprint := FPrinter; write := Writer; isEqual := EqCheck; getBounds := Bounder; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := IsZeroes; note_write := ExprRep.NotWritable; genLiteral := GenLiteral; END; PROCEDURE New (value: INTEGER): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.value := value; p.checked := TRUE; IF (value = 0) THEN p.type := Null.T; ELSE p.type := Addr.T; END; RETURN p; END New; PROCEDURE Split (e: Expr.T; VAR value: INTEGER): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(p) => value := p.value; RETURN TRUE; ELSE RETURN FALSE; END; END Split; PROCEDURE Add (a, b: Expr.T; VAR c: Expr.T): BOOLEAN = VAR i: INTEGER; BEGIN IF NOT IntegerExpr.Split (b, i) THEN RETURN FALSE END; TYPECASE a OF | NULL => RETURN FALSE; | P(p) => c := New (p.value + i); RETURN TRUE; ELSE RETURN FALSE; END; END Add; PROCEDURE Subtract (a, b: Expr.T; VAR c: Expr.T): BOOLEAN = VAR i, j: INTEGER; BEGIN TYPECASE a OF | NULL => RETURN FALSE; | P(p) => i := p.value; ELSE RETURN FALSE; END; IF IntegerExpr.Split (b, j) THEN c := New (i - j); ELSE (* address - address *) TYPECASE b OF | NULL => RETURN FALSE; | P(p) => c := IntegerExpr.New (i - p.value); ELSE RETURN FALSE; END; END; RETURN TRUE; END Subtract; PROCEDURE Compare (a, b: Expr.T; VAR sign: INTEGER): BOOLEAN = VAR x, y: INTEGER; BEGIN IF NOT SplitPair (a, b, x, y) THEN RETURN FALSE END; IF (x < y) THEN sign := -1 ELSIF (x > y) THEN sign := 1 ELSE sign := 0 END; RETURN TRUE; END Compare; PROCEDURE SplitPair (a, b: Expr.T; VAR x, y: INTEGER): BOOLEAN = BEGIN TYPECASE a OF | NULL => RETURN FALSE; | P(p) => x := p.value; ELSE RETURN FALSE; END; TYPECASE b OF | NULL => RETURN FALSE; | P(p) => y := p.value; ELSE RETURN FALSE; END; RETURN TRUE; END SplitPair; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN (a.value = b.value); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE Compile (e: Expr.T): Temp.T = BEGIN RETURN Temp.FromExpr (e); END Compile; PROCEDURE Writer (p: P; <*UNUSED*> t1, t2: Temp.T) = BEGIN IF (p.type = Null.T) THEN Emit.Op ("0") ELSE Emit.OpI ("((char*) @)", p.value); END; END Writer; PROCEDURE Bounder (p: P; VAR min, max: INTEGER) = BEGIN min := p.value; max := p.value; END Bounder; PROCEDURE FPrinter (p: P; <*UNUSED*> map: Type.FPMap; wr: MBuf.T) = BEGIN MBuf.PutText (wr, "@ "); MBuf.PutInt (wr, p.value); END FPrinter; PROCEDURE IsZeroes (p: P): BOOLEAN = BEGIN RETURN p = Null.Nil OR p.value = 0; END IsZeroes; PROCEDURE GenLiteral (p: P) = BEGIN IF (p.value = 0) THEN Emit.Op ("_NIL"); ELSE Emit.OpI ("((_ADDRESS) @)", p.value) END; END GenLiteral; BEGIN END AddressExpr.