Goto() public static method

Creates a GotoExpression representing a goto.
public static Goto ( LabelTarget target ) : GotoExpression
target LabelTarget The that the will jump to.
return GotoExpression
Ejemplo n.º 1
0
        protected override object VisitFor(For F)
        {
            target.PushScope();

            // Generate the loop header code.
            Visit(F.Init);

            string name = target.LabelName();

            LinqExprs.LabelTarget begin = LinqExpr.Label("for_" + name + "_begin");
            LinqExprs.LabelTarget end   = LinqExpr.Label("for_" + name + "_end");
            loops.Push(new Loop(LinqExpr.Goto(end), LinqExpr.Goto(begin)));

            // Check the condition, exit if necessary.
            target.Add(LinqExpr.Label(begin));
            target.Add(LinqExpr.IfThen(LinqExpr.Not(target.Compile(F.Condition)), LinqExpr.Goto(end)));

            // Generate the body code.
            Visit(F.Body);

            // Generate the step code.
            Visit(F.Step);
            target.Add(LinqExpr.Goto(begin));

            // Exit point.
            target.Add(LinqExpr.Label(end));

            loops.Pop();
            target.PopScope();

            return(null);
        }
Ejemplo n.º 2
0
        // Pseudocode:
        //string input =>
        //{
        //    R result = 0;
        //    for (int i = input.Length - 1; i >= 0; i--)
        //    {
        //        result <<= 6;
        //        var m = _invMap[input[i]];
        //        if (m == 0xff)
        //            return default(ConversionResult<R>);
        //        result += m;
        //    }
        //    return new ConversionResult<R>(result);
        //}
        private LambdaExpression fromLambda(Type to)
        {
            var stringthis = typeof(string).GetTypeInfo().DeclaredProperties.First(p => p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof(int));
            var input      = Ex.Parameter(typeof(string), "input");
            var result     = Ex.Parameter(to, "result");
            var i          = Ex.Parameter(typeof(int), "i");
            var m          = Ex.Parameter(typeof(byte), "m");
            var loopstart  = Ex.Label("loopstart");
            var end        = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var loop       = Ex.Block(
                Ex.Label(loopstart),
                Ex.IfThen(Ex.MakeBinary(ExpressionType.LessThan, i, Ex.Constant(0)),
                          Ex.Goto(end, Result(to, result))),
                Ex.LeftShiftAssign(result, Ex.Constant(6)),
                Ex.Assign(m, Ex.ArrayIndex(Ex.Constant(_invMap), Ex.Convert(Ex.MakeIndex(input, stringthis, new[] { i }), typeof(int)))),
                Ex.IfThen(Ex.MakeBinary(ExpressionType.Equal, m, Ex.Constant((byte)0xff)),
                          Ex.Goto(end, NoResult(to))),
                Ex.AddAssign(result, Ex.Convert(m, result.Type)),
                Ex.PostDecrementAssign(i),
                Ex.Goto(loopstart));
            var block = Ex.Block(new[] { result, i, m },
                                 Ex.Assign(result, Ex.Convert(Ex.Constant(0), to)),
                                 Ex.Assign(i, Ex.MakeBinary(ExpressionType.Subtract, Ex.Property(input, nameof(string.Length)), Ex.Constant(1))),
                                 loop,
                                 Ex.Label(end, NoResult(to)));

            return(Ex.Lambda(block, input));
        }
