public void EmitRewritingRuleCountAllCallOrRuleAllCallNonRandom(SourceBuilder source, String firstRewrite, bool fireDebugEvents) { // iterate through matches, use Modify on each, fire the next match event after the first if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarationsAllCall + "\n"); } String enumeratorName = "enum_" + ruleCallRewritingGenerator.seqRule.Id; source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", null, " + specialStr + ");\n"); } if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } source.AppendFront("if(!" + firstRewrite + ") procEnv.RewritingNextMatch();\n"); if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleCallRewritingGenerator.ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(intermediateReturnAssignmentsAllCall + "\n"); } source.AppendFront("procEnv.PerformanceInfo.RewritesPerformed++;\n"); source.AppendFront(firstRewrite + " = false;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } source.Unindent(); source.AppendFront("}\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignmentsAllCall + "\n"); } if (ruleCallRewritingGenerator.seqRule.SequenceType == SequenceType.RuleCountAllCall) { SequenceRuleCountAllCall ruleCountAll = (SequenceRuleCountAllCall)ruleCallRewritingGenerator.seqRule; source.AppendFront(ruleCallRewritingGenerator.seqHelper.SetVar(ruleCountAll.CountResult, matchesName + ".Count")); } }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String parameterDeclarations = null; String parameters = null; if (seqRule.Subgraph != null) { parameters = seqHelper.BuildParametersInDeclarations(seqRule, ArgumentExpressions, source, out parameterDeclarations); } else { parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); } if (seqRule.Subgraph != null) { source.AppendFront(parameterDeclarations + "\n"); source.AppendFront("procEnv.SwitchToSubgraph((GRGEN_LIBGR.IGraph)" + seqHelper.GetVar(seqRule.Subgraph) + ");\n"); source.AppendFront("graph = ((GRGEN_LGSP.LGSPActionExecutionEnvironment)procEnv).graph;\n"); } source.AppendFront(matchesType + " " + matchesName + " = " + ruleName + ".Match(procEnv, " + (seqRule.SequenceType == SequenceType.RuleCall ? "1" : "procEnv.MaxMatches") + parameters + ");\n"); source.AppendFront("procEnv.PerformanceInfo.MatchesFound += " + matchesName + ".Count;\n"); for (int i = 0; i < seqRule.Filters.Count; ++i) { seqExprGen.EmitFilterCall(source, (SequenceFilterCallCompiled)seqRule.Filters[i], patternName, matchesName, seqRule.PackagePrefixedName, false); } if (seqRule is SequenceRuleCountAllCall) { SequenceRuleCountAllCall seqRuleCountAll = (SequenceRuleCountAllCall)seqRule; source.AppendFront(seqHelper.SetVar(seqRuleCountAll.CountResult, matchesName + ".Count")); } String insufficientMatchesCondition; if (seqRule is SequenceRuleAllCall && ((SequenceRuleAllCall)seqRule).ChooseRandom && ((SequenceRuleAllCall)seqRule).MinSpecified) { SequenceRuleAllCall seqRuleAll = (SequenceRuleAllCall)seqRule; String minMatchesVarName = "minmatchesvar_" + seqRuleAll.Id; source.AppendFrontFormat("int {0} = (int){1};\n", minMatchesVarName, seqHelper.GetVar(seqRuleAll.MinVarChooseRandom)); insufficientMatchesCondition = matchesName + ".Count < " + minMatchesVarName; } else { insufficientMatchesCondition = matchesName + ".Count == 0"; } source.AppendFrontFormat("if({0}) {{\n", insufficientMatchesCondition); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqRule, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqRule, "true")); if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", null, " + specialStr + ");\n"); } if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } SequenceRuleOrRuleAllCallRewritingGenerator rewritingGen = new SequenceRuleOrRuleAllCallRewritingGenerator(this); if (seqRule.SequenceType == SequenceType.RuleCall) { rewritingGen.EmitRewritingRuleCall(source); } else if (seqRule.SequenceType == SequenceType.RuleCountAllCall || !((SequenceRuleAllCall)seqRule).ChooseRandom) // seq.SequenceType == SequenceType.RuleAll { rewritingGen.EmitRewritingRuleCountAllCallOrRuleAllCallNonRandom(source); } else // seq.SequenceType == SequenceType.RuleAll && ((SequenceRuleAll)seqRule).ChooseRandom { rewritingGen.EmitRewritingRuleAllCallRandom(source); } if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } source.Unindent(); source.AppendFront("}\n"); if (seqRule.Subgraph != null) { source.AppendFront("procEnv.ReturnFromSubgraph();\n"); source.AppendFront("graph = ((GRGEN_LGSP.LGSPActionExecutionEnvironment)procEnv).graph;\n"); } }
/// <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; } }