-- ThreeC4OtherModItemsImpl.ThreeC4
-- Sturgis, May 6, 1986 4:26:36 pm PDT

Include[ThreeC4BaseDecl, ThreeC4RecFcnDecl, ThreeC4BasicAbTypes, ThreeC4OtherModItemsAbGram];


ThreeC4OtherModItemsImpl: Module =
Begin

for BaseItems.baseTypes: AbstractProduction[IdList]
 let CollectModuleValueTypes[tree, file, context] ←
   RecordMultipleBaseTypes[IdList, file, context]
  
 let CollectModuleFunctionTypes[tree, file, context] ← FakeCopyContextForConditional[context] 
 let DefFileCode[tree, context, usage] ←
   <BaseDeclCode[IdList, context], FakeUsageCopy[usage]>

 let ImplFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;

for BaseItems.enumBaseType: AbstractProduction[Identifier, IdList]
 let CollectModuleValueTypes[tree, file, context] ←
   RecordEnumeratedBaseType[context, name, file, names, codeName]
  where name ← BuildName[Identifier]
  where names ← FormNameList[IdList]
  where codeName ← RopeCode1["%g", IdFill[Identifier]]
  
 let CollectModuleFunctionTypes[tree, file, context] ← FakeCopyContextForConditional[context]

 let DefFileCode[tree, context, usage] ← <code, FakeUsageCopy[usage]>
  where code ← RopeCode2["%g: TYPE = {%g};\N",
   IdFill[Identifier],
   CodeFill[BuildNameSeqArgCode[FormNameList[IdList]]]]
   
 let ImplFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;

for BaseItems.baseFcn: AbstractProduction[Identifier, ModIdList.args, ModIdList.results, DamageShareAssertions]
 let CollectModuleValueTypes[tree, file, context] ← FakeCopyContextForConditional[context]

 let CollectModuleFunctionTypes[tree, file, context] ←
   RecordBaseFcnDef[context, BuildName[Identifier],
         file, argTypes, resultTypes, fcnDefGraph]
  where argTypes ← FormTypeListEarly[ModIdList.args, context]
  where resultTypes ← FormTypeListEarly[ModIdList.results, context]
   where fcnDefGraph ←
    FormRecordOfDamageShareAssertion[DamageShareAssertions, fcnDefGraph1]
   where fcnDefGraph1 ← BuildFcnBaseGraph[argNames, resultNames]
   where argNames ← FormNameList[ModIdList.args]
   where resultNames ← FormNameList[ModIdList.results]

 let DefFileCode[tree, context, usage] ← <code, use>
  where code ← RopeCode3["%g: PROC%g RETURNS[%g];\N\N",
     IdFill[Identifier],
     CodeFill[argsCode],
     CodeFill[resultsCode]]
  where argsCode ← if TestEmptyCode[argsCode1] then BuildEmptyCode[]
        else RopeCode1["[%g]", CodeFill[argsCode1]]
  where <argsCode1, use> ← FormTypesCode[ModIdList.args, context, use1]
  where <resultsCode, use1> ← FormTypesCode[ModIdList.results, context, usage]

 let ImplFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;

for BaseItems.treeRecFcn:
  AbstractProduction[Identifier, ModIdList.args, ModIdList.results, DamageShareAssertions]
 let CollectModuleValueTypes[tree, file, context] ← FakeCopyContextForConditional[context]

 let CollectModuleFunctionTypes[tree, file, context] ←
   RecordRecFcnDef[context, BuildName[Identifier],
       file, argTypes, resultTypes, fcnDefGraph]
  where check ← CheckForEqualTypeLists[
   BuildOneTypeList[GetFirstType[argTypes]],
   BuildOneTypeList[FindType[context, BuildRopeName["Tree"]]]]
  where argTypes ← FormTypeListEarly[ModIdList.args, context]
  where resultTypes ← FormTypeListEarly[ModIdList.results, context]
  where procTypeName ←
   BuildRopeName[ConcatRopes2[RopeFromIdentifierNode[Identifier], "ProcType"]]
   where fcnDefGraph ← PrepareRecFcnDefGraph[fcnDefGraph2]
   where fcnDefGraph2 ←
    FormRecordOfDamageShareAssertion[DamageShareAssertions, fcnDefGraph1]
   where fcnDefGraph1 ← BuildFcnBaseGraph[argNames, resultNames]
   where argNames ← FormNameList[ModIdList.args]
   where resultNames ← FormNameList[ModIdList.results]

 let DefFileCode[tree, context, usage] ← <code, use>
  where code ← RopeCode3["%gProcType: TYPE = PROC[%g] RETURNS[%g];\N\N",
     IdFill[Identifier],
     CodeFill[argCode],
     CodeFill[resultsCode]]
  where <argCode, use> ← FormTypesCode[ModIdList.args, context, use1]
  where <resultsCode, use1> ← FormTypesCode[ModIdList.results, context, usage]

 let ImplFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;