Ejemplo n.º 3
0
        private GotoExpression GotoExpression(
            ExpressionType nodeType, System.Type type, JObject obj)
        {
            var value      = this.Expression(this.Prop(obj, "value"));
            var kind       = this.Enum <GotoExpressionKind>(this.Prop(obj, "kind"));
            var targetType = this.Type(this.Prop(obj, "targetType"));
            var targetName = this.Prop(obj, "targetName").Value <string>();

            switch (kind)
            {
            case GotoExpressionKind.Break:
                return(Expr.Break(CreateLabelTarget(targetName, targetType), value));

            case GotoExpressionKind.Continue:
                return(Expr.Continue(CreateLabelTarget(targetName, targetType)));

            case GotoExpressionKind.Goto:
                return(Expr.Goto(CreateLabelTarget(targetName, targetType), value));

            case GotoExpressionKind.Return:
                return(Expr.Return(CreateLabelTarget(targetName, targetType), value));

            default:
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Generate a for loop with the given code generator functions.
        /// </summary>
        /// <param name="Init"></param>
        /// <param name="Condition"></param>
        /// <param name="Step"></param>
        /// <param name="Body"></param>
        public void For(
            Action Init,
            LinqExpr Condition,
            Action Step,
            Action <LinqExpr, LinqExpr> Body)
        {
            PushScope();

            // Generate the loop header code.
            Init();

            string name = LabelName();

            LinqExprs.LabelTarget begin = LinqExpr.Label("for_" + name + "_begin");
            LinqExprs.LabelTarget end   = LinqExpr.Label("for_" + name + "_end");

            // Check the condition, exit if necessary.
            code.Add(LinqExpr.Label(begin));
            code.Add(LinqExpr.IfThen(LinqExpr.Not(Condition), LinqExpr.Goto(end)));

            // Generate the body code.
            Body(LinqExpr.Goto(end), LinqExpr.Goto(begin));

            // Generate the step code.
            Step();
            code.Add(LinqExpr.Goto(begin));

            // Exit point.
            code.Add(LinqExpr.Label(end));

            PopScope();
        }
Ejemplo n.º 5
0
        protected override object VisitIf(If I)
        {
            string name = target.LabelName();

            LinqExprs.LabelTarget _else = LinqExpr.Label("if_" + name + "_else");
            LinqExprs.LabelTarget end   = LinqExpr.Label("if_" + name + "_end");

            // Check the condition, exit if necessary.
            target.Add(LinqExpr.IfThen(LinqExpr.Not(target.Compile(I.Condition)), LinqExpr.Goto(_else)));

            // Execute true code.
            target.PushScope();
            Visit(I.True);
            target.PopScope();
            target.Add(LinqExpr.Goto(end));

            // Execute false code.
            target.Add(LinqExpr.Label(_else));
            target.PushScope();
            Visit(I.False);
            target.PopScope();

            // Exit point.
            target.Add(LinqExpr.Label(end));
            return(null);
        }
Ejemplo n.º 6
0
        public void If(
            LinqExpr Condition,
            Action True,
            Action False)
        {
            string name = LabelName();

            LinqExprs.LabelTarget _else = LinqExpr.Label("if_" + name + "_else");
            LinqExprs.LabelTarget end   = LinqExpr.Label("if_" + name + "_end");

            // Check the condition, exit if necessary.
            code.Add(LinqExpr.IfThen(LinqExpr.Not(Condition), LinqExpr.Goto(_else)));

            // Execute true code.
            PushScope();
            True();
            PopScope();
            code.Add(LinqExpr.Goto(end));

            // Execute false code.
            code.Add(LinqExpr.Label(_else));
            PushScope();
            False();
            PopScope();

            // Exit point.
            code.Add(LinqExpr.Label(end));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Generate a while loop with the given code generator functions.
        /// </summary>
        /// <param name="Condition"></param>
        /// <param name="Body"></param>
        public void While(
            LinqExpr Condition,
            Action <LinqExpr, LinqExpr> Body)
        {
            string name = LabelName();

            LinqExprs.LabelTarget begin = LinqExpr.Label("while_" + name + "_begin");
            LinqExprs.LabelTarget end   = LinqExpr.Label("while_" + name + "_end");

            PushScope();

            // Check the condition, exit if necessary.
            code.Add(LinqExpr.Label(begin));
            code.Add(LinqExpr.IfThen(LinqExpr.Not(Condition), LinqExpr.Goto(end)));

            // Generate the body code.
            Body(LinqExpr.Goto(end), LinqExpr.Goto(begin));

            // Loop.
            code.Add(LinqExpr.Goto(begin));

            // Exit label.
            code.Add(LinqExpr.Label(end));

            PopScope();
        }
Ejemplo n.º 8
0
        private LambdaExpression toDictLambda(Type from, Type to)
        {
            var valueType = recordCreator.GetValueType(to);
            var recType   = typeof(IRecord <>).MakeGenericType(valueType);
            var set       = recType.GetTypeInfo().GetDeclaredMethod(nameof(IRecord <object> .SetValue));

            var input      = Ex.Parameter(from, "input");
            var tmp        = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(valueType), "tmp");
            var res        = Ex.Parameter(typeof(IDictionary <,>).MakeGenericType(typeof(string), valueType), "res");
            var rec        = Ex.Parameter(recType, "rec");
            var getters    = GetReadablePropertiesForType(from);
            var converters = getters.Select(g => Ref.GetLambda(g.PropertyType, valueType));

            var end   = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to));
            var block = Ex.Block(new[] { tmp, res, rec },
                                 Ex.Assign(res, Ex.New(GetParameterlessConstructor(to))),
                                 Ex.Assign(rec, recordCreator.Creator(to).ApplyTo(res)),
                                 Ex.IfThen(Ex.MakeBinary(ExpressionType.Equal, rec, Ex.Default(rec.Type)), Ex.Goto(end, NoResult(to))),
                                 Ex.Block(getters.Zip(converters, (g, c) => new { g, c })
                                          .Select(x =>
                                                  Ex.Block(
                                                      Ex.Assign(tmp, x.c.ApplyTo(Ex.Property(input, x.g))),
                                                      Ex.IfThenElse(Ex.Property(tmp, nameof(IConversionResult.IsSuccessful)),
                                                                    Ex.Call(rec, set, Ex.Constant(x.g.Name), Ex.Property(tmp, nameof(IConversionResult.Result))),
                                                                    Ex.Goto(end, NoResult(to)))))),
                                 Ex.Label(end, Result(to, Ex.Convert(res, to))));

            return(Ex.Lambda(block, input));
        }
