-- ThreeC4MiscImpl.ThreeC4
-- Sturgis, May 10, 1986 3:21:40 pm PDT
Include[ThreeC4BaseDecl, ThreeC4RecFcnDecl, ThreeC4BasicAbTypes, ThreeC4MiscAbGram];

ThreeC4MiscImpl: Module =
Begin



for ModId.oneId: AbstractProduction[Identifier]
	let FormName[tree] ← BuildName[Identifier]
	let FormFirstId[tree] ← Identifier
	let FormType[tree, context] ← LookUpType[context, BuildName[Identifier]]
	let FormValueInfo[tree, context] ← LookUpSimpleValue[context, Identifier]
	let FormExpCode[tree, context, usage] ← <code, type, FakeUsageCopy[usage]>
		where code ← RopeCode1["%g", NameFill[name]]
		where check ← Check[FoundType[type]]
		where type ← LookUpRightSideSymbol[context, name]
		where name ← FormName[tree]
	let FormTypeUse[tree, usage, context] ←
			RecordTypeUse[usage, LookUpType[context, BuildName[Identifier]]]
	let FormTypeEarly[tree, context] ← FindType[context, BuildName[Identifier]];
	
for ModId.twoIds: AbstractProduction[Identifier.left, Identifier.right]
	let FormName[tree] ← BuildName2[Identifier.left, Identifier.right]
	let FormFirstId[tree] ← Identifier.left
	let FormType[tree, context] ← LookUpType[context, BuildName[Identifier.left]]
	let FormValueInfo[tree, context] ← LookUpValue2[context, Identifier.left, Identifier.right]
	let FormExpCode[tree, context, usage]  ←
		if FoundType[type1] then
			<RopeCode1["%g", NameFill[name1]], type1, FakeUsageCopy[usage]>
		 else (<code2, type2, use2>
		 	where use2 ← RecordTypeUse[usage, type2] 
		 	where <type2, code2> ←
		 		LookUpEnumTypeVal[context,
		 				BuildName[Identifier.left], BuildName[Identifier.right]])
		where type1 ← LookUpRightSideSymbol[context, name1] 
		where name1 ← FormName[tree]
	let FormTypeUse[tree, usage, context] ←
			RecordTypeUse[usage, LookUpType[context, BuildName[Identifier.left]]]
	let FormTypeEarly[tree, context] ← FindType[context, BuildName[Identifier.left]];
	

for ModIdList.Empty: AbstractProduction[]
	let FormNameList[tree] ← BuildEmptyNameList[]
	let FormTypeList[tree, context] ← BuildEmptyTypeList[]
	let FormAbstRightSideContext[tree, context] ← FakeCopyContextForConditional[context]
	let FormTypeUse[tree, usage, context] ← FakeUsageCopy[usage]
	let ProdDataTypeDefCode[tree, prodNameCode, context] ←
		BuildErrorCode["GetRidOf ProdDataTypeDefCode as it is never used"]
	let DataBodyFieldTypeCode[tree, context] ← BuildEmptyCode[]
	let ProdBuildDataRcdCode[tree, typeNameCode, prodNameCode] ←
		BuildErrorCode["GetRidOf ProdBuildDataRcdCode as it is never used"]
	let FormTypeListEarly[tree, context] ← BuildEmptyTypeList[]
	let FormTypesCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>;

for ModIdList.Many: AbstractProduction[ModIdList, ModId]
	let FormNameList[tree] ← AppendToNameList[FormNameList[ModIdList], FormName[ModId]]
	let FormTypeList[tree, context] ← AppendToTypeList[FormTypeList[ModIdList, context], FormType[ModId, context]] 
	let FormAbstRightSideContext[tree, context] ←
			RecordAbstRightSideSymbol[
				FormAbstRightSideContext[ModIdList, context],
				FormName[ModId],
				BuildName[FormFirstId[ModId]]]
	let FormTypeUse[tree, usage, context] ←
			FormTypeUse[ModId, FormTypeUse[ModIdList, usage, context], context]
	let ProdDataTypeDefCode[tree, prodNameCode, context] ←
		BuildErrorCode["GetRidOf ProdDataTypeDefCode as it is never used"]
	
	let DataBodyFieldTypeCode[tree, context] ←
			RopeCode1[", %g", CodeFill[BuildArgNameTypeCode[names, types]]]
		where names ← FormNameList[tree]
		where types ← FormTypeList[tree, context]
	
	let ProdBuildDataRcdCode[tree, typeNameCode, prodNameCode] ←
		BuildErrorCode["GetRidOf ProdBuildDataRcdCode as it is never used"]
	
	let FormTypeListEarly[tree, context] ←
			AppendToTypeList[
				FormTypeListEarly[ModIdList, context],
				FormTypeEarly[ModId, context]]
	
	let FormTypesCode[tree, context, usage] ← <code, use>
			where code ← ConcatCode2[
								if TestEmptyCode[listCode] then BuildEmptyCode[]
										else RopeCode1["%g, ", CodeFill[listCode]],
								GetTypeCodeName[type]]
			where use ← RecordTypeUse[use1, type]
			where type ← FormType[ModId, context]
			where <listCode, use1> ← FormTypesCode[ModIdList, context, usage]; 



