internal override void Populate(string property) { base.Populate(property); InputVariable.Populate(property); RepeatContext.Populate(property); }
internal override GremlinPathStepVariable GetAndPopulatePath() { GremlinPathVariable pathVariable = RepeatContext.PopulateGremlinPath(); pathVariable.IsInRepeatContext = true; return(new GremlinPathStepVariable(pathVariable, this)); }
protected override async Task <decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator) { var repeatAttribute = GetRepeatAttribute(TestMethod); if (repeatAttribute == null) { return(await InvokeTestMethodCoreAsync(aggregator).ConfigureAwait(false)); } var repeatContext = new RepeatContext(repeatAttribute.RunCount); RepeatContext.Current = repeatContext; var timeTaken = 0.0M; for (repeatContext.CurrentIteration = 0; repeatContext.CurrentIteration < repeatContext.Limit; repeatContext.CurrentIteration++) { timeTaken = await InvokeTestMethodCoreAsync(aggregator).ConfigureAwait(false); if (aggregator.HasExceptions) { return(timeTaken); } } return(timeTaken); }
internal override void PopulateLocalPath() { if (ProjectedProperties.Contains(GremlinKeyword.Path)) { return; } ProjectedProperties.Add(GremlinKeyword.Path); RepeatContext.PopulateLocalPath(); }
public RepeatContext(RepeatContext previous, int min, int max, bool lazy, int expr_pc) { this.previous = previous; this.min = min; this.max = max; this.lazy = lazy; this.expr_pc = expr_pc; start = -1; count = 0; }
public static void RegisterRepeatCount(this ScenarioStepContext context, string repeatContextName, int count) { if (!ExecutionContextContainer.Contexts[Thread.CurrentThread.ManagedThreadId].RegressionEnabled) { throw new TagNotSetException("enable-regression", nameof(RegisterRepeatCount)); } var contextDictionary = ExecutionContextContainer.Contexts[Thread.CurrentThread.ManagedThreadId].RepeatContext; contextDictionary[repeatContextName] = new RepeatContext() { Count = count, BeginStepDefinition = context.CurrentStep() }; }
internal override List <GremlinVariable> FetchVarsFromCurrAndChildContext() { List <GremlinVariable> variableList = new List <GremlinVariable>(); variableList.AddRange(RepeatContext.FetchVarsFromCurrAndChildContext()); if (RepeatCondition.EmitContext != null) { variableList.AddRange(RepeatCondition.EmitContext.FetchVarsFromCurrAndChildContext()); } if (RepeatCondition.TerminationContext != null) { variableList.AddRange(RepeatCondition.TerminationContext.FetchVarsFromCurrAndChildContext()); } return(variableList); }
internal override List <GremlinVariable> PopulateAllTaggedVariable(string label) { List <GremlinVariable> variableList = new List <GremlinVariable>(); foreach (var variable in RepeatContext.SelectVarsFromCurrAndChildContext(label)) { var repeatSelectedVariable = new GremlinRepeatSelectedVariable(this, variable, label); variableList.Add(repeatSelectedVariable); if (SelectedVariableList.All(p => p.Item1 != label)) { SelectedVariableList.Add(new Tuple <string, GremlinRepeatSelectedVariable>(label, repeatSelectedVariable)); } } return(variableList); }
internal override void Populate(string property) { if (ProjectedProperties.Contains(property)) { return; } base.Populate(property); InputVariable.Populate(property); if (SelectedVariableList.Exists(p => p.Item1 != property)) { RepeatContext.Populate(property); } else { RepeatContext.Populate(property); } }
internal override List <GremlinVariable> FetchAllTableVars() { List <GremlinVariable> variableList = new List <GremlinVariable>() { this }; variableList.AddRange(RepeatContext.FetchAllTableVars()); if (RepeatCondition.EmitContext != null) { variableList.AddRange(RepeatCondition.EmitContext.FetchAllTableVars()); } if (RepeatCondition.TerminationContext != null) { variableList.AddRange(RepeatCondition.TerminationContext.FetchAllTableVars()); } return(variableList); }
public List <WSelectScalarExpression> GetOuterSelectList(ref Dictionary <GremlinVariableProperty, string> map) { List <WSelectScalarExpression> outerSelectList = new List <WSelectScalarExpression>(); var allVariablesInRepeatContext = RepeatContext.FetchVarsFromCurrAndChildContext(); foreach (var variable in allVariablesInRepeatContext) { if (variable is GremlinSelectedVariable) { var repeatInnerVar = (variable as GremlinSelectedVariable); if (repeatInnerVar.IsFromSelect && !allVariablesInRepeatContext.Contains(repeatInnerVar.RealVariable)) { List <GremlinVariable> outerVarList = RepeatContext.Select(repeatInnerVar.SelectKey); GremlinVariable outerVar = null; switch (repeatInnerVar.Pop) { case GremlinKeyword.Pop.last: outerVar = outerVarList.Last(); break; case GremlinKeyword.Pop.first: outerVar = outerVarList.First(); break; } if (repeatInnerVar != outerVar) { foreach (var property in repeatInnerVar.ProjectedProperties) { var aliasName = GenerateKey(); outerSelectList.Add( SqlUtil.GetSelectScalarExpr( outerVar.GetVariableProperty(property).ToScalarExpression(), aliasName)); map[repeatInnerVar.GetVariableProperty(property)] = aliasName; } } } } } return(outerSelectList); }
public List <WSelectScalarExpression> GetRepeatPathOuterVariableList(ref Dictionary <GremlinVariableProperty, string> map) { List <WSelectScalarExpression> pathOuterVariableList = new List <WSelectScalarExpression>(); var allVariablesInRepeatContext = RepeatContext.FetchVarsFromCurrAndChildContext(); foreach (var variable in allVariablesInRepeatContext) { if (variable is GremlinPathVariable) { var pathVariable = (variable as GremlinPathVariable); foreach (var stepVariable in pathVariable.PathList) { if (!allVariablesInRepeatContext.Contains(stepVariable.GremlinVariable)) { var aliasName = GenerateKey(); pathOuterVariableList.Add(SqlUtil.GetSelectScalarExpr(stepVariable.ToScalarExpression(), aliasName)); map[stepVariable] = aliasName; } } } } return(pathOuterVariableList); }
public static void DecrementRepeatCount(this ScenarioStepContext context, string repeatContextName) { if (!ExecutionContextContainer.Contexts[Thread.CurrentThread.ManagedThreadId].RegressionEnabled) { throw new TagNotSetException("enable-regression", nameof(DecrementRepeatCount)); } var contextDictionary = ExecutionContextContainer.Contexts[Thread.CurrentThread.ManagedThreadId].RepeatContext; if (contextDictionary.ContainsKey(repeatContextName)) { contextDictionary[repeatContextName] = new RepeatContext() { Count = contextDictionary[repeatContextName].Count - 1, BeginStepDefinition = contextDictionary[repeatContextName].BeginStepDefinition, EndStepDefinition = context.CurrentStep() }; } else { throw new AdvanceStepsException($"Repeat context with the name {repeatContextName} is not yet set, please call 'RegisterRepeatCount' to set it"); } }
private bool Eval(Mode mode, ref int ref_ptr, int pc) { int ptr = ref_ptr; Begin: for (;;) { ushort word = program[pc]; OpCode op = (OpCode)(word & 0x00ff); OpFlags flags = (OpFlags)(word & 0xff00); switch (op) { case OpCode.Anchor: { int skip = program[pc + 1]; int anch_offset = program[pc + 2]; bool anch_reverse = (flags & OpFlags.RightToLeft) != 0; int anch_ptr = anch_reverse ? ptr - anch_offset : ptr + anch_offset; int anch_end = text_end - match_min + anch_offset; // maximum anchor position int anch_begin = 0; // the general case for an anchoring expression is at the bottom, however we // do some checks for the common cases before to save processing time. the current // optimizer only outputs three types of anchoring expressions: fixed position, // fixed substring, and no anchor. OpCode anch_op = (OpCode)(program[pc + 3] & 0x00ff); if (anch_op == OpCode.Position && skip == 6) // position anchor // Anchor // Position // True { switch ((Position)program[pc + 4]) { case Position.StartOfString: if (anch_reverse || anch_offset == 0) { if (anch_reverse) { ptr = anch_offset; } if (TryMatch(ref ptr, pc + skip)) { goto Pass; } } break; case Position.StartOfLine: if (anch_ptr == 0) { ptr = 0; if (TryMatch(ref ptr, pc + skip)) { goto Pass; } ++anch_ptr; } while ((anch_reverse && anch_ptr >= 0) || (!anch_reverse && anch_ptr <= anch_end)) { if (anch_ptr == 0 || text[anch_ptr - 1] == '\n') { if (anch_reverse) { ptr = anch_ptr == anch_end ? anch_ptr : anch_ptr + anch_offset; } else { ptr = anch_ptr == 0 ? anch_ptr : anch_ptr - anch_offset; } if (TryMatch(ref ptr, pc + skip)) { goto Pass; } } if (anch_reverse) { --anch_ptr; } else { ++anch_ptr; } } break; case Position.StartOfScan: if (anch_ptr == scan_ptr) { ptr = anch_reverse ? scan_ptr + anch_offset : scan_ptr - anch_offset; if (TryMatch(ref ptr, pc + skip)) { goto Pass; } } break; default: // FIXME break; } } else if (qs != null || (anch_op == OpCode.String && skip == 6 + program[pc + 4])) // substring anchor // Anchor // String // True { bool reverse = ((OpFlags)program[pc + 3] & OpFlags.RightToLeft) != 0; if (qs == null) { bool ignore = ((OpFlags)program[pc + 3] & OpFlags.IgnoreCase) != 0; string substring = GetString(pc + 3); qs = new QuickSearch(substring, ignore, reverse); } while ((anch_reverse && anch_ptr >= anch_begin) || (!anch_reverse && anch_ptr <= anch_end)) { if (reverse) { anch_ptr = qs.Search(text, anch_ptr, anch_begin); if (anch_ptr != -1) { anch_ptr += qs.Length; } } else { anch_ptr = qs.Search(text, anch_ptr, anch_end); } if (anch_ptr < 0) { break; } ptr = reverse ? anch_ptr + anch_offset : anch_ptr - anch_offset; if (TryMatch(ref ptr, pc + skip)) { goto Pass; } if (reverse) { anch_ptr -= 2; } else { ++anch_ptr; } } } else if (anch_op == OpCode.True) // no anchor // Anchor // True { while ((anch_reverse && anch_ptr >= anch_begin) || (!anch_reverse && anch_ptr <= anch_end)) { ptr = anch_ptr; if (TryMatch(ref ptr, pc + skip)) { goto Pass; } if (anch_reverse) { --anch_ptr; } else { ++anch_ptr; } } } else // general case // Anchor // <expr> // True { while ((anch_reverse && anch_ptr >= anch_begin) || (!anch_reverse && anch_ptr <= anch_end)) { ptr = anch_ptr; if (Eval(Mode.Match, ref ptr, pc + 3)) { // anchor expression passed: try real expression at the correct offset ptr = anch_reverse ? anch_ptr + anch_offset : anch_ptr - anch_offset; if (TryMatch(ref ptr, pc + skip)) { goto Pass; } } if (anch_reverse) { --anch_ptr; } else { ++anch_ptr; } } } goto Fail; } case OpCode.False: { goto Fail; } case OpCode.True: { goto Pass; } case OpCode.Position: { if (!IsPosition((Position)program[pc + 1], ptr)) { goto Fail; } pc += 2; break; } case OpCode.String: { bool reverse = (flags & OpFlags.RightToLeft) != 0; bool ignore = (flags & OpFlags.IgnoreCase) != 0; int len = program[pc + 1]; if (reverse) { ptr -= len; if (ptr < 0) { goto Fail; } } else if (ptr + len > text_end) { goto Fail; } pc += 2; for (int i = 0; i < len; ++i) { char c = text[ptr + i]; if (ignore) { c = Char.ToLower(c); } if (c != (char)program[pc++]) { goto Fail; } } if (!reverse) { ptr += len; } break; } case OpCode.Reference: { bool reverse = (flags & OpFlags.RightToLeft) != 0; bool ignore = (flags & OpFlags.IgnoreCase) != 0; int m = GetLastDefined(program [pc + 1]); if (m < 0) { goto Fail; } int str = marks [m].Index; int len = marks [m].Length; if (reverse) { ptr -= len; if (ptr < 0) { goto Fail; } } else if (ptr + len > text_end) { goto Fail; } pc += 2; if (ignore) { for (int i = 0; i < len; ++i) { if (Char.ToLower(text[ptr + i]) != Char.ToLower(text[str + i])) { goto Fail; } } } else { for (int i = 0; i < len; ++i) { if (text[ptr + i] != text[str + i]) { goto Fail; } } } if (!reverse) { ptr += len; } break; } case OpCode.Character: case OpCode.Category: case OpCode.NotCategory: case OpCode.Range: case OpCode.Set: { if (!EvalChar(mode, ref ptr, ref pc, false)) { goto Fail; } break; } case OpCode.In: { int target = pc + program[pc + 1]; pc += 2; if (!EvalChar(mode, ref ptr, ref pc, true)) { goto Fail; } pc = target; break; } case OpCode.Open: { Open(program[pc + 1], ptr); pc += 2; break; } case OpCode.Close: { Close(program[pc + 1], ptr); pc += 2; break; } case OpCode.BalanceStart: { int start = ptr; //point before the balancing group if (!Eval(Mode.Match, ref ptr, pc + 5)) { goto Fail; } if (!Balance(program[pc + 1], program[pc + 2], (program[pc + 3] == 1 ? true : false), start)) { goto Fail; } pc += program[pc + 4]; break; } case OpCode.Balance: { goto Pass; } case OpCode.IfDefined: { int m = GetLastDefined(program [pc + 2]); if (m < 0) { pc += program[pc + 1]; } else { pc += 3; } break; } case OpCode.Sub: { if (!Eval(Mode.Match, ref ptr, pc + 2)) { goto Fail; } pc += program[pc + 1]; break; } case OpCode.Test: { int cp = Checkpoint(); int test_ptr = ptr; if (Eval(Mode.Match, ref test_ptr, pc + 3)) { pc += program[pc + 1]; } else { Backtrack(cp); pc += program[pc + 2]; } break; } case OpCode.Branch: { OpCode branch_op; do { int cp = Checkpoint(); if (Eval(Mode.Match, ref ptr, pc + 2)) { goto Pass; } Backtrack(cp); pc += program[pc + 1]; branch_op = (OpCode)(program[pc] & 0xff); } while (branch_op != OpCode.False); goto Fail; } case OpCode.Jump: { pc += program[pc + 1]; break; } case OpCode.Repeat: { this.repeat = new RepeatContext( this.repeat, // previous context ReadProgramCount(pc + 2), // minimum ReadProgramCount(pc + 4), // maximum (flags & OpFlags.Lazy) != 0, // lazy pc + 6 // subexpression ); if (Eval(Mode.Match, ref ptr, pc + program[pc + 1])) { goto Pass; } else { this.repeat = this.repeat.Previous; goto Fail; } } case OpCode.Until: { RepeatContext current = this.repeat; // // Can we avoid recursion? // // Backtracking can be forced in nested quantifiers from the tail of this quantifier. // Thus, we cannot, in general, use a simple loop on repeat.Expression to handle // quantifiers. // // If 'deep' was unmolested, that implies that there was no nested quantifiers. // Thus, we can safely avoid recursion. // if (deep == current) { goto Pass; } int start = current.Start; int start_count = current.Count; while (!current.IsMinimum) { ++current.Count; current.Start = ptr; deep = current; if (!Eval(Mode.Match, ref ptr, current.Expression)) { current.Start = start; current.Count = start_count; goto Fail; } if (deep != current) // recursive mode { goto Pass; } } if (ptr == current.Start) { // degenerate match ... match tail or fail this.repeat = current.Previous; deep = null; if (Eval(Mode.Match, ref ptr, pc + 1)) { goto Pass; } this.repeat = current; goto Fail; } if (current.IsLazy) { for (;;) { // match tail first ... this.repeat = current.Previous; deep = null; int cp = Checkpoint(); if (Eval(Mode.Match, ref ptr, pc + 1)) { goto Pass; } Backtrack(cp); // ... then match more this.repeat = current; if (current.IsMaximum) { goto Fail; } ++current.Count; current.Start = ptr; deep = current; if (!Eval(Mode.Match, ref ptr, current.Expression)) { current.Start = start; current.Count = start_count; goto Fail; } if (deep != current) // recursive mode { goto Pass; } // Degenerate match: ptr has not moved since the last (failed) tail match. // So, next and subsequent tail matches will fail. if (ptr == current.Start) { goto Fail; } } } else { int stack_size = stack.Count; // match greedily as much as possible while (!current.IsMaximum) { int cp = Checkpoint(); int old_ptr = ptr; int old_start = current.Start; ++current.Count; current.Start = ptr; deep = current; if (!Eval(Mode.Match, ref ptr, current.Expression)) { --current.Count; current.Start = old_start; Backtrack(cp); break; } if (deep != current) { // recursive mode: no more backtracking, truncate the stack stack.Count = stack_size; goto Pass; } stack.Push(cp); stack.Push(old_ptr); // Degenerate match: no point going on if (ptr == current.Start) { break; } } // then, match the tail, backtracking as necessary. this.repeat = current.Previous; for (;;) { deep = null; if (Eval(Mode.Match, ref ptr, pc + 1)) { stack.Count = stack_size; goto Pass; } if (stack.Count == stack_size) { this.repeat = current; goto Fail; } --current.Count; ptr = stack.Pop(); Backtrack(stack.Pop()); } } } case OpCode.FastRepeat: { this.fast = new RepeatContext( fast, ReadProgramCount(pc + 2), // minimum ReadProgramCount(pc + 4), // maximum (flags & OpFlags.Lazy) != 0, // lazy pc + 6 // subexpression ); fast.Start = ptr; int cp = Checkpoint(); pc += program[pc + 1]; // tail expression ushort tail_word = program[pc]; int c1 = -1; // first character of tail operator int c2 = -1; // ... and the same character, in upper case if ignoring case int coff = 0; // 0 or -1 depending on direction OpCode tail_op = (OpCode)(tail_word & 0xff); if (tail_op == OpCode.Character || tail_op == OpCode.String) { OpFlags tail_flags = (OpFlags)(tail_word & 0xff00); if ((tail_flags & OpFlags.Negate) != 0) { goto skip; } if (tail_op == OpCode.String) { int offset = 0; if ((tail_flags & OpFlags.RightToLeft) != 0) { offset = program[pc + 1] - 1; } c1 = program[pc + 2 + offset]; // first char of string } else { c1 = program[pc + 1]; // character } if ((tail_flags & OpFlags.IgnoreCase) != 0) { c2 = Char.ToUpper((char)c1); // ignore case } else { c2 = c1; } if ((tail_flags & OpFlags.RightToLeft) != 0) { coff = -1; // reverse } else { coff = 0; } } skip: if (fast.IsLazy) { if (!fast.IsMinimum && !Eval(Mode.Count, ref ptr, fast.Expression)) { //Console.WriteLine ("lazy fast: failed mininum."); fast = fast.Previous; goto Fail; } while (true) { int p = ptr + coff; if (c1 < 0 || (p >= 0 && p < text_end && (c1 == text[p] || c2 == text[p]))) { deep = null; if (Eval(Mode.Match, ref ptr, pc)) { break; } } if (fast.IsMaximum) { //Console.WriteLine ("lazy fast: failed with maximum."); fast = fast.Previous; goto Fail; } Backtrack(cp); if (!Eval(Mode.Count, ref ptr, fast.Expression)) { //Console.WriteLine ("lazy fast: no more."); fast = fast.Previous; goto Fail; } } fast = fast.Previous; goto Pass; } else { if (!Eval(Mode.Count, ref ptr, fast.Expression)) { fast = fast.Previous; goto Fail; } int width; if (fast.Count > 0) { width = (ptr - fast.Start) / fast.Count; } else { width = 0; } while (true) { int p = ptr + coff; if (c1 < 0 || (p >= 0 && p < text_end && (c1 == text[p] || c2 == text[p]))) { deep = null; if (Eval(Mode.Match, ref ptr, pc)) { break; } } --fast.Count; if (!fast.IsMinimum) { fast = fast.Previous; goto Fail; } ptr -= width; Backtrack(cp); } fast = fast.Previous; goto Pass; } } case OpCode.Info: { Debug.Assert(false, "Regex", "Info block found in pattern"); goto Fail; } } } Pass: ref_ptr = ptr; switch (mode) { case Mode.Match: return(true); case Mode.Count: { ++fast.Count; if (fast.IsMaximum || (fast.IsLazy && fast.IsMinimum)) { return(true); } pc = fast.Expression; goto Begin; } } Fail: switch (mode) { case Mode.Match: return(false); case Mode.Count: { if (!fast.IsLazy && fast.IsMinimum) { return(true); } ref_ptr = fast.Start; return(false); } } return(false); }
internal override void PopulateGremlinPath() { RepeatContext.PopulateGremlinPath(); RepeatContext.CurrentContextPath.IsInRepeatContext = true; }
public override WTableReference ToTableReference() { Dictionary <GremlinVariableProperty, string> map = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map2 = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map3 = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map4 = new Dictionary <GremlinVariableProperty, string>(); WRepeatConditionExpression conditionExpr = GetRepeatConditionExpression(); List <WSelectScalarExpression> inputSelectList = GetInputSelectList(ref map); List <WSelectScalarExpression> outerSelectList = GetOuterSelectList(ref map); List <WSelectScalarExpression> terminateSelectList = GetConditionSelectList(ref map2); List <WSelectScalarExpression> repeatPathOuterList = GetRepeatPathOuterVariableList(ref map3); List <WSelectScalarExpression> conditionPathOuterList = GetConditionPathOuterVariableList(ref map4); WSelectQueryBlock selectQueryBlock = RepeatContext.ToSelectQueryBlock(); selectQueryBlock.SelectElements.Clear(); foreach (var selectElement in inputSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in outerSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in terminateSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in repeatPathOuterList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in conditionPathOuterList) { selectQueryBlock.SelectElements.Add(selectElement); } WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock(); foreach (var item in map) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } foreach (var item in map2) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), item.Value)); } foreach (var item in map3) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } foreach (var item in map4) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } //firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(FirstVariable.DefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); //selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(RepeatContext.PivotVariable.DefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); foreach (var property in ProjectedProperties) { if (InputVariable.ProjectedProperties.Contains(property)) { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr( InputVariable.GetVariableProperty(property).ToScalarExpression(), property)); } else { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), property)); } if (RepeatContext.PivotVariable.ProjectedProperties.Contains(property)) { selectQueryBlock.SelectElements.Add( SqlUtil.GetSelectScalarExpr( RepeatContext.PivotVariable.GetVariableProperty(property).ToScalarExpression(), property)); } else { selectQueryBlock.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), property)); } } if (SelectedVariableList.Count != 0) { foreach (var selectedVariableTuple in SelectedVariableList) { var columnName = selectedVariableTuple.Item1; var selectedVariable = selectedVariableTuple.Item2; firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), columnName)); List <WScalarExpression> compose2Paramters = new List <WScalarExpression>(); compose2Paramters.Add(selectedVariable.RealVariable.ToCompose1()); compose2Paramters.Add(SqlUtil.GetColumnReferenceExpr("R", columnName)); WFunctionCall compose2 = SqlUtil.GetFunctionCall(GremlinKeyword.func.Compose2, compose2Paramters); selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(compose2, columnName)); } } if (RepeatContext.IsPopulateGremlinPath) { var columnName = GremlinKeyword.Path; var pathVariable = RepeatContext.CurrentContextPath; firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), columnName)); selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(pathVariable.DefaultProjection().ToScalarExpression(), columnName)); } var WBinaryQueryExpression = SqlUtil.GetBinaryQueryExpr(firstQueryExpr, selectQueryBlock); ModifyColumnNameVisitor newVisitor = new ModifyColumnNameVisitor(); newVisitor.Invoke(selectQueryBlock, map); newVisitor.Invoke(conditionExpr, map2); newVisitor.Invoke(selectQueryBlock, map3); newVisitor.Invoke(conditionExpr, map4); List <WScalarExpression> repeatParameters = new List <WScalarExpression>(); repeatParameters.Add(SqlUtil.GetScalarSubquery(WBinaryQueryExpression)); repeatParameters.Add(conditionExpr); var secondTableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Repeat, repeatParameters, this, GetVariableName()); return(SqlUtil.GetCrossApplyTableReference(null, secondTableRef)); }
public RepeatContext repeat() { RepeatContext _localctx = new RepeatContext(Context, State); EnterRule(_localctx, 192, RULE_repeat); int _la; try { EnterOuterAlt(_localctx, 1); { State = 1920; k_repeat(); State = 1925; ErrorHandler.Sync(this); _la = TokenStream.La(1); while (_la==SCOL) { { { State = 1921; Match(SCOL); State = 1922; other_param(); } } State = 1927; ErrorHandler.Sync(this); _la = TokenStream.La(1); } State = 1928; Match(COL); State = 1929; integer(); State = 1930; Match(CRLF); } } catch (RecognitionException re) { _localctx.exception = re; ErrorHandler.ReportError(this, re); ErrorHandler.Recover(this, re); } finally { ExitRule(); } return _localctx; }
public override WTableReference ToTableReference() { if (RepeatContext.ContextLocalPath != null) { RepeatContext.ContextLocalPath.PathList.Insert(0, null); RepeatContext.ContextLocalPath.IsInRepeatContext = true; } //The following two variables are used for manually creating SelectScalarExpression of repeat List <WSelectScalarExpression> repeatFirstSelect = new List <WSelectScalarExpression>(); List <WSelectScalarExpression> repeatSecondSelect = new List <WSelectScalarExpression>(); // The following two variables are used for Generating a Map // such as N_0.id -> key_0 // Then we will use this map to replace ColumnRefernceExpression in the syntax tree which matchs n_0.id to R_0.key_0 Dictionary <WColumnReferenceExpression, string> repeatVistorMap = new Dictionary <WColumnReferenceExpression, string>(); Dictionary <WColumnReferenceExpression, string> conditionVistorMap = new Dictionary <WColumnReferenceExpression, string>(); //We should generate the syntax tree firstly //Some variables will populate ProjectProperty only when we call the ToTableReference function where they appear. WRepeatConditionExpression repeatConditionExpr = GetRepeatConditionExpression(); WSelectQueryBlock repeatQueryBlock = RepeatContext.ToSelectQueryBlock(); // TODO: explain this step in detail var repeatNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatContext); if (!repeatNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable)) { repeatNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatContext.VariableList.First(); } foreach (var pair in repeatNewToOldSelectedVarMap) { GremlinVariable newVariable = pair.Key; GremlinVariable oldVariable = pair.Value; foreach (var property in pair.Value.ProjectedProperties) { var aliasName = GenerateKey(); var firstSelectColumn = oldVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression; var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression; repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName)); repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName)); repeatVistorMap[firstSelectColumn.Copy()] = aliasName; } } if (RepeatCondition.TerminationContext != null && RepeatCondition.TerminationContext.VariableList.Count > 0) { var terminatedNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatCondition.TerminationContext); if (!terminatedNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable)) { terminatedNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatCondition.TerminationContext.VariableList.First(); } foreach (var pair in terminatedNewToOldSelectedVarMap) { GremlinVariable newVariable = pair.Key; GremlinVariable oldVariable = pair.Value; foreach (var property in oldVariable.ProjectedProperties) { var aliasName = GenerateKey(); var firstSelectColumn = RepeatCondition.StartFromContext ? oldVariable.GetVariableProperty(property).ToScalarExpression() : SqlUtil.GetValueExpr(null); var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression; repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName)); repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName)); if (RepeatCondition.StartFromContext) { conditionVistorMap[(firstSelectColumn as WColumnReferenceExpression).Copy()] = aliasName; } else { conditionVistorMap[secondSelectColumn.Copy()] = aliasName; } } } } if (RepeatCondition.EmitContext != null && RepeatCondition.EmitContext.VariableList.Count > 0) { var terminatedNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatCondition.EmitContext); if (!terminatedNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable)) { terminatedNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatCondition.EmitContext.VariableList.First(); } foreach (var pair in terminatedNewToOldSelectedVarMap) { GremlinVariable newVariable = pair.Key; GremlinVariable oldVariable = pair.Value; foreach (var property in pair.Value.ProjectedProperties) { var aliasName = GenerateKey(); var firstSelectColumn = RepeatCondition.IsEmitContext ? oldVariable.GetVariableProperty(property).ToScalarExpression() : SqlUtil.GetValueExpr(null); var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression; repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName)); repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName)); if (RepeatCondition.IsEmitContext) { conditionVistorMap[(firstSelectColumn as WColumnReferenceExpression).Copy()] = aliasName; } else { conditionVistorMap[secondSelectColumn.Copy()] = aliasName; } } } } foreach (var property in ProjectedProperties) { if (property == GremlinKeyword.Path) { repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), GremlinKeyword.Path)); repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(RepeatContext.ContextLocalPath.GetDefaultProjection().ToScalarExpression(), GremlinKeyword.Path)); continue; } WScalarExpression firstExpr = InputVariable.ProjectedProperties.Contains(property) ? InputVariable.GetVariableProperty(property).ToScalarExpression() : SqlUtil.GetValueExpr(null); WScalarExpression secondExpr = RepeatContext.PivotVariable.ProjectedProperties.Contains(property) ? RepeatContext.PivotVariable.GetVariableProperty(property).ToScalarExpression() : SqlUtil.GetValueExpr(null); repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstExpr, property)); repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondExpr, property)); } WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock(); foreach (var selectColumnExpr in repeatFirstSelect) { firstQueryExpr.SelectElements.Add(selectColumnExpr); } repeatQueryBlock = RepeatContext.ToSelectQueryBlock(); repeatQueryBlock.SelectElements.Clear(); foreach (var selectColumnExpr in repeatSecondSelect) { repeatQueryBlock.SelectElements.Add(selectColumnExpr); } //Replace N_0.id -> R_0.key_0, when N_0 is a outer variable new ModifyColumnNameVisitor().Invoke(repeatQueryBlock, repeatVistorMap); new ModifyColumnNameVisitor().Invoke(repeatConditionExpr, conditionVistorMap); List <WScalarExpression> repeatParameters = new List <WScalarExpression>() { SqlUtil.GetScalarSubquery(SqlUtil.GetBinaryQueryExpr(firstQueryExpr, repeatQueryBlock)), repeatConditionExpr }; var tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Repeat, repeatParameters, GetVariableName()); return(SqlUtil.GetCrossApplyTableReference(tableRef)); }
private void Reset() { ResetGroups(); fast = (repeat = null); }
private bool Eval(Mode mode, ref int ref_ptr, int pc) { int ref_ptr2 = ref_ptr; while (true) { ushort num = program[pc]; OpCode opCode = (OpCode)(num & 0xFF); OpFlags opFlags = (OpFlags)(num & 0xFF00); int num13; int num12; bool flag; int num15; int num11; RepeatContext repeatContext; int start; int count; int count2; switch (opCode) { default: continue; case OpCode.Anchor: { num13 = program[pc + 1]; num12 = program[pc + 2]; flag = ((opFlags & OpFlags.RightToLeft) != OpFlags.None); num11 = ((!flag) ? (ref_ptr2 + num12) : (ref_ptr2 - num12)); num15 = text_end - match_min + num12; int num16 = 0; OpCode opCode3 = (OpCode)(program[pc + 3] & 0xFF); if (opCode3 == OpCode.Position && num13 == 6) { switch (program[pc + 4]) { case 2: break; case 3: goto IL_0165; case 4: goto IL_0234; default: goto end_IL_0028; } if (flag || num12 == 0) { if (flag) { ref_ptr2 = num12; } if (TryMatch(ref ref_ptr2, pc + num13)) { goto case OpCode.True; } break; } break; } if (qs != null || (opCode3 == OpCode.String && num13 == 6 + program[pc + 4])) { bool flag4 = (ushort)(program[pc + 3] & 0x400) != 0; if (qs == null) { bool ignore = (ushort)(program[pc + 3] & 0x200) != 0; string @string = GetString(pc + 3); qs = new QuickSearch(@string, ignore, flag4); } while ((flag && num11 >= num16) || (!flag && num11 <= num15)) { if (flag4) { num11 = qs.Search(text, num11, num16); if (num11 != -1) { num11 += qs.Length; } } else { num11 = qs.Search(text, num11, num15); } if (num11 < 0) { break; } ref_ptr2 = ((!flag4) ? (num11 - num12) : (num11 + num12)); if (TryMatch(ref ref_ptr2, pc + num13)) { goto case OpCode.True; } num11 = ((!flag4) ? (num11 + 1) : (num11 - 2)); } break; } if (opCode3 == OpCode.True) { while ((flag && num11 >= num16) || (!flag && num11 <= num15)) { ref_ptr2 = num11; if (TryMatch(ref ref_ptr2, pc + num13)) { goto case OpCode.True; } num11 = ((!flag) ? (num11 + 1) : (num11 - 1)); } break; } for (; (flag && num11 >= num16) || (!flag && num11 <= num15); num11 = ((!flag) ? (num11 + 1) : (num11 - 1))) { ref_ptr2 = num11; if (!Eval(Mode.Match, ref ref_ptr2, pc + 3)) { continue; } ref_ptr2 = ((!flag) ? (num11 - num12) : (num11 + num12)); if (!TryMatch(ref ref_ptr2, pc + num13)) { continue; } goto case OpCode.True; } break; } case OpCode.Position: if (!IsPosition((Position)program[pc + 1], ref_ptr2)) { break; } pc += 2; continue; case OpCode.String: { bool flag5 = (opFlags & OpFlags.RightToLeft) != OpFlags.None; bool flag6 = (opFlags & OpFlags.IgnoreCase) != OpFlags.None; int num17 = program[pc + 1]; if (flag5) { ref_ptr2 -= num17; if (ref_ptr2 < 0) { break; } } else if (ref_ptr2 + num17 > text_end) { break; } pc += 2; for (int k = 0; k < num17; k++) { char c = text[ref_ptr2 + k]; if (flag6) { c = char.ToLower(c); } if (c != program[pc++]) { goto end_IL_0028; } } if (!flag5) { ref_ptr2 += num17; } continue; } case OpCode.Reference: { bool flag2 = (opFlags & OpFlags.RightToLeft) != OpFlags.None; bool flag3 = (opFlags & OpFlags.IgnoreCase) != OpFlags.None; int lastDefined2 = GetLastDefined(program[pc + 1]); if (lastDefined2 < 0) { break; } int index = marks[lastDefined2].Index; int length = marks[lastDefined2].Length; if (flag2) { ref_ptr2 -= length; if (ref_ptr2 < 0) { break; } } else if (ref_ptr2 + length > text_end) { break; } pc += 2; if (flag3) { for (int i = 0; i < length; i++) { if (char.ToLower(text[ref_ptr2 + i]) != char.ToLower(text[index + i])) { goto end_IL_0028; } } } else { for (int j = 0; j < length; j++) { if (text[ref_ptr2 + j] != text[index + j]) { goto end_IL_0028; } } } if (!flag2) { ref_ptr2 += length; } continue; } case OpCode.Character: case OpCode.Category: case OpCode.NotCategory: case OpCode.Range: case OpCode.Set: if (!EvalChar(mode, ref ref_ptr2, ref pc, multi: false)) { break; } continue; case OpCode.In: { int num10 = pc + program[pc + 1]; pc += 2; if (!EvalChar(mode, ref ref_ptr2, ref pc, multi: true)) { break; } pc = num10; continue; } case OpCode.Open: Open(program[pc + 1], ref_ptr2); pc += 2; continue; case OpCode.Close: Close(program[pc + 1], ref_ptr2); pc += 2; continue; case OpCode.BalanceStart: { int ptr = ref_ptr2; if (!Eval(Mode.Match, ref ref_ptr2, pc + 5) || !Balance(program[pc + 1], program[pc + 2], (program[pc + 3] == 1) ? true : false, ptr)) { break; } pc += program[pc + 4]; continue; } case OpCode.IfDefined: { int lastDefined = GetLastDefined(program[pc + 2]); pc = ((lastDefined >= 0) ? (pc + 3) : (pc + program[pc + 1])); continue; } case OpCode.Sub: if (!Eval(Mode.Match, ref ref_ptr2, pc + 2)) { break; } pc += program[pc + 1]; continue; case OpCode.Test: { int cp4 = Checkpoint(); int ref_ptr3 = ref_ptr2; if (Eval(Mode.Match, ref ref_ptr3, pc + 3)) { pc += program[pc + 1]; continue; } Backtrack(cp4); pc += program[pc + 2]; continue; } case OpCode.Branch: while (true) { int cp2 = Checkpoint(); if (Eval(Mode.Match, ref ref_ptr2, pc + 2)) { break; } Backtrack(cp2); pc += program[pc + 1]; if ((ushort)(program[pc] & 0xFF) == 0) { goto end_IL_0028; } } goto case OpCode.True; case OpCode.Jump: pc += program[pc + 1]; continue; case OpCode.Repeat: repeat = new RepeatContext(repeat, ReadProgramCount(pc + 2), ReadProgramCount(pc + 4), (opFlags & OpFlags.Lazy) != OpFlags.None, pc + 6); if (Eval(Mode.Match, ref ref_ptr2, pc + program[pc + 1])) { goto case OpCode.True; } repeat = repeat.Previous; break; case OpCode.Until: repeatContext = repeat; if (deep != repeatContext) { start = repeatContext.Start; count = repeatContext.Count; while (!repeatContext.IsMinimum) { repeatContext.Count++; repeatContext.Start = ref_ptr2; deep = repeatContext; if (!Eval(Mode.Match, ref ref_ptr2, repeatContext.Expression)) { goto IL_09bc; } if (deep == repeatContext) { continue; } goto case OpCode.True; } if (ref_ptr2 == repeatContext.Start) { repeat = repeatContext.Previous; deep = null; if (!Eval(Mode.Match, ref ref_ptr2, pc + 1)) { repeat = repeatContext; break; } } else if (repeatContext.IsLazy) { while (true) { repeat = repeatContext.Previous; deep = null; int cp3 = Checkpoint(); if (Eval(Mode.Match, ref ref_ptr2, pc + 1)) { break; } Backtrack(cp3); repeat = repeatContext; if (repeatContext.IsMaximum) { goto end_IL_0028; } repeatContext.Count++; repeatContext.Start = ref_ptr2; deep = repeatContext; if (!Eval(Mode.Match, ref ref_ptr2, repeatContext.Expression)) { repeatContext.Start = start; repeatContext.Count = count; goto end_IL_0028; } if (deep != repeatContext) { break; } if (ref_ptr2 == repeatContext.Start) { goto end_IL_0028; } } } else { count2 = stack.Count; while (true) { if (!repeatContext.IsMaximum) { int num14 = Checkpoint(); int value = ref_ptr2; int start2 = repeatContext.Start; repeatContext.Count++; repeatContext.Start = ref_ptr2; deep = repeatContext; if (!Eval(Mode.Match, ref ref_ptr2, repeatContext.Expression)) { repeatContext.Count--; repeatContext.Start = start2; Backtrack(num14); } else { if (deep != repeatContext) { break; } stack.Push(num14); stack.Push(value); if (ref_ptr2 != repeatContext.Start) { continue; } } } repeat = repeatContext.Previous; goto IL_0bf5; } stack.Count = count2; } } goto case OpCode.True; case OpCode.FastRepeat: { fast = new RepeatContext(fast, ReadProgramCount(pc + 2), ReadProgramCount(pc + 4), (opFlags & OpFlags.Lazy) != OpFlags.None, pc + 6); fast.Start = ref_ptr2; int cp = Checkpoint(); pc += program[pc + 1]; ushort num2 = program[pc]; int num3 = -1; int num4 = -1; int num5 = 0; OpCode opCode2 = (OpCode)(num2 & 0xFF); if (opCode2 == OpCode.Character || opCode2 == OpCode.String) { OpFlags opFlags2 = (OpFlags)(num2 & 0xFF00); if ((opFlags2 & OpFlags.Negate) == OpFlags.None) { if (opCode2 == OpCode.String) { int num6 = 0; if ((opFlags2 & OpFlags.RightToLeft) != 0) { num6 = program[pc + 1] - 1; } num3 = program[pc + 2 + num6]; } else { num3 = program[pc + 1]; } num4 = (((opFlags2 & OpFlags.IgnoreCase) == OpFlags.None) ? num3 : char.ToUpper((char)num3)); num5 = (((opFlags2 & OpFlags.RightToLeft) != 0) ? (-1) : 0); } } if (fast.IsLazy) { if (!fast.IsMinimum && !Eval(Mode.Count, ref ref_ptr2, fast.Expression)) { fast = fast.Previous; break; } while (true) { int num7 = ref_ptr2 + num5; if (num3 < 0 || (num7 >= 0 && num7 < text_end && (num3 == text[num7] || num4 == text[num7]))) { deep = null; if (Eval(Mode.Match, ref ref_ptr2, pc)) { break; } } if (fast.IsMaximum) { goto IL_0e57; } Backtrack(cp); if (Eval(Mode.Count, ref ref_ptr2, fast.Expression)) { continue; } goto IL_0e8e; } fast = fast.Previous; } else { if (!Eval(Mode.Count, ref ref_ptr2, fast.Expression)) { fast = fast.Previous; break; } int num8 = (fast.Count > 0) ? ((ref_ptr2 - fast.Start) / fast.Count) : 0; while (true) { int num9 = ref_ptr2 + num5; if (num3 < 0 || (num9 >= 0 && num9 < text_end && (num3 == text[num9] || num4 == text[num9]))) { deep = null; if (Eval(Mode.Match, ref ref_ptr2, pc)) { break; } } fast.Count--; if (fast.IsMinimum) { ref_ptr2 -= num8; Backtrack(cp); continue; } goto IL_0fab; } fast = fast.Previous; } goto case OpCode.True; } case OpCode.True: case OpCode.Balance: ref_ptr = ref_ptr2; switch (mode) { case Mode.Match: return(true); case Mode.Count: fast.Count++; if (!fast.IsMaximum && (!fast.IsLazy || !fast.IsMinimum)) { pc = fast.Expression; continue; } return(true); } break; case OpCode.False: case OpCode.Info: break; IL_0fab: fast = fast.Previous; break; IL_0234: if (num11 == scan_ptr) { ref_ptr2 = ((!flag) ? (scan_ptr - num12) : (scan_ptr + num12)); if (TryMatch(ref ref_ptr2, pc + num13)) { goto case OpCode.True; } break; } break; IL_0165: if (num11 == 0) { ref_ptr2 = 0; if (TryMatch(ref ref_ptr2, pc + num13)) { goto case OpCode.True; } num11++; } for (; (flag && num11 >= 0) || (!flag && num11 <= num15); num11 = ((!flag) ? (num11 + 1) : (num11 - 1))) { if (num11 != 0 && text[num11 - 1] != '\n') { continue; } ref_ptr2 = ((!flag) ? ((num11 != 0) ? (num11 - num12) : num11) : ((num11 != num15) ? (num11 + num12) : num11)); if (!TryMatch(ref ref_ptr2, pc + num13)) { continue; } goto case OpCode.True; } break; IL_0c31: repeat = repeatContext; break; IL_09bc: repeatContext.Start = start; repeatContext.Count = count; break; IL_0e57: fast = fast.Previous; break; IL_0e8e: fast = fast.Previous; break; IL_0bf5: while (true) { deep = null; if (Eval(Mode.Match, ref ref_ptr2, pc + 1)) { break; } if (stack.Count != count2) { repeatContext.Count--; ref_ptr2 = stack.Pop(); Backtrack(stack.Pop()); continue; } goto IL_0c31; } stack.Count = count2; goto case OpCode.True; end_IL_0028: break; } break; } switch (mode) { case Mode.Match: return(false); case Mode.Count: if (!fast.IsLazy && fast.IsMinimum) { return(true); } ref_ptr = fast.Start; return(false); default: return(false); } }
protected IExpression ConvertWithReplication(IExpression expr) { IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(expr); // Check if this is an index local variable if (baseVar == null) { return(expr); } // Check if the variable is stochastic if (!CodeRecognizer.IsStochastic(context, baseVar)) { return(expr); } if (cutVariables.Contains(baseVar)) { return(expr); } // Get the repeat context for this variable RepeatContext lc = context.InputAttributes.Get <RepeatContext>(baseVar); if (lc == null) { Error("Repeat context not found for '" + baseVar.Name + "'."); return(expr); } // Get the reference loop context for this expression var rlc = lc.GetReferenceRepeatContext(context); // If the reference is in the same loop context as the declaration, do nothing. if (rlc.repeats.Count == 0) { return(expr); } // Determine if this expression is being defined (is on the LHS of an assignment) bool isDef = Recognizer.IsBeingMutated(context, expr); Containers containers = context.InputAttributes.Get <Containers>(baseVar); for (int currentRepeat = 0; currentRepeat < rlc.repeatCounts.Count; currentRepeat++) { IExpression repeatCount = rlc.repeatCounts[currentRepeat]; IRepeatStatement repeat = rlc.repeats[currentRepeat]; // must replicate across this loop. if (isDef) { Error("Cannot re-define a variable in a repeat block."); continue; } // are we replicating the argument of Gate.Cases? IMethodInvokeExpression imie = context.FindAncestor <IMethodInvokeExpression>(); if (imie != null) { if (Recognizer.IsStaticMethod(imie, typeof(Gate), "Cases")) { Error("'if(" + expr + ")' should be placed outside 'repeat(" + repeatCount + ")'"); } if (Recognizer.IsStaticMethod(imie, typeof(Gate), "CasesInt")) { Error("'case(" + expr + ")' or 'switch(" + expr + ")' should be placed outside 'repeat(" + repeatCount + ")'"); } } VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar); IList <IStatement> stmts = Builder.StmtCollection(); List <IList <IExpression> > inds = Recognizer.GetIndices(expr); IVariableDeclaration repVar = varInfo.DeriveIndexedVariable(stmts, context, VariableInformation.GenerateName(context, varInfo.Name + "_rpt"), inds); if (!context.InputAttributes.Has <DerivedVariable>(repVar)) { context.OutputAttributes.Set(repVar, new DerivedVariable()); } if (context.InputAttributes.Has <ChannelInfo>(baseVar)) { VariableInformation repVarInfo = VariableInformation.GetVariableInformation(context, repVar); ChannelInfo ci = ChannelInfo.UseChannel(repVarInfo); ci.decl = repVar; context.OutputAttributes.Set(repVar, ci); } // set the RepeatContext of repVar to include all repeats up to this one (so that it doesn't get Entered again) List <IRepeatStatement> repeats = new List <IRepeatStatement>(lc.repeats); for (int i = 0; i <= currentRepeat; i++) { repeats.Add(rlc.repeats[i]); } context.OutputAttributes.Remove <RepeatContext>(repVar); context.OutputAttributes.Set(repVar, new RepeatContext(repeats)); // Create replicate factor Type returnType = Builder.ToType(repVar.VariableType); IMethodInvokeExpression powerPlateMethod = Builder.StaticGenericMethod( new Func <PlaceHolder, double, PlaceHolder>(PowerPlate.Enter), new Type[] { returnType }, expr, repeatCount); IExpression assignExpression = Builder.AssignExpr(Builder.VarRefExpr(repVar), powerPlateMethod); // Copy attributes across from variable to replication expression context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, powerPlateMethod); context.InputAttributes.CopyObjectAttributesTo <DivideMessages>(baseVar, context.OutputAttributes, powerPlateMethod); context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(baseVar, context.OutputAttributes, powerPlateMethod); stmts.Add(Builder.ExprStatement(assignExpression)); // add any containers missing from context. containers = new Containers(context); // remove inner repeats for (int i = currentRepeat + 1; i < rlc.repeatCounts.Count; i++) { containers = containers.RemoveOneRepeat(rlc.repeats[i]); } context.OutputAttributes.Set(repVar, containers); containers = containers.RemoveOneRepeat(repeat); containers = Containers.RemoveUnusedLoops(containers, context, powerPlateMethod); if (context.InputAttributes.Has <DoNotSendEvidence>(baseVar)) { containers = Containers.RemoveStochasticConditionals(containers, context); } //Containers shouldBeEmpty = containers.GetContainersNotInContext(context, context.InputStack.Count); //if (shouldBeEmpty.inputs.Count > 0) { Error("Internal: Variable is out of scope"); return expr; } int ancIndex = containers.GetMatchingAncestorIndex(context); Containers missing = containers.GetContainersNotInContext(context, ancIndex); stmts = Containers.WrapWithContainers(stmts, missing.inputs); // must convert the output since it may contain 'if' conditions context.AddStatementsBeforeAncestorIndex(ancIndex, stmts, true); baseVar = repVar; expr = Builder.VarRefExpr(repVar); } return(expr); }