Ejemplo n.º 9
0
        protected override object VisitDoWhile(DoWhile W)
        {
            string name = target.LabelName();

            LinqExprs.LabelTarget begin = LinqExpr.Label("do_" + name + "_begin");
            LinqExprs.LabelTarget end   = LinqExpr.Label("do_" + name + "_end");
            loops.Push(new Loop(LinqExpr.Goto(end), LinqExpr.Goto(begin)));

            target.PushScope();

            // Check the condition, exit if necessary.
            target.Add(LinqExpr.Label(begin));

            // Generate the body target.
            Visit(W.Body);

            // Loop.
            target.Add(LinqExpr.IfThen(target.Compile(W.Condition), LinqExpr.Goto(begin)));

            // Exit label.
            target.Add(LinqExpr.Label(end));

            loops.Pop();
            target.PopScope();
            return(null);
        }
        public LambdaExpression CreateLambda(Type from, Type to)
        {
            var toParameters = to.GetTypeInfo().GenericTypeArguments;
            var tupa         = toParameters.Length;
            var input        = Ex.Parameter(from, "input");
            var converters   = toParameters.Select(p => Ref.GetLambda(typeof(string), p)).ToArray();
            var res          = toParameters.Select(p => Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p))).ToArray();
            var end          = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var indexer      = typeof(string[]).GetTypeInfo().GetDeclaredProperty("Item");

            var split      = Ex.Parameter(typeof(string[]), "split");
            var conversion = Ex.Block(converters.Select((c, i) =>
                                                        Ex.Block(
                                                            Ex.Assign(res[i],
                                                                      c.ApplyTo(Ex.MakeIndex(split, indexer, new[] { Ex.MakeBinary(Et.Add, Ex.Constant(i), Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))) }))),
                                                            Ex.IfThen(Ex.Not(Ex.Property(res[i], nameof(IConversionResult.IsSuccessful))),
                                                                      Ex.Goto(end, NoResult(to))))));
            var block = Ex.Block(new[] { split },
                                 Ex.Assign(split, Ex.Call(input, nameof(string.Split), Type.EmptyTypes, _separator)),
                                 Ex.Condition(Ex.MakeBinary(Et.LessThan, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa)),
                                              NoResult(to),
                                              Ex.Block(res,
                                                       Ex.IfThen(Ex.MakeBinary(Et.GreaterThan, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa)),
                                                                 Ex.Assign(Ex.ArrayAccess(split, Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))),
                                                                           Ex.Call(typeof(string), nameof(string.Join), Type.EmptyTypes, _separatorString,
                                                                                   Ex.Call(typeof(Enumerable), nameof(Enumerable.Take), new[] { typeof(string) }, split,
                                                                                           Ex.MakeBinary(Et.Add, Ex.Constant(1), Ex.MakeBinary(Et.Subtract, Ex.Property(split, nameof(Array.Length)), Ex.Constant(tupa))))))),
                                                       conversion,
                                                       Ex.Label(end, Result(to, Ex.Call(Creator(to), res.Select(r => Ex.Property(r, nameof(IConversionResult.Result)))))))));
            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
