(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: ConsExpr.m3 *) (* Last modified on Sat Feb 10 17:34:28 1990 by kalsow *) (* modified on Sun Jan 28 01:24:09 1990 by muller *) MODULE ConsExpr; IMPORT Expr, ExprRep, Error, Type, Scope, RecordType, ArrayType, Temp; IMPORT SetType, TypeExpr, SetExpr, RecordExpr, ArrayExpr, Wr; TYPE P = Expr.T OBJECT tipe : Expr.T; args : Expr.List; dots : BOOLEAN; base : Expr.T; METHODS bind := Bind; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := EqCheck; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (type: Expr.T; args: Expr.List; dots: BOOLEAN): Expr.T = VAR p := NEW (P); BEGIN ExprRep.Init (p); p.tipe := type; p.args := args; p.dots := dots; p.base := NIL; RETURN p; END New; PROCEDURE Bind (p: P) = VAR ta, range, index, element: Type.T; fields: Scope.T; BEGIN Expr.Bind (p.tipe); IF TypeExpr.Split (p.tipe, ta) THEN p.type := ta; ELSE p.type := Expr.TypeOf (p.tipe); ta := NIL; END; IF RecordType.Split (ta, fields) THEN IF (p.dots) THEN BadDots () END; p.base := RecordExpr.New (ta, p.args); ELSIF SetType.Split (ta, range) THEN IF (p.dots) THEN BadDots () END; p.base := SetExpr.New (ta, p.args); ELSIF ArrayType.Split (ta, index, element) THEN p.base := ArrayExpr.New (ta, p.args, p.dots); (* Sometime, ArrayExpr.New does not use ta for its type *) Expr.Bind (p.base); p.type := Expr.TypeOf (p.base); ELSE Error.Msg ("bad type expression on constructor"); FOR i := 0 TO LAST (p.args^) DO Expr.Bind (p.args[i]) END; END; Expr.Bind (p.base); END Bind; PROCEDURE BadDots () = BEGIN Error.Msg ("tailing \'..\' in constructor, ignored"); END BadDots; PROCEDURE Check (p: P) = BEGIN Expr.TypeCheck (p.tipe); Expr.TypeCheck (p.base); IF (p.base = NIL) THEN (* bad expr, check the parts anyway... *) FOR i := 0 TO LAST (p.args^) DO Expr.TypeCheck (p.args[i]) END; END; END Check; PROCEDURE EqCheck (a: P; e: Expr.T): BOOLEAN = BEGIN TYPECASE e OF | NULL => RETURN FALSE; | P(b) => RETURN Expr.IsEqual (a.base, b.base); ELSE RETURN Expr.IsEqual (a.base, e); END; END EqCheck; PROCEDURE Compile (p: P): Temp.T = BEGIN RETURN Expr.Compile (p.base); END Compile; PROCEDURE Fold (p: P): Expr.T = BEGIN RETURN Expr.ConstValue (p.base); END Fold; PROCEDURE FPrinter (p: P; map: Type.Map; wr: Wr.T) = BEGIN Wr.PutText (wr, "{} "); Expr.Fingerprint (p.base, map, wr); END FPrinter; BEGIN END ConsExpr.