DIRECTORY
	ThreeC4BaseDecl1Def,
	ThreeC4RecFcnImplAbGramDef,
	ThreeC4Support,
	ThreeC4BaseDecl2Def,
	ThreeC4BasicAbTypesDef;

ThreeC4RecFcnImplImpl1Impl: CEDAR PROGRAM IMPORTS ThreeC4BaseDecl1Def, ThreeC4RecFcnImplAbGramDef, ThreeC4Support, ThreeC4BaseDecl2Def EXPORTS ThreeC4RecFcnImplAbGramDef= 
BEGIN
OPEN ThreeC4BaseDecl1Def, ThreeC4RecFcnImplAbGramDef, ThreeC4Support, ThreeC4BaseDecl2Def, ThreeC4BasicAbTypesDef;
AbProductionFcnImplProdImplFileCode: PUBLIC PROC[ref: REF ANY, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: UsageNode] =
BEGIN
tree: AbProductionFcnImplNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: AbProductionFcnImplProdData ← NARROW[tree.data];
BEGIN
code: MesaCodeNode;
use1: UsageNode;
localContext: LookupContextNode;
check: BOOLEAN;
newRightSideList: NameListNode;
oldRightSideList: NameListNode;
prodContext: LockedContextNode;
abTypeName: NameNode;
abProdName: NameNode;
abProdName ← treeData.ModId.procs.FormName[treeData.ModId];
abTypeName ← BuildName[treeData.ModId.procs.FormFirstId[treeData.ModId]];
[oldRightSideList, prodContext] ← LookUpAbProduction[context, abProdName];
newRightSideList ← treeData.ModIdList.procs.FormNameList[treeData.ModIdList];
check ← BPrintError[CompareNameLists[oldRightSideList, newRightSideList], "name lists do not match"];
localContext ← PushProductionContext[context, prodContext];
[code, use1] ← treeData.RecFcnImplList.procs.ProdImplFileCode[treeData.RecFcnImplList, localContext, abTypeName, abProdName, usage];
temp1 ← use1;
temp0 ← code;
END;
END
END;