Ejemplo n.º 11
0
 private static Ex enumeratorConversion(Type to, Ex enumerator, Type eType, LambdaExpression[] converters, Ex[] res, System.Linq.Expressions.LabelTarget end)
 {
     return(Ex.Block(res.Zip(converters, (r, con) =>
                             Ex.Block(
                                 Ex.IfThenElse(
                                     enumerator.Type.GetTypeInfo().GetDeclaredMethod(nameof(IEnumerator.MoveNext)) == null
                         ? Ex.Call(Ex.Convert(enumerator, typeof(IEnumerator)), nameof(IEnumerator.MoveNext), Type.EmptyTypes)
                         : Ex.Call(enumerator, enumerator.Type.GetTypeInfo().GetDeclaredMethod(nameof(IEnumerator.MoveNext))),
                                     Ex.Assign(r, con.ApplyTo(Ex.Property(enumerator, nameof(IEnumerator.Current)))),
                                     Ex.Goto(end, NoResult(to))),
                                 Ex.IfThen(Ex.Not(Ex.Property(r, nameof(IConversionResult.IsSuccessful))),
                                           Ex.Goto(end, NoResult(to)))))));
 }
Ejemplo n.º 12
0
        private LambdaExpression constructionLambda(Type from, Type to)
        {
            var valueType = recordCreator.GetValueType(from);
            var recType   = typeof(IRecord <>).MakeGenericType(valueType);
            var tryGet    = recType.GetTypeInfo().GetDeclaredMethod(nameof(IRecord <object> .TryGetValue));

            var input = Ex.Parameter(from, "input");
            var rec   = Ex.Parameter(recType, "rec");
            var ctor  = GetConstructorForType(to);
            var tmp   = Ex.Parameter(valueType, "tmp");
            var pars  = ctor.GetParameters().Select((p, i) => new
            {
                Converter = Ref.GetLambda(valueType, p.ParameterType),
                Var       = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p.ParameterType), p.Name),
                Type      = p.ParameterType,
                Optional  = p.GetCustomAttributes <OptionalAttribute>().Any(),
                Default   = p.HasDefaultValue ? p.DefaultValue : p.ParameterType.GetTypeInfo().IsValueType ? Activator.CreateInstance(p.ParameterType) : null
            }).ToArray();
            var end   = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var block = Ex.Block(new[] { rec }.Concat(pars.Select(x => x.Var)),
                                 Ex.Assign(rec, recordCreator.Creator(from).ApplyTo(input)),
                                 Ex.Block(new[] { tmp }, pars
                                          .Select(x =>
                                                  x.Optional
                        ? Ex.Block(
                                                      Ex.IfThenElse(
                                                          Ex.MakeBinary(ExpressionType.OrElse,
                                                                        Ex.Call(rec, tryGet, Ex.Constant(x.Var.Name), tmp),
                                                                        Ex.Call(rec, tryGet, Ex.Constant(ToPascalCase(x.Var.Name)), tmp)),
                                                          Ex.Block(
                                                              Ex.Assign(x.Var, x.Converter.ApplyTo(tmp)),
                                                              Ex.IfThen(Ex.Not(Ex.Property(x.Var, nameof(IConversionResult.IsSuccessful))),
                                                                        Ex.Goto(end, NoResult(to)))),
                                                          Ex.Assign(x.Var, Result(x.Type, Ex.Constant(x.Default, x.Type)))))
                        : Ex.Block(
                                                      Ex.IfThen(Ex.Not(Ex.Call(rec, tryGet, Ex.Constant(x.Var.Name), tmp)),
                                                                Ex.IfThen(Ex.Not(Ex.Call(rec, tryGet, Ex.Constant(ToPascalCase(x.Var.Name)), tmp)),
                                                                          Ex.Goto(end, NoResult(to)))),
                                                      Ex.Assign(x.Var, x.Converter.ApplyTo(tmp)),
                                                      Ex.IfThen(Ex.Not(Ex.Property(x.Var, nameof(IConversionResult.IsSuccessful))),
                                                                Ex.Goto(end, NoResult(to)))))),
                                 Ex.Label(end, Result(to, Ex.New(ctor, pars.Select(p => Ex.Property(p.Var, nameof(IConversionResult.Result)))))));

            return(Ex.Lambda(block, input));
        }
