Exemplo n.º 1
0
        public CodeExpression VisitLambda(Lambda l)
        {
            var e = new CodeLambdaExpression(
                l.args.Select(a => a.name.Accept(this)).ToArray(),
                l.body.Accept(this));

            return(e);
        }
Exemplo n.º 2
0
            /// <summary>
            /// Rewrites the lambda expression.
            /// </summary>
            /// <param name="lambdaExpression">The lambda expression to rewrite.</param>
            /// <returns>Expression rewritten as code snippet</returns>
            private CodeSnippetExpression RewriteLambdaExpression(CodeLambdaExpression lambdaExpression)
            {
                using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
                {
                    if (lambdaExpression.Parameters.Count == 1 && lambdaExpression.Parameters[0].Type is CodeImplicitTypeReference)
                    {
                        sw.Write(this.generator.CreateEscapedIdentifier(lambdaExpression.Parameters[0].Name));
                    }
                    else
                    {
                        sw.Write("(");
                        string separator = string.Empty;
                        foreach (CodeParameterDeclarationExpression cpde in lambdaExpression.Parameters)
                        {
                            sw.Write(separator);
                            separator = ", ";
                            if (!(cpde.Type is CodeImplicitTypeReference))
                            {
                                this.generator.GenerateCodeFromExpression(cpde, sw, null);
                            }
                            else
                            {
                                sw.Write(this.generator.CreateEscapedIdentifier(cpde.Name));
                            }
                        }

                        sw.Write(")");
                    }

                    sw.Write(" => ");
                    bool didRewrite = false;
                    if (lambdaExpression.BodyStatements.Count > 0)
                    {
                        sw.WriteLine();
                        this.WriteIndentation(sw);
                        sw.WriteLine("{");
                        this.nestingLevel++;
                        foreach (CodeStatement stat in lambdaExpression.BodyStatements)
                        {
                            this.WriteIndentation(sw);
                            this.generator.GenerateCodeFromStatement(this.Rewrite(stat, ref didRewrite), sw, null);
                        }

                        this.nestingLevel--;
                        this.WriteIndentation(sw);
                        sw.Write("}");
                        didRewrite = true;
                    }
                    else
                    {
                        this.generator.GenerateCodeFromExpression(this.Rewrite(lambdaExpression.Body, ref didRewrite), sw, null);
                    }

                    return(new CodeSnippetExpression(sw.ToString()));
                }
            }
Exemplo n.º 3
0
            private CodeExpression RewriteLambdaExpression(CodeLambdaExpression lambdaExpression, ref bool didRewrite)
            {
                // This is a workaround for CodeDomTreeRewriter which does not handle CodeLambdaExpression in the case when
                // expressions further down the tree have been rewritten. (the lambda is rewritten as an empty CodeObject).
                var body = this.Rewrite(lambdaExpression.Body, ref didRewrite);

                if (didRewrite)
                {
                    var parameters = lambdaExpression.Parameters.Cast <CodeParameterDeclarationExpression>().Select(e => e.Name).ToArray();
                    var result     = new CodeLambdaExpression().WithParameters(parameters).WithBody(body);
                    return(result);
                }

                return(lambdaExpression);
            }
Exemplo n.º 4
0
            /// <summary>
            /// Rewrites CodeExpression
            /// </summary>
            /// <param name="e">A CodeExpression to be rewritten.</param>
            /// <param name="didRewrite">A value which will be set to true if the rewriting returned a new object.</param>
            /// <returns>Rewritten CodeExpression.</returns>
            protected override CodeExpression Rewrite(CodeExpression e, ref bool didRewrite)
            {
                CodeLambdaExpression lambdaExpression = e as CodeLambdaExpression;

                if (lambdaExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteLambdaExpression(lambdaExpression));
                }

                CodeQueryExpression queryExpression = e as CodeQueryExpression;

                if (queryExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteComprehensionExpression(queryExpression));
                }

                CodeCreateAndInitializeObjectExpression objectCreateExpression = e as CodeCreateAndInitializeObjectExpression;

                if (objectCreateExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteCreateAndInitializeObjectExpression(objectCreateExpression));
                }

                CodeArrayInitializerExpression arrayInitializer = e as CodeArrayInitializerExpression;

                if (arrayInitializer != null)
                {
                    didRewrite = true;
                    return(this.RewriteArrayInitializerExpression(arrayInitializer));
                }

                CodeExclusiveOrExpression exclusiveOrExpression = e as CodeExclusiveOrExpression;

                if (exclusiveOrExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteExclusiveOrExpression(exclusiveOrExpression));
                }

                CodeAsExpression asExpression = e as CodeAsExpression;

                if (asExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteAsExpression(asExpression));
                }

                CodeIsExpression isExpression = e as CodeIsExpression;

                if (isExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteIsExpression(isExpression));
                }

                CodePrimitiveExpression primitiveExpression = e as CodePrimitiveExpression;

                if (primitiveExpression != null)
                {
                    return(this.RewritePrimitiveExpression(primitiveExpression, ref didRewrite));
                }

                var ternaryExpression = e as CodeTernaryExpression;

                if (ternaryExpression != null)
                {
                    didRewrite = true;
                    return(this.RewriteTernaryExpression(ternaryExpression));
                }

                var anonymousArray = e as CodeAnonymousArrayExpression;

                if (anonymousArray != null)
                {
                    didRewrite = true;
                    return(this.RewriteAnonymousArrayExpression(anonymousArray));
                }

                return(base.Rewrite(e, ref didRewrite));
            }
