DIRECTORY CCTypes USING [BreakPrintType, CCError, CCErrorCase, CCTypeProcs, CreateCedarType, SelectIdField, GetProcDataFromType, LR, ExtractIdField, GetIndirectType, CheckConformance, ConformanceCheck, GetProcDataFromGroundType], CirioTypes USING[CompilerContext, Type, TypedCode, Node], CedarCode USING [BreakShowNode, Code, ConcatCode, CreateCedarNode, OperationsBody, GetDataFromNode, GetTypeOfNode, ShowNode, LoadThroughIndirectNode, CodeToCoerce, CodeToLoadThroughIndirect, Operator, CodeToStoreUnpopped, CodeToLoadContentsOfAMNode, CodeToDoApply, StoreThroughIndirectNode], CirioSyntacticOperations USING [ParseTree, CompileForRHS], IO, Lists USING [ListNodeInfo], Rope; ListsImpl: CEDAR PROGRAM IMPORTS CCTypes, CedarCode, CirioSyntacticOperations, IO EXPORTS Lists = BEGIN OPEN CCTypes; CC: TYPE = CirioTypes.CompilerContext; Code: TYPE = CedarCode.Code; Type: TYPE = CirioTypes.Type; TypedCode: TYPE = CirioTypes.TypedCode; Node: TYPE = CirioTypes.Node; CCE: ERROR[case: CCTypes.CCErrorCase, msg: Rope.ROPE _ NIL] _ CCTypes.CCError; Operator: TYPE = CedarCode.Operator; ListTypeInfo: TYPE = REF ListTypeInfoBody; ListTypeInfoBody: TYPE = RECORD [ listStructType: Type, listElementType: Type, getNewList: PROC [listType: Type, data: REF ANY, cc: CC] RETURNS [Node], data: REF ANY]; CreateListType: PUBLIC PROC [listStructType: Type, listElementType: Type, getNewList: PROC [listType: Type, data: REF ANY, cc: CC] RETURNS [Node], procData: REF ANY, cc: CC] RETURNS [Type] = { info: ListTypeInfo _ NEW [ListTypeInfoBody _ [listStructType, listElementType, getNewList, procData]]; type: Type _ CCTypes.CreateCedarType[$list, ListTypeCCTypeProcs, IndirectListTypeCCTypeProcs, cc, info]; RETURN [type]; }; ListTypeCCTypeProcs: REF CCTypes.CCTypeProcs _ NEW[CCTypes.CCTypeProcs _[ checkConformance: ListCCTypesCheckConformance, operand: ListCCTypesOperand, typeOp: ListCCTypesTypeOp, applyOperand: ListCCTypesApplyOperand, apply: ListCCTypesApply, extractIdField: ListCCTypesExtractIdField, printType: ListCCTypesPrintType]]; ListCCTypesCheckConformance: PROC[valType, varType: Type, cc: CC, procData: REF ANY] RETURNS[CCTypes.ConformanceCheck] = BEGIN valInfo: ListTypeInfo _ NARROW[procData]; WITH CCTypes.GetProcDataFromGroundType[varType, cc] SELECT FROM varInfo: ListTypeInfo => RETURN [CCTypes.CheckConformance[valInfo.listStructType, varInfo.listStructType, cc]]; ENDCASE => RETURN[no]; END; ListCCTypesOperand: PROC [op: Operator, lr: CCTypes.LR, tc: TypedCode, cc: CC, procData: REF ANY] RETURNS [TypedCode] = BEGIN SELECT op FROM $dot , $extractId => RETURN[tc]; ENDCASE => CCE[operation]; -- client error, invalid operation END; ListCCTypesTypeOp: PROC[op: Operator, type: Type, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN info: ListTypeInfo _ NARROW[procData]; node: Node _ info.getNewList[type, info.data, cc]; RETURN [[CedarCode.CodeToLoadContentsOfAMNode[node], type]]; END; ListCCTypesApplyOperand: PROC[operatorType: Type, operand: CirioSyntacticOperations.ParseTree, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN info: ListTypeInfo _ NARROW[procData]; RETURN[CirioSyntacticOperations.CompileForRHS[operand, info.listStructType, cc]]; END; ListCCTypesApply: PROC[operator: TypedCode, operand: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN info: ListTypeInfo _ NARROW[procData]; code: Code _ CedarCode.ConcatCode[operator.code, CedarCode.ConcatCode[operand.code, CedarCode.CodeToDoApply[operator.type, operand.type]]]; RETURN [[code, operator.type]]; END; ListCCTypesExtractIdField: PROC[id: Rope.ROPE, fieldContext: Type, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN info: ListTypeInfo _ NARROW[procData]; code: Code _ CedarCode.CodeToCoerce[fieldContext, info.listStructType]; code1: Code _ CedarCode.ConcatCode[code, CedarCode.CodeToLoadThroughIndirect[CCTypes.GetIndirectType[info.listStructType]]]; tc: TypedCode _ CCTypes.ExtractIdField[id, info.listStructType, cc]; code2: Code _ CedarCode.ConcatCode[code1, tc.code]; RETURN [[code2, tc.type]]; END; IndirectListTypeCCTypeProcs: REF CCTypes.CCTypeProcs _ NEW[CCTypes.CCTypeProcs _[ operand: IndirectListCCTypesOperand, store: ListCCTypesStore, selectIdField: ListCCTypesSelectIdField, printType: ListCCTypesPrintType]]; IndirectListCCTypesOperand: PROC[op: Operator, lr: CCTypes.LR, tc: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN SELECT op FROM $selectId, $address => RETURN[tc]; ENDCASE => CCE[operation]; -- client error; invalid operation END; ListCCTypesStore: PROC[value: TypedCode, indirect: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN code: Code _ CedarCode.ConcatCode[ indirect.code, CedarCode.ConcatCode[ value.code, CedarCode.CodeToStoreUnpopped[indirect.type, value.type]]]; RETURN[[code, value.type]]; END; ListCCTypesSelectIdField: PROC[id: Rope.ROPE, fieldIndirectContext: Type, cc: CC, procData: REF ANY] RETURNS[TypedCode] = { info: ListTypeInfo _ NARROW[procData]; code: Code _ CedarCode.CodeToCoerce[fieldIndirectContext, info.listStructType]; tc: TypedCode _ CCTypes.SelectIdField[id, CCTypes.GetIndirectType[info.listStructType], cc]; code1: Code _ CedarCode.ConcatCode[code, tc.code]; RETURN [[code1, tc.type]]; }; ListCCTypesPrintType: PROC [to: IO.STREAM, type: Type, printDepth: INT, printWidth: INT, cc: CC, procData: REF ANY] = { info: ListTypeInfo _ NARROW[procData]; to.PutRope["LIST OF"]; CCTypes.BreakPrintType[to, info.listElementType, printDepth-1, printWidth, cc, " "]; RETURN}; CreateListIndirectNode: PUBLIC PROC [type: Type, info: REF ANY] RETURNS [Node] = { RETURN [CedarCode.CreateCedarNode[ListIndirectOps, type, info]]; }; ListIndirectOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody _[ coerce: ListIndirectCoerce, unaryOp: ListIndirectUnaryOp, store: ListIndirectStore, load: ListIndirectLoad, show: ListIndirectShow, apply: ListApply ]]; ListIndirectCoerce: PROC [sourceType, targetType: Type, node: Node, cc: CC] RETURNS [Node] = BEGIN info: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN [info.getListStruct[targetType, cc, info.data]]; END; ListIndirectUnaryOp: PROC [op: CedarCode.Operator, type: CirioTypes.Type, node: CirioTypes.Node, cc: CC] RETURNS [CirioTypes.Node] = BEGIN indirectNodeData: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[indirectNodeData.getPointer[indirectNodeData.data, cc]]; END; ListIndirectStore: PROC[valType: Type, valNode: Node, indirectType: Type, indirectNode: Node, cc: CC] = BEGIN info: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[indirectNode]]; info.storeList[valNode, cc, info.data]; END; ListIndirectLoad: PROC [indirectType: Type, indirectNode: Node, cc: CC] RETURNS [Node] = { info: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[indirectNode]]; listIndirectType: Type _ CedarCode.GetTypeOfNode[indirectNode]; RETURN [CreateListNode[listIndirectType, DeferedLoadListProcs, info]]; }; ListIndirectShow: PROC [to: IO.STREAM, node: Node, depth: INT, width: INT, cc: CC] = { info: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[node]]; node1: Node _ CreateListNode[CedarCode.GetTypeOfNode[node], DeferedLoadListProcs, info]; to.PutRope["^["]; CedarCode.ShowNode[to, node1, depth, width, cc]; to.PutChar[']]; RETURN}; ListApply: PROC [operatorType: Type, operandType: Type, operator: Node, operand: Node, cc: CC] RETURNS [Node] = BEGIN info: Lists.ListNodeInfo _ NARROW[CedarCode.GetDataFromNode[operator]]; typeInfo: ListTypeInfo _ NARROW[CCTypes.GetProcDataFromType[operatorType]]; structNode: Node _ info.getListStruct[typeInfo.listStructType, cc, info.data]; CedarCode.StoreThroughIndirectNode[operandType, operand, CCTypes.GetIndirectType[typeInfo.listStructType], structNode, cc]; RETURN [CreateListNode[operatorType, DeferedLoadListProcs, info]]; END; DeferedLoadListProcs: REF ListNodeProcs _ NEW[ListNodeProcs _ [coerceToStruct: DeferedLoadCoerceToStruct, extractElement: DeferedLoadListExtractElement, getRepresentation: DeferedLoadGetRepresentation]]; DeferedLoadCoerceToStruct: PROC [listStructType: Type, cc: CC, data: REF ANY] RETURNS [Node] = BEGIN info: Lists.ListNodeInfo _ NARROW[data]; RETURN [info.getListStruct[listStructType, cc, info.data]]; END; DeferedLoadListExtractElement: PROC [index: CARD, listElementType: Type, cc: CC, data: REF ANY] RETURNS [Node] = BEGIN info: Lists.ListNodeInfo _ NARROW[data]; indirectElement: Node _ info.getListElements[index, listElementType, cc, info.data]; indirectElementType: Type; IF indirectElement = NIL THEN RETURN [NIL]; indirectElementType _ CedarCode.GetTypeOfNode[indirectElement]; RETURN [CedarCode.LoadThroughIndirectNode[indirectElementType, indirectElement, cc]]; END; DeferedLoadGetRepresentation: PROC [data: REF ANY] RETURNS [REF ANY] = BEGIN info: Lists.ListNodeInfo _ NARROW[data]; RETURN [info.data]; END; ListData: TYPE = RECORD [ procs: REF ListNodeProcs, data: REF ANY]; ListNodeProcs: TYPE = RECORD [ coerceToStruct: PROC [listStructType: Type, cc: CC, data: REF ANY] RETURNS [Node], extractElement: PROC [index: CARD, listElementType: Type, cc: CC, data: REF ANY] RETURNS [Node], getRepresentation: PROC [data: REF ANY] RETURNS [REF ANY]]; CreateListNode: PROC [listType: Type, procs: REF ListNodeProcs, data: REF ANY] RETURNS [Node] = BEGIN info: REF ListData _ NEW [ListData _ [procs, data]]; RETURN [CedarCode.CreateCedarNode[ListOps, listType, info]]; END; ListOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody _[ coerce: ListCoerce, show: ListShow, getNodeRepresentation: ListGetNodeRepresentation ]]; ListCoerce: PROC [sourceType, targetType: Type, node: Node, cc: CC] RETURNS [Node] = BEGIN info: REF ListData _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN [info.procs.coerceToStruct[targetType, cc, info.data]]; END; ListShow: PROC [to: IO.STREAM, node: Node, depth: INT, width: INT, cc: CC] = { info: REF ListData _ NARROW[CedarCode.GetDataFromNode[node]]; listType: Type _ CedarCode.GetTypeOfNode[node]; listTypeInfo: ListTypeInfo _ NARROW[CCTypes.GetProcDataFromType[listType]]; elementNode: Node; i: INT _ 0; to.PutRope["LIST["]; DO elementNode _ info.procs.extractElement[i, listTypeInfo.listElementType, cc, info.data]; IF elementNode = NIL THEN EXIT ELSE i _ i + 1; IF i>1 THEN to.PutChar[',]; CedarCode.BreakShowNode[to, elementNode, depth-1, width, cc, IF i>1 THEN " " ELSE NIL]; ENDLOOP; to.PutChar[']]; RETURN}; ListGetNodeRepresentation: PROC[node: Node, cc: CC] RETURNS[REF ANY] = BEGIN info: REF ListData _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN [info.procs.getRepresentation[info.data]]; END; END. l ListsImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Theimer, May 17, 1989 3:56:05 pm PDT Changed by Theimer on May 20, 1989 6:42:37 pm PDT Last changed by Theimer on July 25, 1989 0:26:26 am PDT Hopcroft July 26, 1989 10:20:37 am PDT Last tweaked by Mike Spreitzer January 9, 1992 10:33 am PST Type operations. Node operations. Κ μ•NewlineDelimiter ™šœ™J™Kšœ˜—K˜š’œœœœœ œœ˜NKšœœ œ"˜=Kšœ/˜/Kšœœ(˜KK˜Kšœœ˜ K˜š˜KšœX˜XKšœœœ˜Kšœ ˜Kšœœ˜Kš œ=œœœœ˜WKšœ˜—K˜Kšœ˜—J˜š Ÿœœœœœœ˜FKš˜Kšœœ œ"˜=Kšœ+˜1Kšœ˜—K™—Kšœ˜—…—)j5Β