-- 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.