Ejemplo n.º 13
0
        // Pseudocode:
        //I input =>
        //{
        //  var i = (UI)input;
        //  var result = new char[base64sizeof(UI)];
        //  for (int j = 0; j == 0 || i > 0; j++)
        //  {
        //      result[j] = _mapChar[i & 0x3f];
        //      i >>= 6;
        //  }
        //}
        private LambdaExpression toLambda(Type from)
        {
            var input     = Ex.Parameter(from, "input");
            var result    = Ex.Parameter(typeof(char[]), "result");
            var i         = workingType(from) == from ? input : Ex.Parameter(workingType(from), "i");
            var j         = Ex.Parameter(typeof(int), "j");
            var loopstart = Ex.Label("loopstart");
            var loopend   = Ex.Label("loopend");

            var loop = Ex.Block(
                Ex.Label(loopstart),
                Ex.IfThen(Ex.MakeBinary(ExpressionType.AndAlso,
                                        Ex.MakeBinary(ExpressionType.GreaterThan, j, Ex.Constant(0)),
                                        i.Type == typeof(BigInteger)
                        ? (Ex)Ex.Call(i, nameof(BigInteger.Equals), Type.EmptyTypes, Ex.Constant(BigInteger.Zero))
                        : Ex.MakeBinary(ExpressionType.Equal, i, Ex.Convert(Ex.Constant(0), i.Type))),
                          Ex.Goto(loopend)),
                Ex.Assign(
                    Ex.ArrayAccess(result, j),
                    Ex.ArrayIndex(Ex.Constant(_mapChars),
                                  Ex.Convert(Ex.MakeBinary(ExpressionType.And, i, Ex.Convert(Ex.Constant(0x3f), i.Type)), typeof(int)))),
                Ex.RightShiftAssign(i, Ex.Constant(6)),
                Ex.PostIncrementAssign(j),
                Ex.Goto(loopstart));
            var ret = Result(typeof(string),
                             Ex.New(typeof(string).GetTypeInfo().DeclaredConstructors
                                    .Select(c => new { c, p = c.GetParameters() })
                                    .First(c => c.p.Length == 3 && c.p[0].ParameterType == typeof(char[]) && c.p[1].ParameterType == typeof(int) && c.p[2].ParameterType == typeof(int)).c,
                                    result, Ex.Constant(0), j));
            var block = Ex.Block(Ex.Assign(j, Ex.Constant(0)),
                                 Ex.Assign(result, Ex.NewArrayBounds(typeof(char), Ex.Constant(charbound(from)))),
                                 loop,
                                 Ex.Label(loopend),
                                 ret);

            block = input == i
                ? Ex.Block(new[] { j, result },
                           block)
                : Ex.Block(new[] { i, j, result },
                           Ex.Assign(i, Ex.Convert(input, i.Type)),
                           block);

            return(Ex.Lambda(block, input));
        }
Ejemplo n.º 14
0
            /// <summary>
            /// Creates an Entry based on the converter functions passed as a parameter.
            /// </summary>
            public static Entry Make <T, U>(IEnumerable <Tuple <LambdaExpression, Delegate> > fs)
            {
                var subs      = fs.Select(t => Tuple.Create(t.Item1, (Func <T, ConversionResult <U> >)t.Item2)).ToArray();
                var functions = subs.Select(f => f.Item2).ToArray();
                var specific  = functions.Length == 0
                    ? _ => new ConversionResult <U>()
                    : functions.Length == 1
                        ? functions[0]
                        : new Func <T, ConversionResult <U> >(i =>
                {
                    ConversionResult <U> res;
                    for (int j = 0; j < functions.Length; j++)
                    {
                        res = functions[j](i);
                        if (res.IsSuccessful)
                        {
                            return(res);
                        }
                    }
                    return(new ConversionResult <U>());
                });
                var generic = new Func <object, IConversionResult>(i => specific((T)i));
                var input   = Ex.Parameter(typeof(T), "input");
                var result  = Ex.Parameter(typeof(ConversionResult <U>), "result");
                var end     = Ex.Label(typeof(ConversionResult <U>), "end");
                var lambda  = subs.Length == 0
                    ? (Expression <Func <T, ConversionResult <U> > >)(_ => default(ConversionResult <U>))
                    : subs.Length == 1
                        ? subs[0].Item1 ?? funcToLambda(subs[0].Item2)
                        : Ex.Lambda(Ex.Block(new[] { result },
                                             Ex.Block(subs.Select(sub =>
                                                                  Ex.Block(
                                                                      Ex.Assign(result, (sub.Item1 ?? funcToLambda(sub.Item2)).ApplyTo(input)),
                                                                      Ex.IfThen(
                                                                          Ex.Property(result, nameof(IConversionResult.IsSuccessful)),
                                                                          Ex.Goto(end, result))))),
                                             Ex.Label(end, NoResult(typeof(U)))), input);

                return(new Entry(generic, specific, lambda));

                LambdaExpression funcToLambda(Func <T, ConversionResult <U> > f)
                => (Expression <Func <T, ConversionResult <U> > >)(inp => f(inp));
            }
                protected override Expression VisitGoto(GotoExpression node)
                {
                    var value = Visit(node.Value);

                    var jumpIndex = default(int);

                    if (_leaveLabels.TryGetValue(node.Target, out jumpIndex))
                    {
                        var type = typeof(void);

                        if (node.Value != null)
                        {
                            type = node.Value.Type;
                        }

                        var res = type == typeof(void) ? (Expression)Expression.Constant(null) : Expression.Convert(value, typeof(object));
                        return(Expression.Goto(_leaveLabel, Expression.New(s_leaveCtor, Expression.Constant(jumpIndex), res)));
                    }

                    return(base.VisitGoto(node));
                }
