DIRECTORY CCTypes USING[BinaryTargetTypes, BreakPrintType, CCError, CCErrorCase, CCTypeProcs, CheckConformance, ConformanceCheck, CreateCedarType, GetIndirectType, GetProcDataFromGroundType, GetTypeClass, LR, Operator], CedarCode USING[CodeToDoBinaryOp, CodeToLoadThroughIndirect, ConcatCode, CreateCedarNode, GetDataFromNode, LoadThroughIndirectNode, OperationsBody, ShowNode], CirioTypes USING[BasicTypeInfo, Code, CompilerContext, Mem, Node, Type, TypedCode, TypeClass], CNumericTypes USING [CreateNumericType, GetDescriptorFromCNumericType, NumericDescriptor, NumericDescriptorBody], CPointerTypes USING[PointerNodeInfo], IO, Rope; CPointerTypesImpl: CEDAR PROGRAM IMPORTS CCTypes, CedarCode, CNumericTypes, IO EXPORTS CPointerTypes = BEGIN CC: TYPE = CirioTypes.CompilerContext; Type: TYPE = CirioTypes.Type; TypedCode: TYPE = CirioTypes.TypedCode; Code: TYPE = CirioTypes.Code; Node: TYPE = CirioTypes.Node; Mem: TYPE = CirioTypes.Mem; BasicTypeInfo: TYPE = CirioTypes.BasicTypeInfo; CCE: ERROR[case: CCTypes.CCErrorCase, msg: Rope.ROPE ¬ NIL] ¬ CCTypes.CCError; PointerInfo: TYPE = REF PointerInfoBody; PointerInfoBody: TYPE = RECORD[ target: Type, bti: BasicTypeInfo]; pointerClass: ATOM = $pointer; numberClass: ATOM = $numeric; CreatePointerType: PUBLIC PROC[clientTargetType: Type, cc: CC, bti: BasicTypeInfo] RETURNS[Type] = { pointerInfo: PointerInfo ¬ NEW[PointerInfoBody¬[clientTargetType, bti]]; type: Type ¬ CCTypes.CreateCedarType[pointerClass, PointerTypeCCTypeProcs, IndirectPointerTypeCCTypeProcs, cc, pointerInfo]; RETURN[type]}; IndirectPointerTypeCCTypeProcs: REF CCTypes.CCTypeProcs ¬ NEW[CCTypes.CCTypeProcs ¬[ createIndirectNode: PointerCreateIndirect, getBitSize: PointerBitSize]]; PointerCreateIndirect: PROC [cc: CC, procData: REF ANY, indirectType, targetType: Type, mem: Mem] RETURNS [Node] ~ { pointerInfo: PointerInfo ~ NARROW[procData]; IF pointerInfo.bti=NIL THEN CCE[cirioError, "a pointer Type not connected to the target world is being asked to CreateIndirect"]; RETURN pointerInfo.bti.createIndirectNode[pointerInfo.bti, cc, indirectType, targetType, mem]}; PointerBitSize: PROC[indirectType, targetType: Type, cc: CC, procData: REF ANY] RETURNS[CARD] ~ { pointerInfo: PointerInfo ~ NARROW[procData]; IF pointerInfo.bti=NIL THEN CCE[cirioError, "a pointer Type not connected to the target world is being asked to GetBitSize"]; RETURN pointerInfo.bti.getBitSize[pointerInfo.bti, cc, indirectType, targetType]}; PointerTypeCCTypeProcs: REF CCTypes.CCTypeProcs ¬ NEW[CCTypes.CCTypeProcs ¬[ checkConformance: PointerCCTypesCheckConformance, binaryOperandTypes: PointerCCTypesBinaryOperandTypes, getRTargetType: PointerCCTypesGetRTargetType, operand: PointerCCTypesOperand, coerceToType: PointerCCTypesCoerceToType, unaryOp: PointerCCTypesUnaryOp, binaryOp: PointerCCTypesBinaryOp, printType: PointerCCTypesPrintType]]; PointerCCTypesCheckConformance: PROC[valType, varType: Type, cc: CC, procData: REF ANY] RETURNS[CCTypes.ConformanceCheck] = { valInfo: PointerInfo ¬ NARROW[procData]; varClass: ATOM ¬ CCTypes.GetTypeClass[varType]; SELECT varClass FROM pointerClass => { varInfo: PointerInfo ~ NARROW[CCTypes.GetProcDataFromGroundType[varType, cc]]; RETURN[CCTypes.CheckConformance[ CCTypes.GetIndirectType[valInfo.target], CCTypes.GetIndirectType[varInfo.target], cc]]}; numberClass => { intType: CirioTypes.Type ¬ CNumericTypes.CreateNumericType[ NEW[CNumericTypes.NumericDescriptorBody ¬ [primary: signed, secondary: integer]], cc, NIL]; RETURN[CCTypes.CheckConformance[intType, varType, cc]]}; ENDCASE => RETURN[no]; }; PointerCCTypesBinaryOperandTypes: PROC[op: CCTypes.Operator, left, right: Type, cc: CC, procData: REF ANY] RETURNS[CCTypes.BinaryTargetTypes] = { rightClass: ATOM ¬ CCTypes.GetTypeClass[right]; SELECT rightClass FROM pointerClass => RETURN[[left,right]]; numberClass => { intType: CirioTypes.Type ¬ CNumericTypes.CreateNumericType[ NEW[CNumericTypes.NumericDescriptorBody ¬ [primary: signed, secondary: integer]], cc, NIL]; RETURN[[left, intType]]}; ENDCASE => CCE[operation, "illegal pointer / something binary operation"]; }; PointerCCTypesGetRTargetType: PROC[type: Type, cc: CC, procData: REF ANY] RETURNS[Type] = BEGIN pointerTypeInfo: PointerInfo ¬ NARROW[procData]; RETURN[pointerTypeInfo.target]; END; PointerCCTypesOperand: PROC[op: CCTypes.Operator, lr: CCTypes.LR, tc: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN RETURN[tc]; END; PointerCCTypesCoerceToType: PROC[targetType: Type, tc: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN pointerTypeInfo: PointerInfo ¬ NARROW[procData]; IF pointerTypeInfo.target # targetType THEN CCE[typeConformity] ELSE RETURN[tc] END; PointerCCTypesUnaryOp: PROC[op: CCTypes.Operator, arg: TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN pointerTypeInfo: PointerInfo ¬ NARROW[procData]; SELECT op FROM $uparrow => BEGIN RETURN[[CedarCode.ConcatCode[ arg.code, CedarCode.CodeToLoadThroughIndirect[CCTypes.GetIndirectType[pointerTypeInfo.target]]], pointerTypeInfo.target]]; END ENDCASE => CCE[typeConformity]; END; PointerCCTypesBinaryOp: PROC[op: CCTypes.Operator, left, right: CirioTypes.TypedCode, cc: CC, procData: REF ANY] RETURNS[TypedCode] = BEGIN pointerTypeInfo: PointerInfo ~ NARROW[procData]; SELECT op FROM $minus, $eq, $ne, $lt, $gt, $le, $ge => { RETURN[[CedarCode.ConcatCode[ left.code, CedarCode.ConcatCode[right.code, CedarCode.CodeToDoBinaryOp[op, left.type, right.type]]], CreateBoolType[cc]]] }; $plus => { RETURN[[CedarCode.ConcatCode[ left.code, CedarCode.ConcatCode[right.code, CedarCode.CodeToDoBinaryOp[op, left.type, right.type]]], left.type]]; }; ENDCASE => CCE[unimplemented, IO.PutFR1["the binary op `%g' is not implemented for C pointers", [atom[op]] ]]; END; CreateBoolType: PROC [cc: CC] RETURNS [CirioTypes.Type] ~{RETURN CNumericTypes.CreateNumericType[ NEW[CNumericTypes.NumericDescriptorBody ¬ [primary: signed, secondary: integer]], cc, NIL]}; PointerCCTypesPrintType: PROC [to: IO.STREAM, type: Type, printDepth: INT, printWidth: INT, cc: CC, procData: REF ANY] = { pointerTypeInfo: PointerInfo ¬ NARROW[procData]; to.PutRope["POINTER TO"]; CCTypes.BreakPrintType[to, pointerTypeInfo.target, printDepth, printWidth, cc, " "]; RETURN}; CreatePointerNode: PUBLIC PROC[type: Type, info: CPointerTypes.PointerNodeInfo, cc: CC] RETURNS[Node] = BEGIN RETURN[CedarCode.CreateCedarNode[PointerNodeOps, type, info]]; END; PointerNodeOps: REF CedarCode.OperationsBody ¬ NEW[CedarCode.OperationsBody¬[ binaryOp: PointerNodeBinaryOp, load: PointerNodeLoad, show: PointerNodeShow]]; PointerNodeBinaryOp: PROC[op: CCTypes.Operator, leftType, rightType: Type, leftNode, rightNode: CirioTypes.Node, cc: CC] RETURNS[Node] = { leftData: CPointerTypes.PointerNodeInfo ¬ NARROW[CedarCode.GetDataFromNode[leftNode]]; rightClass: CirioTypes.TypeClass ¬ CCTypes.GetTypeClass[rightType]; SELECT rightClass FROM numberClass => { rightDescriptor: CNumericTypes.NumericDescriptor ¬ CNumericTypes.GetDescriptorFromCNumericType[rightType, cc]; SELECT op FROM $plus => { IF rightDescriptor.primary = signed AND rightDescriptor.secondary = integer THEN { newIndirectNode: CirioTypes.Node ¬ leftData.add[leftNode, rightNode, leftData, cc]; RETURN[newIndirectNode]} ELSE CCE[typeConformity]}; ENDCASE => CCE[typeConformity]; }; pointerClass => { SELECT op FROM $le, $lt, $eq, $ne, $gt, $ge => RETURN[leftData.compare[leftNode, rightNode, op, cc]]; $minus => { IF leftType = rightType THEN RETURN[leftData.subtract[leftNode, rightNode, cc]] ELSE CCE[typeConformity]}; ENDCASE => CCE[typeConformity]}; ENDCASE => CCE[typeConformity]; }; PointerNodeLoad: PROC [indirectType: Type, indirectNode: Node, cc: CC] RETURNS [Node] ~ BEGIN data: CPointerTypes.PointerNodeInfo ¬ NARROW[CedarCode.GetDataFromNode[indirectNode]]; RETURN[CedarCode.LoadThroughIndirectNode[CCTypes.GetIndirectType[data.clientTargetType], data.indirectToClientTarget, cc]] END; PointerNodeShow: PROC[to: IO.STREAM, node: Node, depth: INT, width: INT, cc: CC] = { data: CPointerTypes.PointerNodeInfo ¬ NARROW[CedarCode.GetDataFromNode[node]]; target: Node ¬ CedarCode.LoadThroughIndirectNode[CCTypes.GetIndirectType[data.clientTargetType], data.indirectToClientTarget, cc]; to.PutChar['^]; CedarCode.ShowNode[to, target, depth, width, cc]; RETURN}; END.. ’ CPointerTypesImpl.mesa Copyright Σ 1990, 1992 by Xerox Corporation. All rights reserved. Hopcroft August 18, 1989 6:25:13 pm PDT Last changed by Theimer on September 28, 1989 10:57:04 am PDT Last tweaked by Mike Spreitzer on January 9, 1992 10:20 am PST Willie-s, May 14, 1992 4:59 pm PDT Started by theimer by copying from PointerTypesImpl.mesa at May 1, 1989 4:56:50 pm PDT. Nodes begin here Pointer nodes ΚŽ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ7™BK™'K™=K™>K™"—K˜KšœW™WK˜šΟk ˜ KšœžœΆžœ ˜ΡKšœ žœ˜žKšœ žœN˜^Kšœžœ^˜qKšœžœ˜%Kšžœ˜Kšœ˜—K˜šΟnœžœž˜ Kšžœ$ž˜-Kšžœ˜—Kšœž˜Kšžœžœ˜&Kšœžœ˜Kšœ žœ˜'Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜/šžœžœ&žœžœ˜NK™—Kšœ žœžœ˜(šœžœžœ˜Kšœ ˜ šœ˜K˜——Kšœžœ ˜Kšœ žœ ˜K˜š Ÿœžœžœžœžœ ˜dKšœžœ*˜HK˜|Kšžœ˜—K˜šŸœžœžœ˜TK˜*Kšœ˜—K˜š Ÿœžœžœ žœžœ,žœ ˜tKšœžœ ˜,Kšžœžœžœžœb˜KšžœY˜_—K˜šŸœžœ%žœ žœžœžœžœ˜aKšœžœ ˜,Kšžœžœžœžœ^˜}KšžœL˜R—K˜šŸœžœžœ˜LK˜1K˜5K˜-K˜K˜)K˜K˜!K˜%—K˜š Ÿœžœžœ žœžœžœ˜}Kšœžœ ˜(Kšœ žœ!˜/šžœ ž˜šœ˜Kšœžœ1˜Nšžœ˜ Kšœ(˜(Kšœ(˜(Kšœ˜——šœ˜˜;KšžœN˜QKšœžœ˜ —Kšžœ2˜8—Kšžœžœ˜—Kšœ˜—K˜š Ÿ œžœ.žœ žœžœžœ˜‘Kšœ žœ˜/šžœ ž˜Kšœžœ˜%šœ˜˜;KšžœN˜QKšœžœ˜ —Kšžœ˜—Kšžœžœ<˜J—Kšœ˜—K˜š Ÿœžœžœ žœžœžœ˜YKšž˜Kšœžœ ˜0Kšžœ˜Kšžœ˜—K˜šŸœžœ#žœžœ žœžœžœ ˜€Kšž˜Kšžœ˜ Kšžœ˜—K˜š Ÿœžœ&žœ žœžœžœ ˜qKšž˜Kšœžœ ˜0šžœ%žœ˜,Kšžœ˜—šž˜Kšžœ˜ —Kšžœ˜—K˜š Ÿœžœ+žœ žœžœžœ ˜qKšž˜Kšœžœ ˜0šžœž˜˜ Kšž˜šžœ˜Kšœ`˜`Kšœ˜—Kšž˜—Kšžœžœ˜—Kšžœ˜K˜—š Ÿœžœ>žœ žœžœžœ ˜…Kšž˜Kšœžœ ˜0šžœž˜˜)šžœ˜Kšœ ˜ šœ!˜!KšœM˜M——Kšœ˜—˜ šžœ˜Kšœ ˜ šœ!˜!KšœE˜E——Kšœ˜—KšžœžœžœN˜n—Kšžœ˜—K˜šŸœžœžœžœ˜7šœžœ!˜)KšžœN˜QKšœžœ˜ ——K˜šŸœžœžœžœžœžœžœ žœžœ˜zKšœžœ ˜0K˜KšœT˜TKšžœ˜—K˜šœ™˜Kšœ ™ ™K˜—š Ÿœžœžœ6žœžœ˜gKšž˜Kšžœ8˜>Kšžœ˜K˜—šŸœžœžœ˜MK˜K˜K˜—K˜šŸœžœ\žœžœ ˜ŠKšœ*žœ&˜VK˜Cšžœ ž˜šœ˜K˜ošžœž˜šœ ˜ šžœ"žœ&žœ˜SK˜SKšžœ˜—Kšžœžœ˜—Kšžœžœ˜—Kšœ˜—šœ˜šžœž˜˜Kšžœ0˜6—šœ ˜ šžœž˜Kšžœ,˜2—Kšžœžœ˜—Kšžœžœ˜ ——Kšžœžœ˜—Kšœ˜—K˜šŸœžœ.žœžœ ˜WKšž˜Kšœ&žœ*˜VKšžœt˜zKšžœ˜—K˜šŸœžœžœžœžœ žœžœ˜TKšœ&žœ"˜NK˜‚K˜Kšœ1˜1Kšžœ˜—K˜——Kšžœ˜—…— |*¬