RecFcnImplListoneProdProdImplFileCode: PUBLIC PROC[ref: REF ANY, prodContext: LookupContextNode, abTypeName: NameNode, abProdName: NameNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: UsageNode] =
BEGIN
tree: RecFcnImplListNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecFcnImplListoneProdData ← NARROW[tree.data];
BEGIN
code: MesaCodeNode;
headCode: MesaCodeNode;
bodyCode: MesaCodeNode;
treeDataCode: MesaCodeNode;
check2: BOOLEAN;
temp2: FcnImplGraphNode;
temp3: SlotListNode;
temp4: CallGraphNodeNode;
check1: BOOLEAN;
use: UsageNode;
varDeclCode: MesaCodeNode;
statementCode: MesaCodeNode;
varTypes: TypeListNode;
restNames: NameListNode;
nextTempX: IntegerNode;
use5: UsageNode;
varContext: LookupContextNode;
modifiedArgTypes: TypeListNode;
argType1: TypeNode;
argTypesRest: TypeListNode;
modifiedArgNames: NameListNode;
argName1: NameNode;
argNamesRest: NameListNode;
argNames: NameListNode;
resultNames: NameListNode;
nextTempX1: IntegerNode;
use4: UsageNode;
use3: UsageNode;
use2: UsageNode;
use1: UsageNode;
abType: TypeNode;
rightSideNames: NameListNode;
abProd: LockedContextNode;
argTypes: TypeListNode;
fcnResultTypes: TypeListNode;
check0: BOOLEAN;
check0 ← MarkErrors[];
[argTypes, fcnResultTypes] ← LookUpRecFcnDef[prodContext, BuildName[treeData.Identifier]];
[rightSideNames, abProd] ← LookUpAbProduction[prodContext, abProdName];
abType ← LookUpType[prodContext, abTypeName];
use1 ← RecordAbstProdUse[usage, abProdName, Use.ref, prodContext];
use2 ← RecordAbstProdUse[use1, abProdName, Use.export, prodContext];
use3 ← RecordTypeUse[use2, abType];
use4 ← RecordTypesUse[RecordTypesUse[use3, fcnResultTypes], argTypes];
[resultNames, nextTempX1] ← InventTemps[CountTypes[fcnResultTypes], IntegerFromRope["0"]];
argNames ← treeData.IdList.procs.FormNameList[treeData.IdList];
[argName1, argNamesRest] ← PartitionFirstName[argNames];
modifiedArgNames ← PrefixToNameList[BuildRopeName["ref"], argNamesRest];
[argType1, argTypesRest] ← PartitionFirstType[argTypes];
modifiedArgTypes ← PrefixToTypeList[abType, argTypesRest];
varContext ← RecordVarSeq[prodContext, argNames, modifiedArgTypes];
[varDeclCode, statementCode, varTypes, restNames, nextTempX, use5] ← treeData.RecExpression.procs.CompForVars[treeData.RecExpression, resultNames, nextTempX1, varContext, use4];
use ← RecordDefFileUse[use5, "ThreeC4Support", Use.import];
check1 ← CompareValTypesWithVarTypes[varTypes, fcnResultTypes];
IF AreErrors[] THEN {check2 ← False[];
} ELSE {[temp2, temp3, temp4] ← treeData.RecExpression.procs.FormFcnImplGraph[treeData.RecExpression, prodContext, BuildFcnImplGraph[prodContext, treeData.Identifier, treeData.IdList.procs.FormNameList[treeData.IdList]]];
check2 ← CheckFcnImpl[prodContext, temp2, temp3, temp4];
};
IF TestEmptyNameList[rightSideNames] THEN {treeDataCode ← BuildEmptyCode[];
} ELSE {treeDataCode ← RopeCode1["treeData: %gProdData ← NARROW[tree.data];\N", NameFill[abProdName]];
};
bodyCode ← ConcatCode7[RopeCode2["%g: %g← NARROW[ref];\N", NameFill[argName1], CodeFill[GetTypeCodeName[abType]]], RopeCode["BEGIN\N"], RopeCode2["ENABLE ThreeC4Support.GetSourceInfo => RESUME[%g.position, %g.length];\N", NameFill[argName1], NameFill[argName1]], treeDataCode, varDeclCode, statementCode, RopeCode["END\N"]];
headCode ← RopeCode4["%gProd%g: PUBLIC PROC[%g] RETURNS[%g] =\N", NameFill[abProdName], IdFill[treeData.Identifier], CodeFill[BuildArgNameTypeCode[modifiedArgNames, argTypes]], CodeFill[BuildArgNameTypeCode[resultNames, fcnResultTypes]]];
code ← ConcatCode4[headCode, RopeCode["BEGIN\N"], bodyCode, RopeCode["END;\N\N"]];
temp1 ← use;
temp0 ← code;
END;
END
END;

RecFcnImplListmanyProdProdImplFileCode: PUBLIC PROC[ref: REF ANY, context: LookupContextNode, abTypeName: NameNode, abProdName: NameNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: UsageNode] =
BEGIN
tree: RecFcnImplListNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecFcnImplListmanyProdData ← NARROW[tree.data];
BEGIN
code: MesaCodeNode;
code1: MesaCodeNode;
use1: UsageNode;
code2: MesaCodeNode;
use2: UsageNode;
[code2, use2] ← treeData.RecFcnImplListb.procs.ProdImplFileCode[treeData.RecFcnImplListb, context, abTypeName, abProdName, usage];
[code1, use1] ← treeData.RecFcnImplLista.procs.ProdImplFileCode[treeData.RecFcnImplLista, context, abTypeName, abProdName, use2];
code ← ConcatCode2[code2, code1];
temp1 ← use1;
temp0 ← code;
END;
END
END;

RecExpressionwithWhereListProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionwithWhereListProdData ← NARROW[tree.data];
temp0 ← treeData.RecExpression.procs.CountVals[treeData.RecExpression, context];
END
END;

RecExpressionwithWhereListProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionwithWhereListProdData ← NARROW[tree.data];
BEGIN
statementCode: MesaCodeNode;
declCode: MesaCodeNode;
expVarDeclCode: MesaCodeNode;
expStatementCode: MesaCodeNode;
varTypes: TypeListNode;
restNames: NameListNode;
nextTempX: IntegerNode;
use2: UsageNode;
whereVarDeclCode: MesaCodeNode;
whereStatementCode: MesaCodeNode;
nextTempX1: IntegerNode;
nestedContext: LookupContextNode;
use1: UsageNode;
[whereVarDeclCode, whereStatementCode, nextTempX1, nestedContext, use1] ← treeData.WhereExpSeq.procs.CompWhere[treeData.WhereExpSeq, firstTempX, context, usage];
[expVarDeclCode, expStatementCode, varTypes, restNames, nextTempX, use2] ← treeData.RecExpression.procs.CompForVars[treeData.RecExpression, varNames, nextTempX1, nestedContext, use1];
declCode ← BuildEmptyCode[];
statementCode ← ConcatCode6[RopeCode["BEGIN\N"], expVarDeclCode, whereVarDeclCode, whereStatementCode, expStatementCode, RopeCode["END;\N"]];
temp5 ← use2;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← varTypes;
temp1 ← statementCode;
temp0 ← declCode;
END;
END
END;

RecExpressionwithWhereListProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionwithWhereListProdData ← NARROW[tree.data];
BEGIN
statementCode: MesaCodeNode;
varDeclCode: MesaCodeNode;
firstArgCode: MesaCodeNode;
firstTempName: NameNode;
junk: NameListNode;
use3: UsageNode;
check: BOOLEAN;
expVarDeclCode: MesaCodeNode;
expStatementCode: MesaCodeNode;
varTypes: TypeListNode;
restNames: NameListNode;
nextTempX: IntegerNode;
use2: UsageNode;
whereVarDeclCode: MesaCodeNode;
whereStatementCode: MesaCodeNode;
nextTempX2: IntegerNode;
nestedContext: LookupContextNode;
use1: UsageNode;
argCode: MesaCodeNode;
tempNames: NameListNode;
nextTempX1: IntegerNode;
nTemps: IntegerNode;
nTemps ← treeData.RecExpression.procs.CountVals[treeData.RecExpression, context];
[tempNames, nextTempX1] ← InventTemps[nTemps, firstTempX];
argCode ← BuildNameSeqArgCode[tempNames];
[whereVarDeclCode, whereStatementCode, nextTempX2, nestedContext, use1] ← treeData.WhereExpSeq.procs.CompWhere[treeData.WhereExpSeq, nextTempX1, context, usage];
[expVarDeclCode, expStatementCode, varTypes, restNames, nextTempX, use2] ← treeData.RecExpression.procs.CompForVars[treeData.RecExpression, tempNames, nextTempX2, nestedContext, use1];
check ← BAbort[BPrintError[CompareNameLists[restNames, BuildEmptyNameList[]], "name lists do not match"]];
use3 ← RecordTypesUse[use2, varTypes];
[firstTempName, junk] ← PartitionFirstName[tempNames];
IF EqualTreeCallFlags[treeCallFlag, TreeCallFlag.yes] THEN {firstArgCode ← RopeCode1["%g", NameFill[firstTempName]];
} ELSE {firstArgCode ← BuildEmptyCode[];
};
varDeclCode ← BuildVarDeclCode[tempNames, varTypes];
statementCode ← ConcatCode6[RopeCode["BEGIN\N"], expVarDeclCode, whereVarDeclCode, whereStatementCode, expStatementCode, RopeCode["END;\N"]];
temp6 ← use3;
temp5 ← nextTempX;
temp4 ← varTypes;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressioncondProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncondProdData ← NARROW[tree.data];
temp0 ← treeData.RecExpressionthenClause.procs.CountVals[treeData.RecExpressionthenClause, context];
END
END;

RecExpressioncondProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncondProdData ← NARROW[tree.data];
BEGIN
varDeclCode: MesaCodeNode;
statementCode: MesaCodeNode;
varTypes: TypeListNode;
restNames: NameListNode;
check3: BOOLEAN;
check2: BOOLEAN;
vdc3: MesaCodeNode;
sc3: MesaCodeNode;
vt3: TypeListNode;
rn3: NameListNode;
nextTempX: IntegerNode;
use3: UsageNode;
vdc2: MesaCodeNode;
sc2: MesaCodeNode;
vt2: TypeListNode;
rn2: NameListNode;
ntx2: IntegerNode;
use2: UsageNode;
check1: BOOLEAN;
vdc1: MesaCodeNode;
sc1: MesaCodeNode;
ac1: MesaCodeNode;
junk: MesaCodeNode;
agt1: TypeListNode;
ntx1: IntegerNode;
use1: UsageNode;
[vdc1, sc1, ac1, junk, agt1, ntx1, use1] ← treeData.RecExpressionifClause.procs.CompForArgs[treeData.RecExpressionifClause, TreeCallFlag.no, firstTempX, context, usage];
check1 ← CheckForOneBoolean[agt1];
[vdc2, sc2, vt2, rn2, ntx2, use2] ← treeData.RecExpressionthenClause.procs.CompForVars[treeData.RecExpressionthenClause, varNames, ntx1, context, use1];
[vdc3, sc3, vt3, rn3, nextTempX, use3] ← treeData.RecExpressionelseClause.procs.CompForVars[treeData.RecExpressionelseClause, varNames, ntx2, context, use2];
check2 ← BAbort[BPrintError[CompareNameLists[rn2, rn3], "name lists do not match"]];
check3 ← CheckForEqualTypeLists[vt2, vt3];
restNames ← rn2;
varTypes ← vt2;
statementCode ← ConcatCode2[sc1, RopeCode3["IF %g THEN {%g} ELSE {%g};\N", CodeFill[ac1], CodeFill[sc2], CodeFill[sc3]]];
varDeclCode ← ConcatCode3[vdc1, vdc2, vdc3];
temp5 ← use3;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← varTypes;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressioncondProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncondProdData ← NARROW[tree.data];
BEGIN
varDeclCode: MesaCodeNode;
use: UsageNode;
bTypes: TypeListNode;
statementCode: MesaCodeNode;
argCode: MesaCodeNode;
firstArgCode: MesaCodeNode;
bt: NameListNode;
nextTempX: IntegerNode;
check2: BOOLEAN;
vdc3: MesaCodeNode;
sc3: MesaCodeNode;
ac3: MesaCodeNode;
fac3: MesaCodeNode;
at3: TypeListNode;
ntx3: IntegerNode;
use3: UsageNode;
vdc2: MesaCodeNode;
sc2: MesaCodeNode;
ac2: MesaCodeNode;
fac2: MesaCodeNode;
at2: TypeListNode;
ntx2: IntegerNode;
use2: UsageNode;
check1: BOOLEAN;
vdc1: MesaCodeNode;
sc1: MesaCodeNode;
ac1: MesaCodeNode;
junk: MesaCodeNode;
agt1: TypeListNode;
ntx1: IntegerNode;
use1: UsageNode;
[vdc1, sc1, ac1, junk, agt1, ntx1, use1] ← treeData.RecExpressionifClause.procs.CompForArgs[treeData.RecExpressionifClause, TreeCallFlag.no, firstTempX, context, usage];
check1 ← CheckForOneBoolean[agt1];
[vdc2, sc2, ac2, fac2, at2, ntx2, use2] ← treeData.RecExpressionthenClause.procs.CompForArgs[treeData.RecExpressionthenClause, treeCallFlag, ntx1, context, use1];
[vdc3, sc3, ac3, fac3, at3, ntx3, use3] ← treeData.RecExpressionelseClause.procs.CompForArgs[treeData.RecExpressionelseClause, treeCallFlag, ntx2, context, use2];
check2 ← CheckForEqualTypeLists[at2, at3];
[bt, nextTempX] ← InventTemps[IntegerFromRope["1"], ntx3];
IF EqualTreeCallFlags[treeCallFlag, TreeCallFlag.yes] THEN {firstArgCode ← RopeCode3["(IF %g THEN %g ELSE %g)", NameFill[TheOneName[bt]], CodeFill[fac2], CodeFill[fac3]];
} ELSE {firstArgCode ← BuildEmptyCode[];
};
argCode ← RopeCode3["(IF %g THEN %g ELSE %g)", NameFill[TheOneName[bt]], CodeFill[ac2], CodeFill[ac3]];
statementCode ← ConcatCode6[sc1, RopeCode2["IF %g ← %g THEN { NULL;\N", NameFill[TheOneName[bt]], CodeFill[ac1]], sc2, RopeCode["} ELSE {NULL;\N"], sc3, RopeCode["};\N"]];
bTypes ← BuildOneTypeList[LookUpType[context, BuildRopeName["BOOLEAN"]]];
use ← RecordTypesUse[use3, bTypes];
varDeclCode ← ConcatCode3[BuildVarDeclCode[bt, bTypes], vdc3, vdc2];
temp6 ← use;
temp5 ← nextTempX;
temp4 ← at2;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressioncallProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncallProdData ← NARROW[tree.data];
BEGIN
case: FunctionCase;
argTypes: TypeListNode;
resultTypes: TypeListNode;
[case, argTypes, resultTypes] ← LookUpFunction[context, BuildName[treeData.Identifier]];
temp0 ← CountTypes[resultTypes];
END;
END
END;

RecExpressioncallProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncallProdData ← NARROW[tree.data];
BEGIN
statementCode: MesaCodeNode;
assignResultCode: MesaCodeNode;
oneResult: BOOLEAN;
fCall: MesaCodeNode;
argNames: NameListNode;
restNames: NameListNode;
check1: BOOLEAN;
varDeclCode: MesaCodeNode;
sc: MesaCodeNode;
ac: MesaCodeNode;
fac: MesaCodeNode;
at: TypeListNode;
nextTempX: IntegerNode;
use: UsageNode;
use0: UsageNode;
subTreeCallFlag: TreeCallFlag;
fCase: FunctionCase;
funArgTypes: TypeListNode;
funResultTypes: TypeListNode;
funName: NameNode;
funName ← BuildName[treeData.Identifier];
[fCase, funArgTypes, funResultTypes] ← LookUpFunction[context, funName];
IF EqualFunCase[fCase, FunctionCase.base] THEN {subTreeCallFlag ← TreeCallFlag.no;
} ELSE {subTreeCallFlag ← TreeCallFlag.yes;
};
IF EqualFunCase[fCase, FunctionCase.recursive] THEN {use0 ← FakeUsageCopy[usage];
} ELSE {use0 ← RecordFcnUse[usage, funName, Use.import, context];
};
[varDeclCode, sc, ac, fac, at, nextTempX, use] ← treeData.RecExpSeq.procs.CompForArgs[treeData.RecExpSeq, subTreeCallFlag, firstTempX, context, use0];
check1 ← CompareValTypesWithVarTypes[at, funArgTypes];
[argNames, restNames] ← PartitionNames[CountTypes[funResultTypes], varNames];
IF EqualFunCase[fCase, FunctionCase.base] THEN {fCall ← RopeCode2["%g[%g]", IdFill[treeData.Identifier], CodeFill[ac]];
} ELSE {fCall ← RopeCode3["%g.procs.%g[%g]", CodeFill[fac], IdFill[treeData.Identifier], CodeFill[ac]];
};
oneResult ← EqualInteger[CountTypes[funResultTypes], IntegerFromRope["1"]];
IF oneResult THEN {assignResultCode ← BuildNameSeqArgCode[argNames];
} ELSE {assignResultCode ← RopeCode1["[%g]", CodeFill[BuildNameSeqArgCode[argNames]]];
};
statementCode ← ConcatCode2[sc, RopeCode2["%g ← %g;\N", CodeFill[assignResultCode], CodeFill[fCall]]];
temp5 ← use;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← funResultTypes;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressioncallProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressioncallProdData ← NARROW[tree.data];
BEGIN
nextTempX: IntegerNode;
firstArgCode: MesaCodeNode;
argCode: MesaCodeNode;
statementCode: MesaCodeNode;
varDeclCode: MesaCodeNode;
use: UsageNode;
use2: UsageNode;
localVars: NameListNode;
firstLocalVar: NameNode;
otherLocalVars: NameListNode;
inventedTemps: NameListNode;
ntx2: IntegerNode;
simple: BOOLEAN;
oneResult: BOOLEAN;
fCall: MesaCodeNode;
check1: BOOLEAN;
vdc1: MesaCodeNode;
sc1: MesaCodeNode;
ac: MesaCodeNode;
fac: MesaCodeNode;
at: TypeListNode;
ntx1: IntegerNode;
use1: UsageNode;
use0: UsageNode;
subTreeCallFlag: TreeCallFlag;
fCase: FunctionCase;
funArgTypes: TypeListNode;
funResultTypes: TypeListNode;
funName: NameNode;
funName ← BuildName[treeData.Identifier];
[fCase, funArgTypes, funResultTypes] ← LookUpFunction[context, funName];
IF EqualFunCase[fCase, FunctionCase.base] THEN {subTreeCallFlag ← TreeCallFlag.no;
} ELSE {subTreeCallFlag ← TreeCallFlag.yes;
};
IF EqualFunCase[fCase, FunctionCase.recursive] THEN {use0 ← FakeUsageCopy[usage];
} ELSE {use0 ← RecordFcnUse[usage, funName, Use.import, context];
};
[vdc1, sc1, ac, fac, at, ntx1, use1] ← treeData.RecExpSeq.procs.CompForArgs[treeData.RecExpSeq, subTreeCallFlag, firstTempX, context, use0];
check1 ← CompareValTypesWithVarTypes[at, funArgTypes];
IF EqualFunCase[fCase, FunctionCase.base] THEN {fCall ← RopeCode2["%g[%g]", IdFill[treeData.Identifier], CodeFill[ac]];
} ELSE {fCall ← RopeCode3["%g.procs.%g[%g]", CodeFill[fac], IdFill[treeData.Identifier], CodeFill[ac]];
};
oneResult ← EqualInteger[CountTypes[funResultTypes], IntegerFromRope["1"]];
simple ← AndLogical[EqualTreeCallFlags[treeCallFlag, TreeCallFlag.no], oneResult];
[inventedTemps, ntx2] ← InventTemps[CountTypes[funResultTypes], ntx1];
[firstLocalVar, otherLocalVars] ← PartitionFirstName[inventedTemps];
IF simple THEN {localVars ← BuildEmptyNameList[];
} ELSE {localVars ← inventedTemps;
};
IF simple THEN {use2 ← FakeUsageCopy[use1];
} ELSE {use2 ← RecordTypesUse[use1, funResultTypes];
};
IF EqualFunCase[fCase, FunctionCase.recursive] THEN {use ← FakeUsageCopy[use2];
} ELSE {use ← RecordFcnUse[use2, funName, Use.import, context];
};
IF simple THEN {varDeclCode ← FakeCopyCodeForConditional[vdc1];
} ELSE {varDeclCode ← ConcatCode2[BuildVarDeclCode[localVars, funResultTypes], vdc1];
};
IF simple THEN {statementCode ← FakeCopyCodeForConditional[sc1];
} ELSE {IF oneResult THEN {statementCode ← ConcatCode2[FakeCopyCodeForConditional[sc1], RopeCode2["%g ← %g;\N", CodeFill[BuildNameSeqArgCode[localVars]], CodeFill[fCall]]];
} ELSE {statementCode ← ConcatCode2[FakeCopyCodeForConditional[sc1], RopeCode2["[%g] ← %g;\N", CodeFill[BuildNameSeqArgCode[localVars]], CodeFill[fCall]]];
};
};
IF simple THEN {argCode ← fCall;
} ELSE {argCode ← BuildNameSeqArgCode[localVars];
};
IF simple THEN {firstArgCode ← BuildEmptyCode[];
} ELSE {firstArgCode ← RopeCode1["%g", NameFill[firstLocalVar]];
};
IF simple THEN {nextTempX ← ntx1;
} ELSE {nextTempX ← ntx2;
};
temp6 ← use;
temp5 ← nextTempX;
temp4 ← funResultTypes;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressionseqProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionseqProdData ← NARROW[tree.data];
temp0 ← treeData.RecExpSeq.procs.CountVals[treeData.RecExpSeq, context];
END
END;

RecExpressionseqProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionseqProdData ← NARROW[tree.data];
BEGIN
varDeclCode: MesaCodeNode;
statementCode: MesaCodeNode;
varTypes: TypeListNode;
restNames: NameListNode;
nextTempX: IntegerNode;
use: UsageNode;
[varDeclCode, statementCode, varTypes, restNames, nextTempX, use] ← treeData.RecExpSeq.procs.CompForVars[treeData.RecExpSeq, varNames, firstTempX, context, usage];
temp5 ← use;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← varTypes;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressionseqProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionseqProdData ← NARROW[tree.data];
BEGIN
varDeclCode: MesaCodeNode;
statementCode: MesaCodeNode;
argCode: MesaCodeNode;
firstArgCode: MesaCodeNode;
argTypes: TypeListNode;
nextTempX: IntegerNode;
use: UsageNode;
[varDeclCode, statementCode, argCode, firstArgCode, argTypes, nextTempX, use] ← treeData.RecExpSeq.procs.CompForArgs[treeData.RecExpSeq, treeCallFlag, firstTempX, context, usage];
temp6 ← use;
temp5 ← nextTempX;
temp4 ← argTypes;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressionidProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionidProdData ← NARROW[tree.data];
temp0 ← IntegerFromRope["1"];
END
END;

RecExpressionidProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionidProdData ← NARROW[tree.data];
BEGIN
statementCode: MesaCodeNode;
firstName: NameNode;
restNames: NameListNode;
varDeclCode: MesaCodeNode;
valStatementCode: MesaCodeNode;
valCode: MesaCodeNode;
junk: MesaCodeNode;
valTypes: TypeListNode;
nextTempX: IntegerNode;
use: UsageNode;
[varDeclCode, valStatementCode, valCode, junk, valTypes, nextTempX, use] ← tree.procs.CompForArgs[tree, TreeCallFlag.no, firstTempX, context, usage];
[firstName, restNames] ← PartitionFirstName[varNames];
statementCode ← ConcatCode4[RopeCode1["%g ← ", NameFill[firstName]], valCode, RopeCode[";\N"], valStatementCode];
temp5 ← use;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← valTypes;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressionidProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionidProdData ← NARROW[tree.data];
BEGIN
argCode: MesaCodeNode;
firstArgCode: MesaCodeNode;
idTypes: TypeListNode;
type: TypeNode;
code: MesaCodeNode;
[type, code] ← LookUpSimpleValue[context, treeData.Identifier];
idTypes ← BuildOneTypeList[type];
IF EqualTreeCallFlags[treeCallFlag, TreeCallFlag.yes] THEN {firstArgCode ← RopeCode1["%g", CodeFill[code]];
} ELSE {firstArgCode ← BuildEmptyCode[];
};
argCode ← code;
temp6 ← FakeUsageCopy[usage];
temp5 ← FakeCopyInteger[firstTempX];
temp4 ← idTypes;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← BuildEmptyCode[];
temp0 ← BuildEmptyCode[];
END;
END
END;

