/// <summary> /// Helper for checking sequence calls. /// Type checks the input, type checks the output. /// Throws an exception when an error is found. /// </summary> /// <param name="seqSeqCall">The sequence call to check</param> public void CheckSequenceCall(SequenceSequenceCall seqSeqCall) { CheckInputParameters(seqSeqCall, seqSeqCall.ArgumentExpressions, null); CheckOutputParameters(seqSeqCall, seqSeqCall.ReturnVars, null); CheckSubgraph(seqSeqCall); // ok, this is a well-formed invocation }
/// <summary> /// pre-run for emitting the needed entities before emitting the real code /// - emits result variable declarations /// - emits sequence variable declarations (only once for every variable, declaration only possible at assignment targets) /// - collects used rules into knownRules, emit local rule declaration (only once for every rule) /// </summary> public void EmitNeededVarAndRuleEntities(Sequence seq, SourceBuilder source) { source.AppendFront(COMP_HELPER.DeclareResultVar(seq)); switch (seq.SequenceType) { case SequenceType.AssignUserInputToVar: case SequenceType.AssignRandomIntToVar: case SequenceType.AssignRandomDoubleToVar: case SequenceType.DeclareVariable: case SequenceType.AssignConstToVar: case SequenceType.AssignContainerConstructorToVar: case SequenceType.AssignVarToVar: { SequenceAssignToVar toVar = (SequenceAssignToVar)seq; EmitVarIfNew(toVar.DestVar, source); break; } case SequenceType.AssignSequenceResultToVar: case SequenceType.OrAssignSequenceResultToVar: case SequenceType.AndAssignSequenceResultToVar: { SequenceAssignSequenceResultToVar seqToVar = (SequenceAssignSequenceResultToVar)seq; EmitVarIfNew(seqToVar.DestVar, source); EmitNeededVarAndRuleEntities(seqToVar.Seq, source); break; } case SequenceType.RuleCall: case SequenceType.RuleAllCall: case SequenceType.RuleCountAllCall: { SequenceRuleCall seqRule = (SequenceRuleCall)seq; String ruleName = seqRule.PackagePrefixedName; if (!knownRules.ContainsKey(ruleName)) { knownRules.Add(ruleName, null); source.AppendFront("GRGEN_ACTIONS." + TypesHelper.GetPackagePrefixDot(seqRule.Package) + "Action_" + seqRule.Name + " " + "rule_" + TypesHelper.PackagePrefixedNameUnderscore(seqRule.Package, seqRule.Name)); source.Append(" = " + "GRGEN_ACTIONS." + TypesHelper.GetPackagePrefixDot(seqRule.Package) + "Action_" + seqRule.Name + ".Instance;\n"); } // no handling for the input arguments seqRule.ArgumentExpressions needed // because there can only be variable uses for (int i = 0; i < seqRule.ReturnVars.Length; ++i) { EmitVarIfNew(seqRule.ReturnVars[i], source); } if (seq.SequenceType == SequenceType.RuleCountAllCall) { SequenceRuleCountAllCall seqCountRuleAll = (SequenceRuleCountAllCall)seqRule; EmitVarIfNew(seqCountRuleAll.CountResult, source); } break; } case SequenceType.SequenceCall: { SequenceSequenceCall seqSeq = (SequenceSequenceCall)seq; // no handling for the input arguments seqSeq.ArgumentExpressions or the optional Subgraph needed // because there can only be variable uses for (int i = 0; i < seqSeq.ReturnVars.Length; ++i) { EmitVarIfNew(seqSeq.ReturnVars[i], source); } break; } case SequenceType.ForContainer: { SequenceForContainer seqFor = (SequenceForContainer)seq; EmitVarIfNew(seqFor.Var, source); if (seqFor.VarDst != null) { EmitVarIfNew(seqFor.VarDst, source); } EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIntegerRange: { SequenceForIntegerRange seqFor = (SequenceForIntegerRange)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIndexAccessEquality: { SequenceForIndexAccessEquality seqFor = (SequenceForIndexAccessEquality)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIndexAccessOrdering: { SequenceForIndexAccessOrdering seqFor = (SequenceForIndexAccessOrdering)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForAdjacentNodes: case SequenceType.ForAdjacentNodesViaIncoming: case SequenceType.ForAdjacentNodesViaOutgoing: case SequenceType.ForIncidentEdges: case SequenceType.ForIncomingEdges: case SequenceType.ForOutgoingEdges: case SequenceType.ForReachableNodes: case SequenceType.ForReachableNodesViaIncoming: case SequenceType.ForReachableNodesViaOutgoing: case SequenceType.ForReachableEdges: case SequenceType.ForReachableEdgesViaIncoming: case SequenceType.ForReachableEdgesViaOutgoing: case SequenceType.ForBoundedReachableNodes: case SequenceType.ForBoundedReachableNodesViaIncoming: case SequenceType.ForBoundedReachableNodesViaOutgoing: case SequenceType.ForBoundedReachableEdges: case SequenceType.ForBoundedReachableEdgesViaIncoming: case SequenceType.ForBoundedReachableEdgesViaOutgoing: case SequenceType.ForNodes: case SequenceType.ForEdges: { SequenceForFunction seqFor = (SequenceForFunction)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForMatch: { SequenceForMatch seqFor = (SequenceForMatch)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); EmitNeededVarAndRuleEntities(seqFor.Rule, source); break; } case SequenceType.BooleanComputation: { SequenceBooleanComputation seqBoolComp = (SequenceBooleanComputation)seq; EmitNeededVarEntities(seqBoolComp.Computation, source); break; } default: foreach (Sequence childSeq in seq.Children) { EmitNeededVarAndRuleEntities(childSeq, source); } break; } }