Ejemplo n.º 16
0
        private LambdaExpression createForCollection(Type from, Type to)
        {
            var cType = (from i in @from.GetTypeInfo().ImplementedInterfaces.Concat(new[] { @from })
                         where i.GetTypeInfo().IsInterface &&
                         i.GenericTypeArguments.Length == 1 &&
                         i.GetGenericTypeDefinition() == typeof(IReadOnlyCollection <>)
                         select i.GenericTypeArguments[0]).SingleOrDefault();

            if (cType == null)
            {
                return(null);
            }
            var toParameters  = to.GetTypeInfo().GenericTypeArguments;
            var input         = Ex.Parameter(from, "input");
            var getEnumerator = getGetEnumeratorMethod(from);
            var enumerator    = Ex.Parameter(getEnumerator.ReturnType, "enumerator");
            var eType         = getEnumerator.ReturnType.GetTypeInfo().GetDeclaredProperty(nameof(IEnumerator.Current)).PropertyType;
            var converters    = toParameters.Select(p => Ref.GetLambda(eType, p)).ToArray();

            var res        = toParameters.Select(p => Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p))).ToArray();
            var end        = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            Ex  conversion = enumeratorConversion(to, enumerator, eType, converters, res, end);
            var block      = Ex.Block(res.Concat(new[] { enumerator }),
                                      Ex.IfThen(
                                          Ex.MakeBinary(Et.LessThan,
                                                        Ex.Property(input, typeof(IReadOnlyCollection <>).MakeGenericType(cType).GetTypeInfo()
                                                                    .GetDeclaredProperty(nameof(IReadOnlyCollection <object> .Count))),
                                                        Ex.Constant(TupleArity(to))),
                                          Ex.Goto(end, NoResult(to))),
                                      Ex.Assign(enumerator, Ex.Call(input, getEnumerator)),
                                      typeof(IDisposable).GetTypeInfo().IsAssignableFrom(enumerator.Type.GetTypeInfo())
                    ? (Ex)Ex.TryFinally(conversion,
                                        Ex.Call(enumerator, typeof(IDisposable).GetTypeInfo().GetDeclaredMethod(nameof(IDisposable.Dispose))))
                    : conversion,
                                      Ex.Label(end, Result(to, Ex.Call(Creator(to), res.Select(r => Ex.Property(r, nameof(IConversionResult.Result)))))));

            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
Ejemplo n.º 17
0
        public Expr CompileStatement(ParseTreeNode parseNode)
        {
            switch (parseNode.Term.Name)
            {
            case "GlobalAssignment":
            case "LocalAssignment":
            case "FunctionCall":
                throw new NotImplementedException();

            case "Label":
                return(CurrentScope.RegisterJumpTarget(parseNode.ChildNodes[0].Token.Text));

            case "Goto":
                return(Expr.Goto(CurrentScope.GetJumpLabel(parseNode.ChildNodes[0].Token.Text)));

            case "Break":
                return(Expr.Break(CurrentScope.GetExitLabel()));

            case "Scope":
                return(CompileBlock(parseNode));

            case "ForLoop_Enumerable":
            case "ForLoop_Iterable":
            case "WhileLoop":
            case "RepeatLoop":
            case "IfStatement":
            case "GlobalFunction":
                throw new NotImplementedException();

            case "LocalFunction":
                return(CompileLocalFunction(parseNode));

            case "ReturnStatement":
                return(Expr.Return(CurrentScope.GetReturnLabel(), GetMultiExpressionValue(parseNode.ChildNodes[0])));

            default:
                throw new LithiumCompilerException("Unrecognized statement terminal '{0}' at {1}", parseNode.Term.Name, parseNode.Span.Location.ToUiString());
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Generate an infinite loop with the given code generator functions.
        /// </summary>
        /// <param name="Condition"></param>
        /// <param name="Body"></param>
        public void Loop(Action <LinqExpr, LinqExpr> Body)
        {
            string name = LabelName();

            LinqExprs.LabelTarget begin = LinqExpr.Label("while_" + name + "_begin");
            LinqExprs.LabelTarget end   = LinqExpr.Label("while_" + name + "_end");

            PushScope();

            code.Add(LinqExpr.Label(begin));

            // Generate the body code.
            Body(LinqExpr.Goto(end), LinqExpr.Goto(begin));

            // Loop.
            code.Add(LinqExpr.Goto(begin));

            // Exit label.
            code.Add(LinqExpr.Label(end));

            PopScope();
        }
            private Expression RewriteHandler(Expression body)
            {
                //
                // 1. Get accessors to the resulting Value and Index.
                //
                var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value");

                //
                // 2. Compute gotos that leave the body.
                //
                var gotoScanner = new GotoScanner(_labelScanner.Labels);

                gotoScanner.Visit(body);

                //
                // 3. Rewrite body.
                //
                var leaveLabel = Expression.Label(typeof(LeaveHandlerData));
                var rewriter   = new Rewriter(leaveLabel, gotoScanner.LeaveLabels);
                var newBody    = rewriter.Rewrite(body);

                //
                // 4. Create dispatch table.
                //
                if (gotoScanner.LeaveLabels.Count > 0)
                {
                    _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv =>
                    {
                        var index = Expression.Constant(kv.Value);
                        var label = kv.Key;
                        var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type);
                        var jump  = Expression.Goto(label, value);
                        return(Expression.SwitchCase(jump, index));
                    }));
                }

                return(newBody);
            }
