예제 #1
0
        private Expression GenerateSubstitution(Subroutine sub, RegexReplace rm)
        {
            var scalar = Expression.Variable(typeof(P5Scalar));
            var str = Expression.Variable(typeof(string));
            var replace = Expression.Variable(typeof(IP5Any));
            var init_scalar =
                Expression.Assign(scalar, Generate(sub, rm.Childs[0]));
            var init_str =
                Expression.Assign(
                    str,
                    Expression.Call(
                        scalar,
                        typeof(IP5Any).GetMethod("AsString"),
                        Runtime));

            var replace_list = new List<Expression>();

            // at this point all nested scopes have been generated
            replace_list.Add(
                Expression.Assign(replace, ValueBlocks[rm.To]));

            // replace in string
            var rxstate = Expression.Field(
                Runtime,
                typeof(Runtime).GetField("LastMatch"));

            replace_list.Add(
                Expression.Call(
                    scalar,
                    typeof(P5Scalar).GetMethod("SpliceSubstring", new[] { typeof(Runtime), typeof(int), typeof(int), typeof(IP5Any) }),
                    Runtime,
                    Expression.Field(
                        rxstate,
                        typeof(RxResult).GetField("Start")),
                    Expression.Subtract(
                        Expression.Field(
                            rxstate,
                            typeof(RxResult).GetField("End")),
                        Expression.Field(
                            rxstate,
                            typeof(RxResult).GetField("Start"))),
                    replace));

            // return true at end of replacement
            replace_list.Add(Expression.Constant(true));

            var match = Expression.Call(
                Generate(sub, rm.Childs[1]),
                typeof(IP5Regex).GetMethod("MatchString"),
                Runtime,
                str,
                Expression.Constant(-1),
                Expression.Constant(false),
                GetSavedRxState(rm.Index));
            var repl = Expression.Condition(
                match,
                Expression.Block(typeof(bool), replace_list),
                Expression.Constant(false));

            var vars = new List<ParameterExpression>();
            vars.Add(scalar);
            vars.Add(str);
            vars.Add(replace);

            var exps = new List<Expression>();
            exps.Add(init_scalar);
            exps.Add(init_str);
            exps.Add(
                Expression.New(
                    typeof(P5Scalar).GetConstructor(ProtoRuntimeBool),
                    Runtime,
                    repl));

            return Expression.Block(typeof(P5Scalar), vars, exps);
        }
예제 #2
0
        private Expression GenerateGlobalSubstitution(Subroutine sub, RegexReplace rm)
        {
            var scalar = Expression.Variable(typeof(P5Scalar));
            var init_scalar =
                Expression.Assign(scalar, Generate(sub, rm.Childs[0]));
            var pos = Expression.Variable(typeof(int));
            var count = Expression.Variable(typeof(int));
            var matched = Expression.Variable(typeof(bool));
            var str = Expression.Variable(typeof(string));
            var replace = Expression.Variable(typeof(string));
            var repl_list = Expression.Variable(typeof(List<RxReplacement>));
            var init_str =
                Expression.Assign(
                    str,
                    Expression.Call(
                        scalar,
                        typeof(IP5Any).GetMethod("AsString"),
                        Runtime));
            var match = Expression.Call(
                Generate(sub, rm.Childs[1]),
                typeof(IP5Regex).GetMethod("MatchString"),
                Runtime,
                str,
                pos,
                Expression.Constant(false),
                GetSavedRxState(rm.Index));
            var rxstate = Expression.Field(
                Runtime,
                typeof(Runtime).GetField("LastMatch"));
            var rx_end =
                Expression.Field(
                    rxstate,
                    typeof(RxResult).GetField("End"));
            var rx_start =
                Expression.Field(
                    rxstate,
                    typeof(RxResult).GetField("Start"));

            var if_match = new List<Expression>();

            if_match.Add(Expression.PreIncrementAssign(count));
            if_match.Add(Expression.Assign(matched, Expression.Constant(true)));
            if_match.Add(Expression.Assign(pos, rx_end));

            // at this point all nested scopes have been generated
            if_match.Add(Expression.Assign(
                             replace,
                             Expression.Call(
                                 ValueBlocks[rm.To],
                                 typeof(IP5Any).GetMethod("AsString"),
                                 Runtime)));

            if_match.Add(
                Expression.Call(
                    repl_list,
                    typeof(List<RxReplacement>).GetMethod("Add"),
                    Expression.New(
                        typeof(RxReplacement).GetConstructor(
                            new Type[] { typeof(string), typeof(int), typeof(int) }),
                        replace, rx_start, rx_end)));

            var break_to = Expression.Label(typeof(void));
            var loop =
                Expression.Loop(
                    Expression.Block(
                        Expression.IfThenElse(
                            match,
                            Expression.Block(typeof(void), if_match),
                            Expression.Break(break_to))),
                    break_to);

            // TODO save last match

            var vars = new List<ParameterExpression>();
            vars.Add(scalar);
            vars.Add(pos);
            vars.Add(count);
            vars.Add(matched);
            vars.Add(str);
            vars.Add(replace);
            vars.Add(repl_list);

            var body = new List<Expression>();
            body.Add(init_scalar);
            body.Add(init_str);
            body.Add(Expression.Assign(pos, Expression.Constant(-1)));
            body.Add(Expression.Assign(count, Expression.Constant(0)));
            body.Add(Expression.Assign(matched, Expression.Constant(false)));
            body.Add(Expression.Assign(
                         repl_list,
                         Expression.New(
                             typeof(List<RxReplacement>).GetConstructor(
                                 new Type[0]))));
            body.Add(loop);

            // replace substrings
            body.Add(
                Expression.Call(
                    typeof(P5Regex).GetMethod("ReplaceSubstrings"),
                    Runtime,
                    scalar,
                    str,
                    repl_list));

            // return value
            var result =
                Expression.New(
                    typeof(P5Scalar).GetConstructor(ProtoRuntimeInt),
                    Runtime,
                    count);

            body.Add(
                Expression.Condition(
                    Expression.Equal(
                        OpContext(rm),
                        Expression.Constant(Opcode.ContextValues.LIST)),
                    Expression.New(
                        typeof(P5List).GetConstructor(ProtoRuntimeAny),
                        Runtime,
                        result),
                    result, typeof(IP5Any)));

            return Expression.Block(typeof(IP5Any), vars, body);
        }