Exemplo n.º 1
0
        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));
        }
Exemplo n.º 3
0
    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);
    }
Exemplo n.º 4
0
 internal override void PopulateLocalPath()
 {
     if (ProjectedProperties.Contains(GremlinKeyword.Path))
     {
         return;
     }
     ProjectedProperties.Add(GremlinKeyword.Path);
     RepeatContext.PopulateLocalPath();
 }
Exemplo n.º 5
0
 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);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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);
            }
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 12
0
        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");
            }
        }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
 internal override void PopulateGremlinPath()
 {
     RepeatContext.PopulateGremlinPath();
     RepeatContext.CurrentContextPath.IsInRepeatContext = true;
 }
Exemplo n.º 16
0
        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));
        }
Exemplo n.º 17
0
	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;
	}
Exemplo n.º 18
0
        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));
        }
Exemplo n.º 19
0
 private void Reset()
 {
     ResetGroups();
     fast = (repeat = null);
 }
Exemplo n.º 20
0
        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);
            }
        }
Exemplo n.º 21
0
        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);
        }