(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: ConcatExpr.m3 *) (* Last modified on Tue Jun 2 08:26:37 PDT 1992 by kalsow *) (* modified on Thu Nov 29 03:30:53 1990 by muller *) MODULE ConcatExpr; IMPORT Expr, ExprRep, Type, Textt, Error; IMPORT Emit, TextExpr, Temp, MBuf, AssignStmt; TYPE P = ExprRep.Tab BRANDED "ConcatExpr.P" OBJECT folded : Expr.T; OVERRIDES typeOf := ExprRep.NoType; check := Check; compile := Compile; evaluate := Fold; fprint := FPrinter; write := ExprRep.NoWriter; isEqual := ExprRep.EqCheckAB; getBounds := ExprRep.NoBounds; isWritable := ExprRep.IsNever; isDesignator := ExprRep.IsNever; isZeroes := ExprRep.IsNever; note_write := ExprRep.NotWritable; genLiteral := ExprRep.NoLiteral; END; PROCEDURE New (a, b: Expr.T): Expr.T = VAR p := NEW (P); BEGIN ExprRep.Init (p); p.a := a; p.b := b; p.folded := NIL; p.type := Textt.T; RETURN p; END New; PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, tb: Type.T; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); ta := Expr.TypeOf (p.a); tb := Expr.TypeOf (p.b); IF NOT Type.IsAssignable (Textt.T, ta) THEN Error.Msg ("illegal left operand for \'&\'"); ELSIF NOT Type.IsAssignable (Textt.T, tb) THEN Error.Msg ("illegal right operand for \'&\'"); ELSE p.a := AssignStmt.CheckRHS (Textt.T, p.a, cs, AssignStmt.Kind.value); p.b := AssignStmt.CheckRHS (Textt.T, p.b, cs, AssignStmt.Kind.value); END; EVAL Fold (p); (* try folding all concatenations *) IF (p.folded # NIL) THEN Expr.TypeCheck (p.folded, cs) END; END Check; PROCEDURE Compile (p: P): Temp.T = VAR t1, t2, t3: Temp.T; BEGIN IF (p.folded # NIL) THEN t3 := Expr.Compile (p.folded); ELSE <* ASSERT p.a # NIL *> t1 := Expr.Compile (p.a); <* ASSERT t1 # NIL *> <* ASSERT p.b # NIL *> t2 := Expr.Compile (p.b); <* ASSERT t2 # NIL *> t3 := Temp.Alloc (p); Emit.OpTTT ("@ = (_ADDRESS) Text__Cat (@, @);\n", t3, t1, t2); Temp.Free (t1); Temp.Free (t2); END; RETURN t3; END Compile; PROCEDURE Fold (p: P): Expr.T = VAR e1, e2, e3: Expr.T; BEGIN IF (p.folded # NIL) THEN RETURN p.folded END; e1 := Expr.ConstValue (p.a); IF (e1 = NIL) THEN RETURN NIL END; p.a := e1; e2 := Expr.ConstValue (p.b); IF (e2 = NIL) THEN RETURN NIL END; p.b := e2; e3 := NIL; IF TextExpr.Cat (e1, e2, e3) THEN p.folded := e3 END; RETURN e3; END Fold; PROCEDURE FPrinter (p: P; map: Type.FPMap; wr: MBuf.T) = BEGIN MBuf.PutText (wr, "& "); Expr.Fingerprint (p.a, map, wr); Expr.Fingerprint (p.b, map, wr); END FPrinter; BEGIN END ConcatExpr.