for IdList.Empty: AbstractProduction[]
	let RecordCedarTypesFrom[tree, defFileName, context] ← FakeCopyContextForConditional[context]
	let RecordCedarTypes[tree, context] ← FakeCopyContextForConditional[context]
	let FormTypeListEarly[tree, context] ← BuildEmptyTypeList[]
	let FormNameList[tree] ← BuildEmptyNameList[]
	let CollectValueTypes[tree, context] ← FakeCopyContextForConditional[context]
	let CollectFunctionTypes[tree, context] ← FakeCopyContextForConditional[context]
	let CollectRightSideSymbols[tree, context] ← FakeCopyContextForConditional[context]
	let RecordMultipleBaseTypes[tree, file, context] ← FakeCopyContextForConditional[context]
	let ProcFieldTypeCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>
	let BaseDeclCode[tree, context] ← BuildEmptyCode[]
	let FormProcsNamesCode[tree, prodNameCode] ← BuildEmptyCode[]
	let FormTypesCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>
	let FormRecFcnsDeclCode[tree, prodNameCode, context, usage] ←
			<BuildEmptyCode[], FakeUsageCopy[usage]>
	let FormVarDeclCode[tree, types] ← BuildEmptyCode[]
	let FormLinkCallCode[tree, context, usage] ← <BuildEmptyCode[], FakeUsageCopy[usage]>
	let SyntaxFileCodes[tree, context] ← <BuildEmptyCode[], BuildEmptyCode[]>;

