(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: OpenArrayExpr.m3 *) (* Last Modified On Sat Feb 10 17:47:15 1990 By kalsow *) (* Modified On Fri Jan 19 01:05:58 1990 By muller *) MODULE OpenArrayExpr; IMPORT Expr, ExprRep, Type, Emit, VarExpr, IntegerExpr, EnumExpr; IMPORT NamedType, OpenArray, ArrayType, EnumType, SubscriptExpr; IMPORT DerefExpr, Temp, Wr; TYPE P = Expr.T OBJECT expr : Expr.T; target : Type.T; source : Type.T; METHODS bind := Bind; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := EqCheck; getBounds := ExprRep.NoBounds; isWritable := IsWritable; isDesignator := IsDesignator; isZeroes := ExprRep.IsNever; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (target, source: Type.T; a: Expr.T): Expr.T = VAR p: P; BEGIN target := NamedType.Strip (target); source := NamedType.Strip (source); IF Type.IsEqual (target, source) THEN RETURN a END; p := NEW (P); ExprRep.Init (p); p.target := target; p.source := source; p.expr := a; RETURN p; END New; PROCEDURE Bind (p: P) = BEGIN p.target := Type.Bind (p.target); p.source := Type.Bind (p.source); Expr.Bind (p.expr); p.type := p.target; END Bind; PROCEDURE Check (p: P) = BEGIN Type.Check (p.target); Type.Check (p.source); Expr.TypeCheck (p.expr); END Check; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN Type.IsEqual (a.target, b.target) AND Expr.IsEqual (a.expr, b.expr); ELSE RETURN FALSE; END; END EqCheck; PROCEDURE Compile (p: P): Temp.T = VAR t, ti, te, u, ui, ue: Type.T; i: INTEGER; tArray, tOpen: Temp.T; BEGIN tArray := Expr.Compile (p.expr); tOpen := Temp.AllocEmpty (ArrayType.OpenImpl (p.target), TRUE); Emit.Op ("{\001\n"); (* get the pointer to the original data *) IF (ArrayType.OpenDepth (p.source) > 0) THEN i := Type.Name (ArrayType.OpenImpl (p.source)); Emit.OpIT ("register t@* open = & @;\n", i, tArray); Emit.OpT ("@.elts = open->elts;\n", tOpen); ELSE (* it's originally a fixed array *) Emit.OpT ("@.elts = (char*) ", tOpen); Emit.OpT ("(& @);\n", tArray); END; Temp.Free (tArray); (* build the dope vector *) i := 0; t := p.target; u := p.source; WHILE (ArrayType.Split (t, ti, te)) AND (ti = NIL) DO VAR b: BOOLEAN := ArrayType.Split (u, ui, ue); BEGIN <* ASSERT b *> END; Emit.OpTI ("@.size[@] = ", tOpen, i); IF (ui = NIL) THEN Emit.OpI ("open->size[@];\n", i); ELSE Emit.OpI ("@;\n", Type.Number (ui)); END; t := NamedType.Strip (te); u := NamedType.Strip (ue); INC (i); END; Emit.Op ("\002};\n"); RETURN tOpen; END Compile; PROCEDURE Fold (p: P): Expr.T = BEGIN RETURN Expr.ConstValue (p.expr); END Fold; PROCEDURE IsDesignator (p: P): BOOLEAN = BEGIN RETURN Expr.IsDesignator (p.expr); END IsDesignator; PROCEDURE IsWritable (p: P): BOOLEAN = BEGIN RETURN Expr.IsWritable (p.expr); END IsWritable; PROCEDURE FPrinter (p: P; map: Type.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "OPENARRAY "); Type.Fingerprint (p.target, map, wr); Expr.Fingerprint (p.expr, map, wr); END FPrinter; BEGIN END OpenArrayExpr.