for AbGramItems.abType: AbstractProduction[Identifier, IdList]
 let CollectModuleValueTypes[tree, file, context] ←
   RecordAbstractType[context, name, file, codeName, IdList, nameList]
  where name ← BuildName[Identifier]
  where codeName ← RopeCode1["%gNode", IdFill[Identifier]]
  where nameList ← FormNameList[IdList]
  
 let CollectModuleFunctionTypes[tree, file, context] ← FakeCopyContextForConditional[context]
  
 let DefFileCode[tree, context, usage] ← <code, use1>
  where code ← ConcatCode5[
     header,
     nodeCode,
     nodeBodyCode,
     nodeProcsCode,
     nodeProcsBodyCode]

  where header ← RopeCode1["\N--%g\N\N", IdFill[Identifier]]
  
  where nodeCode ← RopeCode2["%g: TYPE = REF %gBody;\N",
         CodeFill[nameCode], CodeFill[nameCode]]

  where nodeBodyCode ← ConcatCode4[
     RopeCode1["%gBody: TYPE = RECORD[\N", CodeFill[nameCode]],
     RopeCode["\Tposition: INT, length: INT,\N"],
     RopeCode1["\Tprocs: %gProcs,\N", CodeFill[nameCode]],
     RopeCode["\Tdata: REF ANY];\N\N"]]
       
  where nodeProcsCode ← RopeCode2["%gProcs: TYPE = REF %gProcsBody;\N",
          CodeFill[nameCode], CodeFill[nameCode]]
  
  where nodeProcsBodyCode ← ConcatCode3[
    RopeCode1["%gProcsBody: TYPE = RECORD[\N", CodeFill[nameCode]],
    typeCode,
    RopeCode["];\N\N"]]
  
  where <typeCode, use1> ← ProcFieldTypeCode[IdList, context, usage]
  
  where nameCode ← GetTypeCodeName[LookUpType[context, name]]
  where name ← BuildName[Identifier]

 let ImplFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;