Exemplo n.º 5
0
        CodeExpression Translate_range(Application appl, CodeExpression[] args)
        {
            var argsCount = args.Length;

            if (1 <= argsCount && argsCount <= 3)
            {
                m.EnsureImport("System");
                m.EnsureImport("System.Linq");

                var enumerableRange = m.MethodRef(m.TypeRefExpr("Enumerable"), "Range");
                var mathCeiling     = m.MethodRef(m.TypeRefExpr("Math"), "Ceiling");
                var convertToInt32  = m.MethodRef(m.TypeRefExpr("Convert"), "ToInt32");
                var convertToDouble = m.MethodRef(m.TypeRefExpr("Convert"), "ToDouble");

                switch (argsCount)
                {
                case 1:
                {
                    // Enumerable.Range(0, count);

                    var startExp = m.Prim(0);
                    var countExp = args[0];

                    return(m.Appl(enumerableRange, startExp, countExp));
                }

                case 2:
                {
                    // Enumerable.Range(0, count);

                    var startExp = args[0];
                    var stopExp  = args[1];
                    var countExp = m.Sub(stopExp, startExp);

                    return(m.Appl(enumerableRange, startExp, countExp));
                }

                case 3:
                {
                    // Enumerable.Range(0, count).Select(x => start + x * step);

                    var startExp = args[0];
                    var stopExp  = args[1];
                    var stepExp  = args[2];

                    // count = (stop - start) divide_ceiling_by step;
                    var rawCountExp       = m.Sub(stopExp, startExp);
                    var rawDoubleCountExp = m.Appl(convertToDouble, rawCountExp);
                    var countDividedExp   = m.Div(rawDoubleCountExp, stepExp);
                    var countCeilingExp   = m.Appl(mathCeiling, countDividedExp);
                    var countExp          = m.Appl(convertToInt32, countCeilingExp);

                    // Enumerable.Range(0, count);
                    var rangeExp = m.Appl(enumerableRange, m.Prim(0), countExp);

                    // x => start + x * step;
                    var lambdaArgExp = expTranslator.gensym.GenSymLocal("_x_", m.TypeRef("object"));
                    var offsetExp    = m.Mul(lambdaArgExp, stepExp);
                    var positionExp  = m.Add(startExp, offsetExp);
                    var mapLambdaExp = new CodeLambdaExpression(new CodeExpression[] { lambdaArgExp }, positionExp);


                    var selectExt = m.Access(rangeExp, "Select");

                    return(m.Appl(selectExt, mapLambdaExp));
                }
                }
            }

            return(null);
        }
Exemplo n.º 6
0
 public void VisitLambda(CodeLambdaExpression l)
 {
     if (l.Arguments.Length == 1)
     {
         l.Arguments[0].Accept(this);
     }
     else
     {
         writer.Write("(");
         var sep = "";
         foreach (var arg in l.Arguments)
         {
             writer.Write(sep);
             sep = ",";
             arg.Accept(this);
         }
         writer.Write(")");
     }
     writer.Write(" =>");
     if (l.Body != null)
     {
         writer.Write(" ");
         l.Body.Accept(this);
     }
     else
     {
         var sw = new CSharpStatementWriter(writer);
         sw.WriteStatements(l.Statements);
     }
 }