for IdList.nonEmpty: AbstractProduction[Identifier, IdList]
	let RecordCedarTypesFrom[tree, defFileName, context] ← 
			RecordCedarTypesFrom[IdList, defFileName,
				RecordCedarType[context, BuildName[Identifier], defFileName, codeName]
					where codeName ← RopeCode1["%g", IdFill[Identifier]]]
	let RecordCedarTypes[tree, context] ←
			RecordCedarTypes[IdList,
				RecordPreDefinedCedarType[context, BuildName[Identifier], codeName]
					where codeName ← RopeCode1["%g", IdFill[Identifier]]]
	let FormTypeListEarly[tree, context] ←
			PrefixToTypeList[
				FindType[context, BuildName[Identifier]],
				FormTypeListEarly[IdList, context]]
	let FormNameList[tree] ←
			PrefixToNameList[
				BuildName[Identifier],
				FormNameList[IdList]]
	let CollectValueTypes[tree, context] ← CollectValueTypes[fileTree, context2]
		where <context2, fileTree> ← FindOrReadAndParseTree[context1, BuildName[Identifier]]
		where context1 ← CollectValueTypes[IdList, context]
	let CollectFunctionTypes[tree, context] ← CollectFunctionTypes[fileTree, context1]
		where fileTree ← FindParseTree[context1, BuildName[Identifier]]
		where context1 ← CollectFunctionTypes[IdList, context]
	let CollectRightSideSymbols[tree, context]← CollectRightSideSymbols[fileTree, context1]
		where fileTree ← FindParseTree[context1, BuildName[Identifier]]
		where context1 ← CollectRightSideSymbols[IdList, context]
	let RecordMultipleBaseTypes[tree, file, context] ←
			RecordSimpleBaseType[context1, name, file, codeName]
		where name ← BuildName[Identifier]
		where codeName ← RopeCode1["%gNode", IdFill[Identifier]]
		where context1 ← RecordMultipleBaseTypes[IdList, file, context]
	let ProcFieldTypeCode[tree, context, usage] ← <code, use>
		where code ← ConcatCode2[
							RopeCode2["\N\T%g: %gProcType",
									IdFill[Identifier], IdFill[Identifier]],
							tailCode]
		where use ← RecordFcnUse[use1, BuildName[Identifier], Use.ref, context]
		where tailCode ← if TestEmptyCode[idListCode] then BuildEmptyCode[]
								else ConcatCode2[RopeCode[", "], idListCode]
		where <idListCode, use1> ← ProcFieldTypeCode[IdList, context, usage]
	let BaseDeclCode[tree, context] ←
			ConcatCode2[
				ConcatCode2[
					RopeCode2["%g: TYPE = REF %gBody;\N",
							CodeFill[codeName], CodeFill[codeName]],
					RopeCode1["%gBody: TYPE;\N\N", CodeFill[codeName]]],
				BaseDeclCode[IdList, context]]
		where codeName ← GetTypeCodeName[LookUpType[context, BuildName[Identifier]]]
	let FormProcsNamesCode[tree, prodNameCode] ←
			ConcatCode2[
				RopeCode2["%g%g", CodeFill[prodNameCode], IdFill[Identifier]],
				if TestEmptyCode[idListCode] then BuildEmptyCode[]
					else RopeCode1[", %g", CodeFill[idListCode]]]
			where idListCode ← FormProcsNamesCode[IdList, prodNameCode]
	let FormTypesCode[tree, context, usage] ← <code, use>
			where code ← ConcatCode2[
								GetTypeCodeName[type],
								if TestEmptyCode[idListCode] then BuildEmptyCode[]
										else RopeCode1[", %g", CodeFill[idListCode]]]
			where use ← RecordTypeUse[use1, type]
			where type ← LookUpType[context, BuildName[Identifier]]
			where <idListCode, use1> ← FormTypesCode[IdList, context, usage]
	let FormRecFcnsDeclCode[tree, prodNameCode, context, usage] ← <code, use>
			where code ← ConcatCode2[
								RopeCode3["%g%g: %gProcType;\N",
									CodeFill[prodNameCode],
									IdFill[Identifier],
									IdFill[Identifier]],
								idListCode]
			where use ← RecordFcnUse[use1, BuildName[Identifier], Use.ref, context]
			where <idListCode, use1> ←
						FormRecFcnsDeclCode[IdList, prodNameCode, context, usage]
	let FormVarDeclCode[tree, types] ←
			ConcatCode2[
				RopeCode2["%g: %g;\N",
					IdFill[Identifier], CodeFill[GetTypeCodeName[firstType]]],
				FormVarDeclCode[IdList, restTypes]]
		where <firstType, restTypes> ← PartitionFirstType[types]
	let FormLinkCallCode[tree, context, usage] ← <ConcatCode2[oneCode, manyCode], use2>
		where <manyCode, use2> ← FormLinkCallCode[IdList, context, use1]
		where <oneCode, use1> ← FormLinkCallCode[fileTree, context, usage]
		where fileTree ← LookUpParseTree[context, BuildName[Identifier]]
	let SyntaxFileCodes[tree, context] ← 
			ConcatCodePairs2[SyntaxFileCodes[fileTree, context], SyntaxFileCodes[IdList, context]]
		where fileTree ← LookUpParseTree[context, BuildName[Identifier]];
	
	

for RopeList.One: AbstractProduction[Rope]
	let CollectRightSideSymbols[tree, context] ← RecordRopeToken[context, Rope]
	
	let SyntaxFileCodes[tree, context] ← <tkn, BuildEmptyCode[]>
		where tkn ← RopeCode1["\"%g\"", CodeFill[RopeCode[RopeFromRopeNode[Rope]]]]
	
	let SpecialSyntaxTokenFileCode[tree] ← if EqualRopes[";", RopeFromRopeNode[Rope]]
			then RopeCode["SpelledTerminals: semiColon ; ;\N"]
			else BuildEmptyCode[];
	
for RopeList.Many: AbstractProduction[RopeList, Rope]
	let CollectRightSideSymbols[tree, context] ←
		RecordRopeToken[CollectRightSideSymbols[RopeList, context], Rope]
	
	let SyntaxFileCodes[tree, context] ← <tkn, BuildEmptyCode[]>
		where tkn ← ConcatCode3[
			listCode,
			RopeCode[" "],
			RopeCode1["\"%g\"", CodeFill[RopeCode[RopeFromRopeNode[Rope]]]]]
		where <listCode, unused> ← SyntaxFileCodes[RopeList, context] 
	
	let SpecialSyntaxTokenFileCode[tree] ←
		ConcatCode2[
			SpecialSyntaxTokenFileCode[RopeList],
			if EqualRopes[";", RopeFromRopeNode[Rope]]
				then RopeCode["SpelledTerminals: semiColon ; ;\N"]
				else BuildEmptyCode[]]




End.