for AbGramItems.abProd: AbstractProduction[ModId, ModIdList]
 let CollectModuleValueTypes[tree, file, context] ←
   RecordAbstractProduction[context, name, file, rightSideList, prodContext]
  where name ← FormName[ModId]
  where rightSideList ← FormNameList[ModIdList]
  where prodContext ←
   FormAbstRightSideContext[ModIdList, BuildEmptyContext[]]

 let CollectModuleFunctionTypes[tree, file, context] ← FakeCopyContextForConditional[context]
   
 let DefFileCode[tree, context, usage] ← <code, use>
      
  where code ← ConcatCode5[
     headerCode,
     dataTypeCode,
     procsCode,
     buildCode,
     code1]
  
  where use ← FormTypeUse[ModIdList, use1, context]  
  where headerCode ← RopeCode1["\N-- %g\N\N", CodeFill[prodNameCode]] 
  where dataTypeCode ← ConcatCode2[
     RopeCode2["%gData: TYPE = REF %gDataBody;\N",
         CodeFill[prodNameCode],
         CodeFill[prodNameCode]],
     ConcatCode3[
      RopeCode1["%gDataBody: TYPE = RECORD[\N", CodeFill[prodNameCode]],
      argNameCode,
      RopeCode["];\N\N"]]]
  
  where argNameCode ← BuildArgNameTypeCode[fieldNames, fieldTypes]
  where fieldNames ← FormNameList[ModIdList]
  where fieldTypes ← FormTypeList[ModIdList, context]
  where procsCode ← RopeCode2["%gProcs: %gProcs;\N\N",
         CodeFill[prodNameCode],
         CodeFill[typeNameCode]]     
  where buildCode ← ConcatCode2[
         RopeCode2["Build%gNode: PROC[position: INT, length: INT%g]\N",
          CodeFill[prodNameCode],
          CodeFill[DataBodyFieldTypeCode[ModIdList, context]]],
         RopeCode1["\TRETURNS[%g];\N\N",
          CodeFill[typeNameCode]]]
     
  where typeNameCode ← GetTypeCodeName[LookUpType[context, typeName]]
  where <code1, use1> ←
    FormRecFcnsDeclCode[LookUpAbTypeRecFcnsIdList[context, typeName], prodNameCode, context, usage]
  where typeName ← BuildName[FormFirstId[ModId]]
  where prodNameCode ← RopeCode1["%gProd", NameFill[FormName[ModId]]]

 let ImplFileCode[tree, context, usage] ← <code, use>
    
  where code ← ConcatCode3[
     headerCode,
     procsImplCode,
     buildImplCode]
     
  where use ← FormTypeUse[ModIdList, use1, context]   
  where headerCode ← RopeCode1["\N-- %g\N\N", CodeFill[prodNameCode]]  
  where procsImplCode ← ConcatCode4[
          RopeCode2["%gProcs: PUBLIC %gProcs ←\N",
           CodeFill[prodNameCode], CodeFill[typeNameCode]],
          RopeCode1["\TNEW[%gProcsBody ← [",
           CodeFill[typeNameCode]],
          procsNamesCode,
          RopeCode["]];\N\N"]]  
  where procsNamesCode ←
    FormProcsNamesCode[procNamesIdList, prodNameCode] 
  where procNamesIdList ← LookUpAbTypeRecFcnsIdList[context, typeName]   
  where buildImplCode ← ConcatCode6[
     RopeCode2["Build%gNode: PUBLIC PROC[position: INT, length: INT%g]\N",
      CodeFill[prodNameCode],
      CodeFill[DataBodyFieldTypeCode[ModIdList, context]]],
     RopeCode1["\TRETURNS[%g] =\N",
      CodeFill[typeNameCode]],
     RopeCode["\T\TBEGIN\N"],
     dataRcdCode,
     RopeCode3["\T\TRETURN[NEW[%gBody←[position, length, %gProcs, %g]]];\N",
      CodeFill[typeNameCode], CodeFill[prodNameCode], CodeFill[dataRefCode]],
     RopeCode["\T\TEND;\N\N"]]
  where dataRcdCode ← if TestEmptyCode[nameSeqArgCode]
      then BuildEmptyCode[]
      else ConcatCode3[
       RopeCode1["\T\Tdata: %gData ←\N",
        CodeFill[prodNameCode]],
       RopeCode1["\T\T\TNEW[%gDataBody←[\N",
        CodeFill[prodNameCode]],
       RopeCode1["\T\T\T%g]];\N",
        CodeFill[nameSeqArgCode]]]
  where dataRefCode ← if TestEmptyCode[nameSeqArgCode]
         then RopeCode["NIL"] else RopeCode["data"]
  where nameSeqArgCode ← BuildNameSeqArgCode[FormNameList[ModIdList]]
  where typeNameCode ← GetTypeCodeName[LookUpType[context, typeName]]
  where use1 ← RecordAbstProdUse[use0, prodName, Use.export, context]
  where use0 ← RecordAbstProdUse[usage, prodName, Use.import, context]
  where typeName ← BuildName[FormFirstId[ModId]]
  where prodNameCode ← RopeCode1["%gProd", NameFill[prodName]]
  where prodName ← FormName[ModId];

for AbGramItems.abProdFcnImpl: AbstractProduction[AbProductionFcnImpl]
 let CollectModuleValueTypes[tree, file, context] ← FakeCopyContextForConditional[context]
 let CollectModuleFunctionTypes[tree, file, context] ← FakeCopyContextForConditional[context]
 let DefFileCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>
 let ImplFileCode[tree, context, usage] ← ImplFileCode[AbProductionFcnImpl, context, usage]


End.