Ejemplo n.º 20
0
        private LambdaExpression createForList(Type from, Type to)
        {
            var cType = (from i in @from.GetTypeInfo().ImplementedInterfaces.Concat(new[] { @from })
                         where i.GetTypeInfo().IsInterface &&
                         i.GenericTypeArguments.Length == 1 &&
                         i.GetGenericTypeDefinition() == typeof(IReadOnlyList <>)
                         select i.GenericTypeArguments[0]).SingleOrDefault();

            if (cType == null)
            {
                return(null);
            }
            var indexer      = typeof(IReadOnlyList <>).MakeGenericType(cType).GetTypeInfo().GetDeclaredProperty("Item");
            var count        = typeof(IReadOnlyCollection <>).MakeGenericType(cType).GetTypeInfo().GetDeclaredProperty(nameof(IReadOnlyCollection <object> .Count));
            var toParameters = to.GetTypeInfo().GenericTypeArguments;
            var input        = Ex.Parameter(from, "input");
            var converters   = toParameters.Select(p => Ref.GetLambda(cType, p)).ToArray();
            var res          = toParameters.Select(p => Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p))).ToArray();
            var end          = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");

            var conversion = Ex.Block(converters.Select((c, i) =>
                                                        Ex.Block(
                                                            Ex.Assign(res[i],
                                                                      c.ApplyTo(Ex.MakeIndex(input, indexer, new[] { Ex.Constant(i) }))),
                                                            Ex.IfThen(Ex.Not(Ex.Property(res[i], nameof(IConversionResult.IsSuccessful))),
                                                                      Ex.Goto(end, NoResult(to))))));
            var block = Ex.Block(res,
                                 Ex.IfThen(
                                     Ex.MakeBinary(Et.LessThan,
                                                   Ex.Property(input, count),
                                                   Ex.Constant(toParameters.Length)),
                                     Ex.Goto(end, NoResult(to))),
                                 conversion,
                                 Ex.Label(end, Result(to, Ex.Call(Creator(to), res.Select(r => Ex.Property(r, nameof(IConversionResult.Result)))))));
            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
