(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: Last.m3 *) (* Last Modified On Tue Mar 20 23:03:48 1990 By muller *) (* Modified On Fri Jul 14 17:04:13 1989 By kalsow *) MODULE Last; IMPORT CallExpr, Expr, Type, Procedure, First, Emit, ArrayType; IMPORT TypeExpr, IntegerExpr, Temp, Int; VAR Z: CallExpr.MethodList; PROCEDURE Bind (<*UNUSED*> proc: Expr.T; args: Expr.List): Type.T = BEGIN RETURN First.DoBind (args); END Bind; PROCEDURE Check (<*UNUSED*> proc: Expr.T; VAR args: Expr.List) = BEGIN First.DoCheck ("LAST", args); END Check; PROCEDURE Compile (<*UNUSED*> proc: Expr.T; args: Expr.List): Temp.T = VAR e: Expr.T; t, index, element: Type.T; min, max: INTEGER; t1, t2: Temp.T; BEGIN e := args[0]; t := Expr.TypeOf (e); t1 := Temp.AllocEmpty (Int.T); IF ArrayType.Split (t, index, element) THEN IF (index = NIL) THEN t2 := Expr.Compile (e); Emit.OpTT ("@ = @.size[0] - 1;\n", t1, t2); Temp.Free (t2); RETURN t1; END; ELSE VAR b: BOOLEAN := TypeExpr.Split (e, index); BEGIN <* ASSERT b *> END; IF ArrayType.Split (index, index, element) THEN END; END; Type.GetBounds (index, min, max); IF (min > max) THEN max := -1 END; Emit.OpTI ("@ = @;\n", t1, max); RETURN t1; END Compile; PROCEDURE Fold (<*UNUSED*> proc: Expr.T; args: Expr.List): Expr.T = VAR t, elem: Type.T; min, max: INTEGER; BEGIN IF TypeExpr.Split (args[0], t) THEN IF ArrayType.Split (t, t, elem) AND (t = NIL) THEN RETURN NIL END; ELSE IF ArrayType.Split (Expr.TypeOf (args[0]), t, elem) THEN IF (t = NIL) THEN RETURN NIL; END; ELSE (* expr is not an array *) RETURN NIL; END; END; Type.GetBounds (t, min, max); RETURN IntegerExpr.New (max); END Fold; PROCEDURE Initialize () = BEGIN Z := CallExpr.NewMethodList (1, 1, TRUE, Bind, Check, Compile, Fold, CallExpr.IsNever, (* writable *) CallExpr.IsNever(* designator *)); Procedure.Define ("LAST", Z); END Initialize; BEGIN END Last.