-- ThreeC4RecFcnImplAbGram.ThreeC4
-- Sturgis, May 8, 1986 3:50:36 pm PDT

Include[ThreeC4BaseDecl, ThreeC4RecFcnDecl, ThreeC4BasicAbTypes];

ThreeC4RecFcnImplAbGram: Module =
Begin

-- this module contains the abstract grammar for the recursive function implementations

-- the following recursive functions are only used here

ProdImplFileCode:
  TreeRecursiveFunction[Tree, LookupContext, Name.type, Name.prod, Usage.arg]
   Returns[MesaCode, Usage.result]
    DamagedReps[Usage.arg];

CompForArgs:
  TreeRecursiveFunction[Tree, TreeCallFlag, Integer.firstTemp, LookupContext, Usage.arg]
   Returns[MesaCode.varDecl, MesaCode.statement, MesaCode.arg, MesaCode.firstArg, TypeList, Integer.nextTemp, Usage.result]
    DamagedReps[Integer.firstTemp, Usage.arg];

CompForVars:
  TreeRecursiveFunction[Tree, NameList.temps, Integer.firstTemp, LookupContext, Usage.arg]
   Returns[MesaCode.varDecl, MesaCode.statement, TypeList, NameList.tempsRemaining, Integer.nextTemp, Usage.result]
     DamagedReps[Integer.firstTemp, Usage.arg]
     SharedReps[NameList.temps, NameList.tempsRemaining];

CountVals: TreeRecursiveFunction[Tree, LookupContext] Returns[Integer];

CompWhere: TreeRecursiveFunction[Tree, Integer.firstTemp, LookupContext.arg, Usage.arg]
  Returns[MesaCode.varDecl, MesaCode.statement, Integer.nextTemp, LookupContext.result, Usage.result]
    SharedReps[LookupContext.arg, LookupContext.result]
    DamagedReps[Integer.firstTemp, Usage.arg];


-- the following base types and recursive functions involved in flow analysis are used only here


FcnImplGraph: BaseType;
SlotList: BaseType;
CallGraphNode: BaseType;
 
 BuildFcnImplGraph: BaseFunction[LookupContext, Identifier, NameList]
  Returns[FcnImplGraph];
 
 FakeCopyFcnImplGraph: BaseFunction[FcnImplGraph.arg] Returns[FcnImplGraph.result]
  DamagedReps[FcnImplGraph.arg];
 
 RecordCall: BaseFunction[FcnImplGraph.arg, LookupContext, Identifier, SlotList.arg, CallGraphNode.arg]
  Returns[FcnImplGraph.result, SlotList.result, CallGraphNode.build]
   DamagedReps[FcnImplGraph.arg];
 
 RecordAssignment: BaseFunction[FcnImplGraph.arg, NameList, SlotList, CallGraphNode.arg]
  Returns[FcnImplGraph.result, CallGraphNode.built]
   DamagedReps[FcnImplGraph.arg];
 
 RecordSequential: BaseFunction[FcnImplGraph.arg, CallGraphNode.arg1, CallGraphNode.arg2]
  Returns[FcnImplGraph.result, CallGraphNode.built]
   DamagedReps[FcnImplGraph.arg];
 
 RecordParallel: BaseFunction[FcnImplGraph.arg, CallGraphNode.arg1, CallGraphNode.arg2]
  Returns[FcnImplGraph.result, CallGraphNode.built]
   DamagedReps[FcnImplGraph.arg];
 
 RecordCondition: BaseFunction[FcnImplGraph.arg,
    SlotList.arg1, CallGraphNode.arg1, SlotList.arg2, CallGraphNode.arg2, SlotList.arg3, CallGraphNode.arg3]
  Returns[FcnImplGraph.result, SlotList.combined, CallGraphNode.built]
   DamagedReps[FcnImplGraph.arg];
 
 RecordSimpleVarUse: BaseFunction[FcnImplGraph.arg, LookupContext, Identifier]
  Returns[FcnImplGraph.result, SlotList, CallGraphNode]
   DamagedReps[FcnImplGraph.arg];
 
 RecordModIdUse: BaseFunction[FcnImplGraph.arg, LookupContext, Identifier.a, Identifier.b]
  Returns[FcnImplGraph.result, SlotList, CallGraphNode]
   DamagedReps[FcnImplGraph.arg];
 
 RecordLiteralUse: BaseFunction[FcnImplGraph.arg, INT]
  Returns[FcnImplGraph.result, SlotList, CallGraphNode]
   DamagedReps[FcnImplGraph.arg];
 
 OpenWithWhereList: BaseFunction[FcnImplGraph.arg] Returns[FcnImplGraph.result]
  DamagedReps[FcnImplGraph.arg];
 
 CloseWithWhereList: BaseFunction[FcnImplGraph.arg] Returns[FcnImplGraph.result]
  DamagedReps[FcnImplGraph.arg];
 
 CheckFcnImpl: BaseFunction[LookupContext, FcnImplGraph.arg, SlotList, CallGraphNode]
  Returns[BOOLEAN]
   DamagedReps[FcnImplGraph.arg];
   
 
 ConcatSlotList: BaseFunction[SlotList.arg1, SlotList.arg2] Returns[SlotList.result]
  DamagedReps[SlotList.arg1]
  SharedReps[SlotList.arg2, SlotList.result];
 
 BuildEmptySlotList: BaseFunction Returns[SlotList];
 
 BuildEmptyCallGraphNode: BaseFunction Returns[CallGraphNode];
 
 
 
 FormFcnImplGraph: TreeRecursiveFunction[Tree, LookupContext, FcnImplGraph.arg]
  Returns[FcnImplGraph.result, SlotList, CallGraphNode]
   DamagedReps[FcnImplGraph.arg];
 
 FormFcnImplWhereGraph: TreeRecursiveFunction[Tree, LookupContext, FcnImplGraph.arg]
  Returns[FcnImplGraph.result, CallGraphNode]
   DamagedReps[FcnImplGraph.arg];
 
 
  





