(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: BitSize.m3 *) (* Last Modified On Tue Jun 30 08:50:32 PDT 1992 By kalsow *) (* Modified On Sat Dec 8 00:54:27 1990 By muller *) MODULE BitSize; IMPORT CallExpr, Expr, Type, Procedure, IntegerExpr, Frame; IMPORT TypeExpr, OpenArrayType, Emit, Error, Card, Temp; VAR Z: CallExpr.MethodList; PROCEDURE Check (<*UNUSED*> proc: Expr.T; VAR args: Expr.List; <*UNUSED*> VAR cs: Expr.CheckState): Type.T = BEGIN CheckArg ("BITSIZE", args); RETURN Card.T; END Check; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = BEGIN RETURN Gen (args[0], 1); END Compile; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = BEGIN RETURN GetSize (args[0], 1); END Fold; PROCEDURE CheckArg (name: TEXT; args: Expr.List) = VAR t: Type.T; BEGIN IF Expr.IsDesignator (args[0]) THEN (* ok *) ELSIF TypeExpr.Split (args[0], t) THEN IF OpenArrayType.Is (t) THEN Error.ID (name, "argument cannot be an open array type"); END; ELSE Error.ID (name, "argument must be a designator or type"); END; END CheckArg; PROCEDURE Gen (e: Expr.T; unit: INTEGER): Temp.T = VAR t: Type.T; x, y: Temp.T; block: INTEGER; BEGIN x := Temp.AllocEmpty (Card.T); IF TypeExpr.Split (e, t) THEN Type.Compile (t); ELSE t := Type.Strip (Expr.TypeOf (e)); IF OpenArrayType.Is (t) THEN y := Expr.Compile (e); Frame.PushBlock (block, 1); Emit.OpF ("register @* _bitsize", t); Emit.OpT (" = & @;\n", y); Emit.OpT ("@ = ", x); FOR i := 0 TO OpenArrayType.OpenDepth (t) - 1 DO Emit.OpI ("_bitsize->size[@] * ", i); END; Emit.OpI ("@;\n", (Type.Size (OpenArrayType.OpenType (t)) + unit - 1) DIV unit); Temp.Free (y); Frame.PopBlock (block); RETURN x; END; END; Emit.OpTI ("@ = @;\n", x, (Type.Size (t) + unit - 1) DIV unit); RETURN x; END Gen; PROCEDURE GetSize (e: Expr.T; unit: INTEGER): Expr.T = VAR t: Type.T; BEGIN IF NOT TypeExpr.Split (e, t) THEN t := Type.Strip (Expr.TypeOf (e)); IF OpenArrayType.Is (t) THEN RETURN NIL END; END; RETURN IntegerExpr.New ((Type.Size (t) + unit - 1) DIV unit); END GetSize; PROCEDURE Initialize () = BEGIN Z := CallExpr.NewMethodList (1, 1, TRUE, FALSE, Card.T, NIL, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever, (* designator *) CallExpr.NotWritable (* noteWriter *)); Procedure.Define ("BITSIZE", Z, TRUE); END Initialize; BEGIN END BitSize.