RecExpressionmodIdProdCountVals: PUBLIC PROC[ref: REF ANY, context: LookupContextNode] RETURNS[temp0: IntegerNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionmodIdProdData ← NARROW[tree.data];
temp0 ← IntegerFromRope["1"];
END
END;

RecExpressionmodIdProdCompForVars: PUBLIC PROC[ref: REF ANY, varNames: NameListNode, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: TypeListNode, temp3: NameListNode, temp4: IntegerNode, temp5: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionmodIdProdData ← NARROW[tree.data];
BEGIN
statementCode: MesaCodeNode;
firstName: NameNode;
restNames: NameListNode;
varDeclCode: MesaCodeNode;
valStatementCode: MesaCodeNode;
valCode: MesaCodeNode;
junk: MesaCodeNode;
valTypes: TypeListNode;
nextTempX: IntegerNode;
use: UsageNode;
[varDeclCode, valStatementCode, valCode, junk, valTypes, nextTempX, use] ← tree.procs.CompForArgs[tree, TreeCallFlag.no, firstTempX, context, usage];
[firstName, restNames] ← PartitionFirstName[varNames];
statementCode ← ConcatCode4[RopeCode1["%g ← ", NameFill[firstName]], valCode, RopeCode[";\N"], valStatementCode];
temp5 ← use;
temp4 ← nextTempX;
temp3 ← restNames;
temp2 ← valTypes;
temp1 ← statementCode;
temp0 ← varDeclCode;
END;
END
END;

RecExpressionmodIdProdCompForArgs: PUBLIC PROC[ref: REF ANY, treeCallFlag: TreeCallFlag, firstTempX: IntegerNode, context: LookupContextNode, usage: UsageNode] RETURNS[temp0: MesaCodeNode, temp1: MesaCodeNode, temp2: MesaCodeNode, temp3: MesaCodeNode, temp4: TypeListNode, temp5: IntegerNode, temp6: UsageNode] =
BEGIN
tree: RecExpressionNode← NARROW[ref];
BEGIN
ENABLE ThreeC4Support.GetSourceInfo => RESUME[tree.position, tree.length];
treeData: RecExpressionmodIdProdData ← NARROW[tree.data];
BEGIN
argCode: MesaCodeNode;
firstArgCode: MesaCodeNode;
idTypes: TypeListNode;
use: UsageNode;
type: TypeNode;
code: MesaCodeNode;
[type, code] ← LookUpValue2[context, treeData.Identifiera, treeData.Identifierb];
use ← RecordTypeUse[usage, type];
idTypes ← BuildOneTypeList[type];
IF EqualTreeCallFlags[treeCallFlag, TreeCallFlag.yes] THEN {firstArgCode ← RopeCode1["%g", CodeFill[code]];
} ELSE {firstArgCode ← BuildEmptyCode[];
};
argCode ← code;
temp6 ← use;
temp5 ← FakeCopyInteger[firstTempX];
temp4 ← idTypes;
temp3 ← firstArgCode;
temp2 ← argCode;
temp1 ← BuildEmptyCode[];
temp0 ← BuildEmptyCode[];
END;
END
END;

END..