-- AbProductionFcnImpl is declared in BasicAbTypes

 AbProductionFcnImpl: AbstractProduction[ModId, ModIdList, RecFcnImplList];



RecFcnImplList: AbstractType[ProdImplFileCode];

 RecFcnImplList.one: AbstractProduction[Identifier, IdList, RecExpression];

 RecFcnImplList.many: AbstractProduction[RecFcnImplList.a, RecFcnImplList.b];
 


RecExpression: AbstractType[CompForArgs, CompForVars, CountVals, FormFcnImplGraph];

 RecExpression.withWhereList: AbstractProduction[RecExpression, WhereExpSeq];
 
 RecExpression.cond:
   AbstractProduction[
    RecExpression.ifClause,
    RecExpression.thenClause,
    RecExpression.elseClause];
 
 RecExpression.call: AbstractProduction[Identifier, RecExpSeq];
 
 RecExpression.seq: AbstractProduction[RecExpSeq];
 
 RecExpression.id: AbstractProduction[Identifier];
 
 RecExpression.modId: AbstractProduction[Identifier.a, Identifier.b];
 
 RecExpression.rope: AbstractProduction[Rope];
 
 RecExpression.numb: AbstractProduction[NonNegInteger];
 
 RecExpression.sourcePosition: AbstractProduction[ModId];
 
 RecExpression.sourceLength: AbstractProduction[ModId];


RecExpSeq: AbstractType[CompForArgs, CompForVars, CountVals, FormFcnImplGraph];

 RecExpSeq.empty: AbstractProduction[];
 
 RecExpSeq.one: AbstractProduction[RecExpression];
 
 RecExpSeq.many: AbstractProduction[RecExpSeq.a, RecExpSeq.b];
  -- concrete grammar guarantees both non empty
 


WhereExpSeq: AbstractType[CompWhere, FormFcnImplWhereGraph];

 WhereExpSeq.one: AbstractProduction[IdList, RecExpression];
 
 WhereExpSeq.many: AbstractProduction[WhereExpSeq.a, WhereExpSeq.b]

 
End.