Ejemplo n.º 21
0
        private LambdaExpression setterLambda(Type from, Type to)
        {
            var valueType = recordCreator.GetValueType(from);
            var recType   = typeof(IRecord <>).MakeGenericType(valueType);
            var tryGet    = recType.GetTypeInfo().GetDeclaredMethod(nameof(IRecord <object> .TryGetValue));

            var input   = Ex.Parameter(from, "input");
            var rec     = Ex.Parameter(recType, "rec");
            var tmp     = Ex.Parameter(valueType, "tmp");
            var ctor    = GetParameterlessConstructor(to);
            var setters = GetWritablePropertiesForType(to);
            var res     = Ex.Parameter(to, "res");
            var pars    = setters.Select((p, i) => new
            {
                Converter = Ref.GetLambda(valueType, p.PropertyType),
                Var       = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(p.PropertyType), p.Name)
            }).ToArray();
            var end   = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var block = Ex.Block(new[] { tmp, res, rec }.Concat(pars.Select(x => x.Var)),
                                 Ex.Assign(res, Ex.New(ctor)),
                                 Ex.Assign(rec, recordCreator.Creator(from).ApplyTo(input)),
                                 Ex.Block(pars
                                          .Select(x =>
                                                  Ex.Block(
                                                      Ex.IfThen(
                                                          Ex.MakeBinary(ExpressionType.OrElse,
                                                                        Ex.Call(rec, tryGet, Ex.Constant(x.Var.Name), tmp),
                                                                        Ex.Call(rec, tryGet, Ex.Constant(ToCamelCase(x.Var.Name)), tmp)),
                                                          Ex.Block(
                                                              Ex.Assign(x.Var, x.Converter.ApplyTo(tmp)),
                                                              Ex.IfThenElse(Ex.Property(x.Var, nameof(IConversionResult.IsSuccessful)),
                                                                            Ex.Assign(Ex.Property(res, x.Var.Name), Ex.Property(x.Var, nameof(IConversionResult.Result))),
                                                                            Ex.Goto(end, NoResult(to)))))))),
                                 Ex.Label(end, Result(to, res)));

            return(Ex.Lambda(block, input));
        }
        public LambdaExpression CreateLambda(Type from, Type to)
        {
            var input          = Ex.Parameter(from, "input");
            var eType          = to.GetElementType();
            var res            = Ex.Parameter(typeof(ConversionResult <>).MakeGenericType(eType).MakeArrayType(), "res");
            var end            = Ex.Label(typeof(ConversionResult <>).MakeGenericType(to), "end");
            var fromParameters = from.GetTypeInfo().GenericTypeArguments;
            var converters     = fromParameters.Select(t => new { Lambda = Ref.GetLambda(t, eType), Input = t }).ToArray();

            var block = Ex.Block(new[] { res },
                                 Ex.Assign(res, Ex.NewArrayBounds(typeof(ConversionResult <>).MakeGenericType(eType), Ex.Constant(fromParameters.Length))),
                                 Ex.Block(converters.Select((con, i) =>
                                                            Ex.Block(
                                                                Ex.Assign(Ex.ArrayAccess(res, Ex.Constant(i)), con.Lambda.ApplyTo(Ex.PropertyOrField(input, $"Item{i + 1}"))),
                                                                Ex.IfThen(Ex.Not(Ex.Property(Ex.ArrayIndex(res, Ex.Constant(i)), nameof(IConversionResult.IsSuccessful))),
                                                                          Ex.Goto(end, NoResult(to)))))),
                                 Ex.Label(end, Result(to,
                                                      Ex.NewArrayInit(eType,
                                                                      Enumerable.Range(0, fromParameters.Length)
                                                                      .Select(idx => Ex.Property(Ex.ArrayIndex(res, Ex.Constant(idx)), nameof(IConversionResult.Result)))))));
            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
Ejemplo n.º 23
0
 public override SysExpr ToExpression() => SysExpr.Goto(Target, Value.ToExpression(), Type);
Ejemplo n.º 24
0
        static void Main()
        {
            var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("bar"), AssemblyBuilderAccess.Save);
            var mod = asm.DefineDynamicModule("bar.dll");
            var typ = mod.DefineType("Foo");

            var lblRet = Expression.Label(typeof(int));
            var lbl1   = Expression.Label(typeof(int));
            var ex     = Expression.Parameter(typeof(Exception));

            var expressions = new Expression[]
            {
                Expression.TryFault(
                    Expression.Constant(1),
                    Expression.Constant(2)
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Goto(lblRet, Expression.Constant(1)),
                        Expression.Constant(2)
                        ),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Block(
                            Expression.Goto(lblRet, Expression.Constant(1)),
                            Expression.Constant(2)
                            ),
                        Expression.Constant(3)
                        ),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Block(
                            Expression.Goto(lbl1, Expression.Constant(1)),
                            Expression.Goto(lblRet, Expression.Constant(2))
                            ),
                        Expression.Constant(3)
                        ),
                    Expression.Label(lbl1, Expression.Constant(-1)),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.TryCatch(
                    Expression.Constant(1),
                    Expression.Catch(ex, Expression.Constant(2), Expression.Constant(true))
                    ),
            };

            var i = 0;

            foreach (var expression in expressions)
            {
                var mtd = typ.DefineMethod("M" + i, MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]);
                Expression.Lambda <Func <int> >(expression).CompileToMethod(mtd);

                var cw = Expression.Lambda <Func <int> >(expression).CompileWithExceptionHandling();
                cw();

                i++;
            }
        }