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.PutFR["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.. z CPointerTypesImpl.mesa Copyright Σ 1990 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 Started by theimer by copying from PointerTypesImpl.mesa at May 1, 1989 4:56:50 pm PDT. Nodes begin here Pointer nodes Κ‚•NewlineDelimiter ™codešœ™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šœœœM˜m—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˜ošœ˜šœ ˜ šœ"œ&œ˜SKšœS˜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šœ˜—…— z*v