<<>> <> <> <> <> <> <> <> DIRECTORY CCTypes USING[CCError, CCErrorCase, CCTypeProcs, CreateCedarType, ExtractIdField, GetIndirectType, GetRTargetType, GetScopeIndex, GetTargetTypeOfIndirect, GlobalScopeIndex, HasIdField, IdFieldCase, Load, LoadIdField, PrintType, PrintTypeBracketed, SelectIdField, sia], CedarCode USING[BreakShowNode, Code, CodeToGetNameContext, CodeToSelectField, CodeToSelectNestedBlock, ConcatCode, CreateCedarNode, GetDataFromNode, GetTypeOfNode, OperationsBody, ShowNode], CirioTypes USING[CompilerContext, Node, Type, TypedCode], Frames USING[IndirectFrameTypeData, IndirectFrameData, IndirectGlobalFrameData, IndirectGlobalFrameTypeData, SourcePositionRep, TargetWorld], IO, Rope, StructuredStreams; FramesImpl: CEDAR PROGRAM IMPORTS CCTypes, CedarCode, IO, Rope, StructuredStreams EXPORTS Frames = BEGIN OPEN SS:StructuredStreams; 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; <> ClientIndirectFrameTypeData: TYPE = Frames.IndirectFrameTypeData; PrivateIndirectFrameTypeData: TYPE = REF PrivateIndirectFrameTypeDataBody; PrivateIndirectFrameTypeDataBody: TYPE = RECORD[ scopeIndex: CARD, clientIndirectFrameTypeData: REF ClientIndirectFrameTypeData]; CreateIndirectFrameType: PUBLIC PROC[data: REF ClientIndirectFrameTypeData, cc: CC] RETURNS[Type] = BEGIN privateData: PrivateIndirectFrameTypeData _ NEW[PrivateIndirectFrameTypeDataBody_[ scopeIndex: CCTypes.GetScopeIndex[data.enclosingContext, cc] + 1, clientIndirectFrameTypeData: data]]; RETURN[CCTypes.GetIndirectType[CCTypes.CreateCedarType[$frame, NIL, IndirectFrameCCTypeProcs, cc, privateData]]]; END; IndirectFrameCCTypeProcs: REF CCTypes.CCTypeProcs _ NEW[CCTypes.CCTypeProcs _[ selectIdField: FrameSelectIdField, loadIdField: FrameLoadIdField, getScopeIndex: FrameGetScopeIndex, printType: FramePrintType]]; FrameSelectIdField: PROC[id: Rope.ROPE, fieldIndirectContext: CirioTypes.Type, cc: CC, procData: REF ANY] RETURNS[CirioTypes.TypedCode] = BEGIN privateData: PrivateIndirectFrameTypeData _ NARROW[procData]; frameData: REF ClientIndirectFrameTypeData _ privateData.clientIndirectFrameTypeData; exists: BOOLEAN _ FALSE; -- tentative CodeForNestedBlock: PROC[index: CARD] RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectNestedBlock[0, index, fieldIndirectContext]; type1: Type _ frameData.blocks[index]; tc2: TypedCode _ CCTypes.SelectIdField[id, type1, cc]; code: Code _ CedarCode.ConcatCode[code1, tc2.code]; RETURN[[code, tc2.type]]; END; CodeForArgs: PROC RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectField["&args", fieldIndirectContext]; type1: Type _ frameData.args; tc2: TypedCode _ CCTypes.SelectIdField[id, type1, cc]; code: Code _ CedarCode.ConcatCode[code1, tc2.code]; RETURN[[code, tc2.type]]; END; CodeForResults: PROC RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectField["&results", fieldIndirectContext]; type1: Type _ frameData.results; tc2: TypedCode _ CCTypes.SelectIdField[id, type1, cc]; code: Code _ CedarCode.ConcatCode[code1, tc2.code]; RETURN[[code, tc2.type]]; END; tc: CirioTypes.TypedCode _ FrameCodeForIdField[id, privateData, CodeForNestedBlock, CodeForArgs, CodeForResults, cc]; IF tc.code # NIL THEN { RETURN [[ CedarCode.ConcatCode[CedarCode.CodeToGetNameContext[privateData.scopeIndex], tc.code], tc.type]]; } ELSE { <> IF frameData.enclosingContext # NIL THEN BEGIN type1: Type _ frameData.enclosingContext; tc2: TypedCode _ CCTypes.SelectIdField[id, type1, cc]; RETURN [tc2]; END ELSE CCE[operation, Rope.Concat[id, " undefined"]]; }; END; FrameLoadIdField: PROC[id: Rope.ROPE, fieldIndirectContext: CirioTypes.Type, cc: CC, procData: REF ANY] RETURNS[CirioTypes.TypedCode] = BEGIN privateData: PrivateIndirectFrameTypeData _ NARROW[procData]; frameData: REF ClientIndirectFrameTypeData _ privateData.clientIndirectFrameTypeData; exists: BOOLEAN _ FALSE; -- tentative CodeForNestedBlock: PROC[index: CARD] RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectNestedBlock[0, index, fieldIndirectContext]; type1: Type _ frameData.blocks[index]; tc2: TypedCode _ CCTypes.Load[[code1, type1], cc]; tc3: TypedCode _ CCTypes.ExtractIdField[id, CCTypes.GetTargetTypeOfIndirect[type1], cc]; code: Code _ CedarCode.ConcatCode[tc2.code, tc3.code]; RETURN[[code, tc3.type]]; END; CodeForArgs: PROC RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectField["&args", fieldIndirectContext]; type1: Type _ frameData.args; tc2: TypedCode _ CCTypes.Load[[code1, type1], cc]; tc3: TypedCode _ CCTypes.ExtractIdField[id, CCTypes.GetTargetTypeOfIndirect[type1], cc]; code: Code _ CedarCode.ConcatCode[tc2.code, tc3.code]; RETURN[[code, tc3.type]]; END; CodeForResults: PROC RETURNS[CirioTypes.TypedCode] = BEGIN code1: Code _ CedarCode.CodeToSelectField["&results", fieldIndirectContext]; type1: Type _ frameData.results; tc2: TypedCode _ CCTypes.Load[[code1, type1], cc]; tc3: TypedCode _ CCTypes.ExtractIdField[id, CCTypes.GetTargetTypeOfIndirect[type1], cc]; code: Code _ CedarCode.ConcatCode[tc2.code, tc3.code]; RETURN[[code, tc3.type]]; END; tc: CirioTypes.TypedCode _ FrameCodeForIdField[id, privateData, CodeForNestedBlock, CodeForArgs, CodeForResults, cc]; IF tc.code # NIL THEN { RETURN [[ CedarCode.ConcatCode[CedarCode.CodeToGetNameContext[privateData.scopeIndex], tc.code], tc.type]]; } ELSE { <> IF frameData.enclosingContext # NIL THEN BEGIN type1: Type _ frameData.enclosingContext; tc2: TypedCode _ CCTypes.LoadIdField[id, type1, cc]; RETURN [tc2]; END ELSE CCE[operation, Rope.Concat[id, " undefined"]]; }; END; FrameCodeForIdField: PROC[id: Rope.ROPE, privateData: PrivateIndirectFrameTypeData, codeForNestedBlock: PROC[index: CARD] RETURNS[CirioTypes.TypedCode], codeForArgs: PROC RETURNS[CirioTypes.TypedCode], codeForResults: PROC RETURNS[CirioTypes.TypedCode], cc: CC] RETURNS[CirioTypes.TypedCode] = BEGIN frameData: REF ClientIndirectFrameTypeData _ privateData.clientIndirectFrameTypeData; FOR I: INT DECREASING IN [0..frameData.nBlocks) DO idField: CCTypes.IdFieldCase _ CCTypes.HasIdField[id, CCTypes.GetRTargetType[frameData.blocks[I], cc], cc]; IF idField = possible THEN CCE[cirioError]; -- these should be pure record/fieldList types. IF idField = yes THEN RETURN[codeForNestedBlock[I]]; ENDLOOP; <> BEGIN argsHasId: CCTypes.IdFieldCase _ CCTypes.HasIdField[id, CCTypes.GetRTargetType[frameData.args, cc], cc]; IF argsHasId = possible THEN CCE[cirioError]; -- this should be a pure record/fieldList type. IF argsHasId = yes THEN RETURN[codeForArgs[]]; END; <> BEGIN resultsHasId: CCTypes.IdFieldCase _ CCTypes.HasIdField[id, CCTypes.GetRTargetType[frameData.results, cc], cc]; IF resultsHasId = possible THEN CCE[cirioError]; -- this should be a pure record/fieldList type. IF resultsHasId = yes THEN RETURN[codeForResults[]]; END; RETURN[[NIL, NIL]]; END; FrameGetScopeIndex: PROC [type: Type, cc: CC, procData: REF ANY] RETURNS [CARD] = BEGIN privateData: PrivateIndirectFrameTypeData _ NARROW[procData]; RETURN [privateData.scopeIndex]; END; FramePrintType: PROC [to: IO.STREAM, type: Type, printDepth: INT, printWidth: INT, cc: CC, procData: REF ANY] = { privateData: PrivateIndirectFrameTypeData _ NARROW[procData]; frameData: REF ClientIndirectFrameTypeData _ privateData.clientIndirectFrameTypeData; SS.Bp[to, always, 0]; SS.Bp[to, always, 0]; CCTypes.PrintType[to, frameData.args, printDepth-1, printWidth, cc]; SS.Bp[to, always, 0]; CCTypes.PrintType[to, frameData.results, printDepth-1, printWidth, cc]; FOR I: INT IN [0..frameData.nBlocks) DO SS.Bp[to, always, CCTypes.sia]; CCTypes.PrintTypeBracketed[to, frameData.blocks[I], printDepth-1, printWidth, cc]; ENDLOOP; IF printDepth>3 THEN { SS.Bp[to, always, 0]; CCTypes.PrintType[to, frameData.enclosingContext, printDepth-1, printWidth, cc]}; RETURN}; ClientIndirectGlobalFrameTypeData: TYPE = Frames.IndirectGlobalFrameTypeData; PrivateIndirectGlobalFrameTypeData: TYPE = REF PrivateIndirectGlobalFrameTypeDataBody; PrivateIndirectGlobalFrameTypeDataBody: TYPE = RECORD[ scopeIndex: CARD, clientIndirectGlobalFrameTypeData: REF ClientIndirectGlobalFrameTypeData]; CreateIndirectGlobalFrameType: PUBLIC PROC[data: REF ClientIndirectGlobalFrameTypeData, cc: CC] RETURNS[Type] = BEGIN <> privateData: PrivateIndirectGlobalFrameTypeData _ NEW[PrivateIndirectGlobalFrameTypeDataBody_[ scopeIndex:CCTypes.GlobalScopeIndex, clientIndirectGlobalFrameTypeData: data]]; RETURN[CCTypes.GetIndirectType[CCTypes.CreateCedarType[$globalFrame, NIL, IndirectGlobalFrameCCTypeProcs, cc, privateData]]]; END; IndirectGlobalFrameCCTypeProcs: REF CCTypes.CCTypeProcs _ NEW[CCTypes.CCTypeProcs _[ selectIdField: GlobalFrameSelectIdField, loadIdField: GlobalFrameLoadIdField, getScopeIndex: GlobalFrameGetScopeIndex, printType: GlobalFramePrintType]]; GlobalFrameSelectIdField: PROC[id: Rope.ROPE, fieldIndirectContext: CirioTypes.Type, cc: CC, procData: REF ANY] RETURNS[CirioTypes.TypedCode] = BEGIN privateData: PrivateIndirectGlobalFrameTypeData _ NARROW[procData]; globalFrameData: REF ClientIndirectGlobalFrameTypeData _ privateData.clientIndirectGlobalFrameTypeData; exists: BOOLEAN _ FALSE; -- tentative idFieldCase: CCTypes.IdFieldCase _ CCTypes.HasIdField[id, CCTypes.GetRTargetType[globalFrameData.globalVars, cc], cc]; IF idFieldCase = possible THEN CCE[cirioError]; -- this should be pure record/fieldList type. IF idFieldCase = yes THEN BEGIN code1: Code _ CedarCode.CodeToSelectField["&globalVars", fieldIndirectContext]; type1: Type _ globalFrameData.globalVars; tc2: TypedCode _ CCTypes.SelectIdField[id, type1, cc]; code: Code _ CedarCode.ConcatCode[code1, tc2.code]; RETURN[[ CedarCode.ConcatCode[CedarCode.CodeToGetNameContext[privateData.scopeIndex], code], tc2.type]]; END; <> CCE[operation, Rope.Concat[id, " undefined"]]; END; GlobalFrameLoadIdField: PROC[id: Rope.ROPE, fieldIndirectContext: CirioTypes.Type, cc: CC, procData: REF ANY] RETURNS[CirioTypes.TypedCode] = BEGIN privateData: PrivateIndirectGlobalFrameTypeData _ NARROW[procData]; globalFrameData: REF ClientIndirectGlobalFrameTypeData _ privateData.clientIndirectGlobalFrameTypeData; exists: BOOLEAN _ FALSE; -- tentative idFieldCase: CCTypes.IdFieldCase _ CCTypes.HasIdField[id, CCTypes.GetRTargetType[globalFrameData.globalVars, cc], cc]; IF idFieldCase = possible THEN CCE[cirioError]; -- this should be pure record/fieldList type. IF idFieldCase = yes THEN BEGIN code1: Code _ CedarCode.CodeToSelectField["&globalVars", fieldIndirectContext]; type1: Type _ globalFrameData.globalVars; tc2: TypedCode _ CCTypes.Load[[code1, type1], cc]; tc3: TypedCode _ CCTypes.ExtractIdField[id, CCTypes.GetTargetTypeOfIndirect[type1], cc]; code: Code _ CedarCode.ConcatCode[tc2.code, tc3.code]; RETURN[[ CedarCode.ConcatCode[CedarCode.CodeToGetNameContext[privateData.scopeIndex], code], tc3.type]]; END; <> CCE[operation, Rope.Concat[id, " undefined"]]; END; GlobalFrameGetScopeIndex: PROC [type: Type, cc: CC, procData: REF ANY] RETURNS [CARD] = BEGIN privateData: PrivateIndirectGlobalFrameTypeData _ NARROW[procData]; RETURN [privateData.scopeIndex]; END; GlobalFramePrintType: PROC [to: IO.STREAM, type: Type, printDepth: INT, printWidth: INT, cc: CC, procData: REF ANY] = { privateData: PrivateIndirectGlobalFrameTypeData _ NARROW[procData]; frameData: REF ClientIndirectGlobalFrameTypeData _ privateData.clientIndirectGlobalFrameTypeData; SS.Bp[to, always, 0]; CCTypes.PrintType[to, frameData.globalVars, printDepth, printWidth, cc]; RETURN}; <> <<>> IndirectFrameData: TYPE = Frames.IndirectFrameData; CreateIndirectFrameNode: PUBLIC PROC[data: REF IndirectFrameData, type: Type, cc: CC] RETURNS[Node] = BEGIN RETURN[CedarCode.CreateCedarNode[FrameOps, type, data]]; END; FrameOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ advanceNameScope: FrameAdvanceNameScope, getCurrentType: FrameGetCurrentType, extractField: FrameExtractField, selectField: FrameSelectField, selectNestedBlock: FrameSelectNestedBlock, show: FrameShow ]]; FrameAdvanceNameScope: PUBLIC PROC[node: Node, cc: CC] RETURNS[Node] = BEGIN frameData: REF IndirectFrameData _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[frameData.enclosingContext]; END; FrameGetCurrentType: PROC[node: Node, cc: CC] RETURNS[Type] = BEGIN RETURN[CedarCode.GetTypeOfNode[node]]; END; FrameExtractField: PROC[id: Rope.ROPE, type: Type, node: Node, cc: CC] RETURNS[Node] = BEGIN frameData: REF IndirectFrameData _ NARROW[CedarCode.GetDataFromNode[node]]; SELECT TRUE FROM Rope.Equal[id, "&descriptor"] => RETURN[frameData.descriptor]; Rope.Equal[id, "&sourcePosition"] => RETURN[frameData.getSourcePosition[frameData.procData, cc]]; Rope.Equal[id, "&procedure"] => RETURN[frameData.procedure]; Rope.Equal[id, "&caller"] => RETURN[frameData.getCallingNode[frameData.procData, cc]]; Rope.Equal[id, "&enclosingContext"] => RETURN[frameData.enclosingContext]; ENDCASE => CCE[cirioError]; -- shouldn't happen END; FrameSelectField: PROC[id: Rope.ROPE, indirectType: Type, indirectNode: Node, cc: CC] RETURNS[Node] = BEGIN frameData: REF IndirectFrameData _ NARROW[CedarCode.GetDataFromNode[indirectNode]]; SELECT TRUE FROM Rope.Equal[id, "&args"] => RETURN[frameData.args]; Rope.Equal[id, "&results"] => RETURN[frameData.results]; ENDCASE => CCE[cirioError]; -- shouldn't happen END; FrameSelectNestedBlock: PROC[set: INT, depth: INT, indirectType: Type, indirectNode: Node, cc: CC] RETURNS[Node] = <> <> BEGIN frameData: REF IndirectFrameData _ NARROW[CedarCode.GetDataFromNode[indirectNode]]; RETURN[frameData.blocks[depth]]; END; FrameShow: PROC[to: IO.STREAM, node: Node, depth: INT, width: INT, cc: CC] = { frameData: REF IndirectFrameData _ NARROW[CedarCode.GetDataFromNode[node]]; CedarCode.ShowNode[to, frameData.descriptor, depth-1, width, cc]; SS.Bp[to, always, 0]; CedarCode.ShowNode[to, frameData.procedure, depth-1, width, cc]; SS.Bp[to, always, 0]; to.PutRope["Arguments:"]; CedarCode.BreakShowNode[to, frameData.args, depth-1, width, cc, " "]; SS.Bp[to, always, 0]; to.PutRope["Results:"]; CedarCode.BreakShowNode[to, frameData.results, depth-1, width, cc, " "]; SS.Bp[to, always, 0]; to.PutRope["Variables:"]; FOR i: CARDINAL IN [0..frameData.nBlocks) DO CedarCode.BreakShowNode[to, frameData.blocks[i], depth-1, width, cc, " "]; ENDLOOP; SS.Bp[to, always, 0]; IF depth>3 THEN { to.PutRope["Global Frame:"]; CedarCode.BreakShowNode[to, frameData.enclosingContext, depth-1, width, cc, " "]} ELSE to.PutRope["Global Frame omitted"]; RETURN}; IndirectGlobalFrameData: TYPE = Frames.IndirectGlobalFrameData; CreateIndirectGlobalFrameNode: PUBLIC PROC[data: REF IndirectGlobalFrameData, type: Type, cc: CC] RETURNS[Node] = BEGIN RETURN[CedarCode.CreateCedarNode[GlobalFrameOps, type, data]]; END; GlobalFrameOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ extractField: GlobalFrameExtractField, selectField: GlobalFrameSelectField, show: GlobalFrameShow]]; GlobalFrameExtractField: PROC[id: Rope.ROPE, type: Type, node: Node, cc: CC] RETURNS[Node] = BEGIN globalFrameData: REF IndirectGlobalFrameData _ NARROW[CedarCode.GetDataFromNode[node]]; SELECT TRUE FROM Rope.Equal[id, "&descriptor"] => RETURN[globalFrameData.descriptor]; ENDCASE => CCE[cirioError]; -- shouldn't happen END; GlobalFrameSelectField: PROC[id: Rope.ROPE, indirectType: Type, indirectNode: Node, cc: CC] RETURNS[Node] = BEGIN globalFrameData: REF IndirectGlobalFrameData _ NARROW[CedarCode.GetDataFromNode[indirectNode]]; SELECT TRUE FROM Rope.Equal[id, "&globalVars"] => RETURN[globalFrameData.globalVars]; ENDCASE => CCE[cirioError]; -- shouldn't happen END; GlobalFrameShow: PROC[to: IO.STREAM, node: Node, depth: INT, width: INT, cc: CC] = { frameData: REF IndirectGlobalFrameData _ NARROW[CedarCode.GetDataFromNode[node]]; SS.Bp[to, always, 0]; CedarCode.ShowNode[to, frameData.descriptor, depth, width, cc]; SS.Bp[to, always, 0]; CedarCode.ShowNode[to, frameData.globalVars, depth, width, cc]; SS.Bp[to, always, 0]; RETURN}; <> CreateSourcePositionNode: PUBLIC PROC[name: Rope.ROPE, index: INT, cc: CC] RETURNS[Node] = BEGIN spData: REF Frames.SourcePositionRep _ NEW[Frames.SourcePositionRep _ [name, index]]; type: Type _ CCTypes.CreateCedarType[$sourcePosition, NIL, NIL, cc]; node: Node _ CedarCode.CreateCedarNode[SPOps, type, spData]; RETURN[node]; END; SPOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ getNodeRepresentation: SPGetRepresention]]; SPGetRepresention: PROC[node: Node, cc: CC] RETURNS[REF ANY] = BEGIN spData: REF Frames.SourcePositionRep _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[spData]; END; <> CreateTargetWorldNode: PUBLIC PROC[tw: Frames.TargetWorld, cc: CC] RETURNS[Node] = BEGIN type: Type _ CCTypes.CreateCedarType[$targetWorld, NIL, NIL, cc]; node: Node _ CedarCode.CreateCedarNode[TWOps, type, tw]; RETURN[node]; END; TWOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ getNodeRepresentation: TWGetRepresention]]; TWGetRepresention: PROC[node: Node, cc: CC] RETURNS[REF ANY] = BEGIN tw: Frames.TargetWorld _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[tw]; END; <> CPHolder: TYPE = RECORD[cpInfo: REF ANY]; CreateCodePosition: PUBLIC PROC[info: REF ANY, cc: CC] RETURNS[Node] = BEGIN type: Type _ CCTypes.CreateCedarType[$codePosition, NIL, NIL, cc]; node: Node _ CedarCode.CreateCedarNode[CPOps, type, NEW[CPHolder _ [info]]]; RETURN[node]; END; CPOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ getNodeRepresentation: CPGetRepresention]]; CPGetRepresention: PROC[node: Node, cc: CC] RETURNS[REF ANY] = BEGIN cph: REF CPHolder _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[cph.cpInfo]; END; <> BIHolder: TYPE = RECORD[biInfo: REF ANY]; CreateBreakInfo: PUBLIC PROC[info: REF ANY, cc: CC] RETURNS[Node] = BEGIN type: Type _ CCTypes.CreateCedarType[$breakInfo, NIL, NIL, cc]; node: Node _ CedarCode.CreateCedarNode[BIOps, type, NEW[BIHolder _ [info]]]; RETURN[node]; END; BIOps: REF CedarCode.OperationsBody _ NEW[CedarCode.OperationsBody_[ getNodeRepresentation: BIGetRepresention]]; BIGetRepresention: PROC[node: Node, cc: CC] RETURNS[REF ANY] = BEGIN bih: REF BIHolder _ NARROW[CedarCode.GetDataFromNode[node]]; RETURN[bih.biInfo]; END; END..