(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: AddressExpr.m3 *) (* Last modified on Fri Apr 27 07:34:00 1990 by muller *) (* modified on Sat Feb 10 17:29:59 1990 by kalsow *) MODULE AddressExpr; IMPORT Expr, ExprRep, Type, Address, Null, IntegerExpr, Emit, Temp, Wr, Fmt; TYPE P = Expr.T OBJECT value : INTEGER; METHODS bind := ExprRep.NoBind; check := ExprRep.NoCheck; compile := Compile; evaluate := ExprRep.Self; fprint := FPrinter; write := Writer; isEqual := EqCheck; getBounds := Bounder; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := IsZeroes; genLiteral := GenLiteral; END; PROCEDURE New (value: INTEGER): Expr.T = VAR p: P; BEGIN p := NEW (P); ExprRep.Init (p); p.value := value; p.bound := TRUE; p.checked := TRUE; IF (value = 0) THEN p.type := Null.T; ELSE p.type := Address.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.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "@ " & Fmt.Int (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.