<> <> <> <> <> <> DIRECTORY Alloc, Code, CodeDefs, ComData, IntCodeDefs, P5, P5S, P5U, RTSD, SymbolOps, Symbols, SymLiteralOps, Tree, TreeOps; Selection: PROGRAM IMPORTS MPtr: ComData, CPtr: Code, CodeDefs, P5U, P5, SymbolOps, TreeOps EXPORTS CodeDefs, P5 = BEGIN OPEN IntCodeDefs, CodeDefs; <> SEIndex: TYPE = Symbols.SEIndex; ISEIndex: TYPE = Symbols.ISEIndex; ISENull: ISEIndex = Symbols.ISENull; CSEIndex: TYPE = Symbols.CSEIndex; BTIndex: TYPE = Symbols.BTIndex; BitCount: TYPE = Symbols.BitCount; tb: Tree.Base; -- tree base (local copy) seb: Symbols.Base; -- semantic entry base (local copy) cb: CodeDefs.Base; -- code base (local copy) SelectionNotify: PUBLIC Alloc.Notifier = BEGIN -- called by allocator whenever table area is repacked seb _ base[Symbols.seType]; tb _ base[Tree.treeType]; cb _ base[codeType]; END; CaseStmtExp: PUBLIC PROC [rootNode: Tree.Index, isExp: BOOL] RETURNS [l: Node] = BEGIN -- generate code for CASE statment and expression saveCaseCV: Node = CPtr.caseCV; saveExtracting: BOOL = CPtr.xtracting; cvTemp: Var; cvr: Node; bits: BitCount; cl: CodeList _ P5U.NewCodeList[]; armHead, armTail: CaseList _ NIL; t3: Tree.Link _ tb[rootNode].son[3]; CaseArm: Tree.Scan = { node: Tree.Index _ TreeOps.GetNode[t]; -- t is an item tests: NodeList _ P5.ExpList[tb[node].son[1]].head; t2: Tree.Link _ tb[node].son[2]; body: Node _ IF isExp THEN P5.Exp[t2] ELSE P5.StatementTree[t2]; arm: CaseList _ z.NEW[CaseListRep _ [tests: tests, body: body, rest: NIL]]; IF armTail = NIL THEN armHead _ arm ELSE armTail.rest _ arm; armTail _ arm}; CPtr.xtracting _ FALSE; cvr _ P5.Exp[tb[rootNode].son[1]]; cvTemp _ P5U.CreateTemp[cvr.bits].var; P5U.Declare[cl, cvTemp, cvr]; CPtr.caseCV _ cvTemp; TreeOps.ScanList[tb[rootNode].son[2], CaseArm]; IF t3 # Tree.Null THEN { ec: Node _ IF isExp THEN P5.Exp[t3] ELSE P5.StatementTree[t3]; other: CaseList _ z.NEW[CaseListRep _ [tests: NIL, body: ec, rest: NIL]]; IF armHead = NIL THEN armHead _ other ELSE armTail.rest _ other}; CPtr.caseCV _ saveCaseCV; CPtr.xtracting _ saveExtracting; IF armHead = NIL OR armHead.body = NIL THEN bits _ 0 ELSE bits _ armHead.body.bits; l _ z.NEW[cond NodeRep _ [bits: bits, details: cond[armHead]]]; RETURN END; BindStmtExp: PUBLIC PROC [rootNode: Tree.Index, isExp: BOOL] RETURNS [l: Node] = BEGIN -- discrimination with copying <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <