-- ThreeC4OtherModItemsImpl.ThreeC4
-- Sturgis, June 28, 1986 12:48:41 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 ←
			LockContext[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.