Exemplo n.º 7
0
        CodeExpression?Translate_isinstance(Application appl, CodeExpression[] args)
        {
            if (appl.args.Count != 2)
            {
                return(null);
            }
            List <Exp> types;

            if (appl.args[1].defval is PyTuple tuple)
            {
                types = tuple.values.ToList();
            }
            else
            {
                types = new List <Exp> {
                    appl.args[1].defval !
                };
            }

            var exp = appl.args[0].defval !.Accept(expTranslator);

            return(types.
                   Select(t => m.BinOp(
                              exp,
                              CodeOperatorType.Is,
                              m.TypeRefExpr(t.ToString())))
                   .Aggregate((a, b) => m.BinOp(a, CodeOperatorType.LogOr, b)));
        }

        CodeExpression Translate_int(Application appl, CodeExpression[] args)
        {
            m.EnsureImport("System");
            var fn = m.MethodRef(m.TypeRefExpr("Convert"), "ToInt32");

            return(m.Appl(fn, args));
        }

        CodeExpression?Translate_list(Application appl, CodeExpression[] args)
        {
            if (args.Length == 0)
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                return(m.New(m.TypeRef("List", "object")));
            }
            if (args.Length == 1)
            {
                m.EnsureImport(TypeReferenceTranslator.LinqNamespace);
                var fn = m.MethodRef(args[0], "ToList");
                return(m.Appl(fn));
            }
            return(null);
        }

        CodeExpression?Translate_set(Application appl, CodeExpression[] args)
        {
            if (args.Length == 0 || args.Length == 1)
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                return(m.New(
                           m.TypeRef("HashSet", "object"),
                           args));
            }
            return(null);
        }

        CodeExpression?Translate_dict(Application appl, CodeExpression[] args)
        {
            if (args.Length == 0)
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                return(m.New(
                           m.TypeRef("Dictionary", "object", "object")));
            }
            else if (args.All(a => a is CodeNamedArgument))
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                var exp = m.New(
                    m.TypeRef("Dictionary", "string", "object"));
                exp.Initializer = new CodeCollectionInitializer(
                    args.Cast <CodeNamedArgument>()
                    .Select(a =>
                            new CodeCollectionInitializer(
                                m.Prim(
                                    ((CodeVariableReferenceExpression)a.exp1).Name),
                                a.exp2 !))
                    .ToArray());
                return(exp);
            }
            else if (args.Length == 1)
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                return(m.Appl(m.MethodRef(args[0], "ToDictionary")));
            }
            return(null);
        }

        CodeExpression?Translate_len(Application appl, CodeExpression[] args)
        {
            if (args.Length == 1)
            {
                var arg = args[0];
                //$TODO: if args is known to be an iterable, but not a collection,
                // using LinQ Count() instead?
                return(m.Access(arg, "Count"));
            }
            return(null);
        }

        CodeExpression?Translate_sum(Application appl, CodeExpression[] args)
        {
            if (args.Length == 1)
            {
                m.EnsureImport(TypeReferenceTranslator.LinqNamespace);
                var arg = args[0];
                args = new CodeExpression[0];
                var fn = m.Access(arg, "Sum");
                return(m.Appl(fn, args));
            }
            return(null);
        }

        CodeExpression?Translate_range(Application appl, CodeExpression[] args)
        {
            var argsCount = args.Length;

            if (1 <= argsCount && argsCount <= 3)
            {
                m.EnsureImport("System");
                m.EnsureImport("System.Linq");

                var enumerableRange = m.MethodRef(m.TypeRefExpr("Enumerable"), "Range");
                var mathCeiling     = m.MethodRef(m.TypeRefExpr("Math"), "Ceiling");
                var convertToInt32  = m.MethodRef(m.TypeRefExpr("Convert"), "ToInt32");
                var convertToDouble = m.MethodRef(m.TypeRefExpr("Convert"), "ToDouble");

                switch (argsCount)
                {
                case 1:
                {
                    // Enumerable.Range(0, count);

                    var startExp = m.Prim(0);
                    var countExp = args[0];

                    return(m.Appl(enumerableRange, startExp, countExp));
                }

                case 2:
                {
                    // Enumerable.Range(0, count);

                    var startExp = args[0];
                    var stopExp  = args[1];
                    var countExp = m.Sub(stopExp, startExp);

                    return(m.Appl(enumerableRange, startExp, countExp));
                }

                case 3:
                {
                    // Enumerable.Range(0, count).Select(x => start + x * step);

                    var startExp = args[0];
                    var stopExp  = args[1];
                    var stepExp  = args[2];

                    // count = (stop - start) divide_ceiling_by step;
                    var rawCountExp       = m.Sub(stopExp, startExp);
                    var rawDoubleCountExp = m.Appl(convertToDouble, rawCountExp);
                    var countDividedExp   = m.Div(rawDoubleCountExp, stepExp);
                    var countCeilingExp   = m.Appl(mathCeiling, countDividedExp);
                    var countExp          = m.Appl(convertToInt32, countCeilingExp);

                    // Enumerable.Range(0, count);
                    var rangeExp = m.Appl(enumerableRange, m.Prim(0), countExp);

                    // x => start + x * step;
                    var lambdaArgExp = expTranslator.gensym.GenSymLocal("_x_", m.TypeRef("object"));
                    var offsetExp    = m.Mul(lambdaArgExp, stepExp);
                    var positionExp  = m.Add(startExp, offsetExp);
                    var mapLambdaExp = new CodeLambdaExpression(new CodeExpression[] { lambdaArgExp }, positionExp);


                    var selectExt = m.Access(rangeExp, "Select");

                    return(m.Appl(selectExt, mapLambdaExp));
                }
                }
            }

            return(null);
        }

        CodeExpression?Translate_filter(Application appl, CodeExpression[] args)
        {
            if (args.Length == 2)
            {
                m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
                m.EnsureImport(TypeReferenceTranslator.LinqNamespace);
                var filter = args[0];
                if (appl.args[0].defval is NoneExp)
                {
                    var formal = expTranslator.gensym.GenSymLocal("_p_", m.TypeRef("object"));
                    filter = m.Lambda(
                        new[] { formal },
                        m.BinOp(formal, CodeOperatorType.NotEqual, m.Prim(null)));
                }
                var fn = m.MethodRef(
                    m.Appl(m.MethodRef(args[1], "Where"), filter),
                    "ToList");
                args = new CodeExpression[0];
                return(m.Appl(fn, args));
            }
            return(null);
        }

        CodeExpression?Translate_complex(Application appl, CodeExpression[] args)
        {
            if (args.Length == 2)
            {
                m.EnsureImport("System.Numerics");
                return(m.New(m.TypeRef("Complex"), args));
            }
            return(null);
        }

        CodeExpression?Translate_float(Application appl, CodeExpression[] args)
        {
            if (args[0] is CodePrimitiveExpression c && c.Value is Str str)
            {
                switch (str.s)
                {
                case "inf":
                case "+inf":
                case "Infinity":
                case "+Infinity":
                    return(m.Access(m.TypeRefExpr("double"), "PositiveInfinity"));

                case "-inf":
                case "-Infinity":
                    return(m.Access(m.TypeRefExpr("double"), "NegativeInfinity"));
                }
            }
            return(null);
        }

        CodeExpression Translate_sorted(Application appl, CodeExpression[] args)
        {
            if (args.Length == 0)
            {
                return(m.Appl(new CodeVariableReferenceExpression("sorted"), args));
            }
            var iter = args[0];
            var cmp  = args.Length > 1 && !(args[1] is CodeNamedArgument)
                ? args[1]
                : null;
            var key = args.Length > 2 && !(args[2] is CodeNamedArgument)
                ? args[2]
                : null;
            var rev = args.Length > 3 && !(args[3] is CodeNamedArgument)
                ? args[3]
                : null;
            var namedArgs = args.OfType <CodeNamedArgument>().ToDictionary(
                k => ((CodeVariableReferenceExpression)k.exp1).Name,
                v => v.exp2);

            if (namedArgs.TryGetValue("cmp", out var tmp))
            {
                cmp = tmp;
            }
            if (namedArgs.TryGetValue("key", out tmp))
            {
                key = tmp;
            }
            if (namedArgs.TryGetValue("reverse", out tmp))
            {
                rev = tmp;
            }

            m.EnsureImport(TypeReferenceTranslator.GenericCollectionNamespace);
            var formal = expTranslator.gensym.GenSymLocal("_p_", m.TypeRef("object"));

            return(m.ApplyMethod(
                       m.ApplyMethod(
                           iter,
                           IsReverse(rev) ? "OrderByDescending" : "OrderBy",
                           cmp ?? key ?? m.Lambda(new[] { formal }, formal)),
                       "ToList"));
        }

        CodeExpression Translate_str(Application appl, CodeExpression[] args)
        {
            switch (args.Length)
            {
            case 1:
                return(m.ApplyMethod(args[0], "ToString"));

            case 2:
            case 3:
                //$TODO: careless about the third arg here.
                m.EnsureImport("System.Text");
                var getEncoding = m.ApplyMethod(
                    m.TypeRefExpr("Encoding"),
                    "GetEncoding",
                    args[1]);
                return(m.ApplyMethod(getEncoding, "GetString", args[0]));

            default:
                throw new NotImplementedException($"str({string.Join<CodeExpression>(",", args)})");
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Begins the new scope which will add statements to given lambda body.
 /// </summary>
 /// <param name="lambda">The lambda.</param>
 public abstract void BeginLambda(CodeLambdaExpression lambda);
Exemplo n.º 9
0
 /// <summary>
 /// Begins the new scope which will add statements to given lambda body.
 /// </summary>
 /// <param name="lambda">The lambda.</param>
 public override void BeginLambda(CodeLambdaExpression lambda)
 {
     this.blockStack.Push(this.currentBlock);
     this.currentBlock = new BlockInformation(null, BlockType.Lambda, lambda.BodyStatements, false);
 }