예제 #1
0
 private CodeVariableReferenceExpression GenSymLocalTuple()
 {
     return(gensym.GenSymLocal("_tup_", new CodeTypeReference(typeof(object))));
 }
예제 #2
0
        public CodeExpression VisitApplication(Application appl)
        {
            Debug.Print("appl: {0}", appl.fn);
            var fn   = appl.fn.Accept(this);
            var args = TranslateArgs(appl).ToArray();

            if (fn is CodeVariableReferenceExpression id)
            {
                if (id.Name == "isinstance" && appl.args.Count == 2)
                {
                    return(TranslateIsinstance(appl));
                }
                if (id.Name == "int")
                {
                    m.EnsureImport("System");
                    fn = m.MethodRef(m.TypeRefExpr("Convert"), "ToInt32");
                }
                if (id.Name == "list")
                {
                    if (args.Length == 0)
                    {
                        m.EnsureImport("System.Collections.Generic");
                        return(m.New(m.TypeRef("List", "object")));
                    }
                    if (args.Length == 1)
                    {
                        m.EnsureImport("System.Linq");
                        fn = m.MethodRef(args[0], "ToList");
                        return(m.Appl(fn));
                    }
                }
                if (id.Name == "set")
                {
                    if (args.Length == 0 || args.Length == 1)
                    {
                        m.EnsureImport("System.Collections.Generic");
                        return(m.New(
                                   m.TypeRef("HashSet", "object"),
                                   args));
                    }
                }
                if (id.Name == "dict")
                {
                    if (args.Length == 0)
                    {
                        m.EnsureImport("System.Collections.Generic");
                        return(m.New(
                                   m.TypeRef("Dictionary", "object", "object")));
                    }
                    else if (args.All(a => a is CodeNamedArgument))
                    {
                        m.EnsureImport("System.Collections.Generic");
                        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("System.Collections.Generic");
                        return(m.Appl(m.MethodRef(args[0], "ToDictionary")));
                    }
                }
                if (id.Name == "len")
                {
                    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"));
                    }
                }
                if (id.Name == "sum")
                {
                    if (args.Length == 1)
                    {
                        m.EnsureImport("System.Linq");
                        var arg = args[0];
                        args = new CodeExpression[0];
                        fn   = m.Access(arg, "Sum");
                    }
                }
                if (id.Name == "filter")
                {
                    if (args.Length == 2)
                    {
                        m.EnsureImport("System.Collections.Generic");
                        m.EnsureImport("System.Linq");
                        var filter = args[0];
                        if (appl.args[0].defval is NoneExp)
                        {
                            var formal = gensym.GenSymLocal("_p_", m.TypeRef("object"));
                            filter = m.Lambda(
                                new[] { formal },
                                m.BinOp(formal, CodeOperatorType.NotEqual, m.Prim(null)));
                        }
                        fn = m.MethodRef(
                            m.Appl(m.MethodRef(args[1], "Where"), filter),
                            "ToList");
                        args = new CodeExpression[0];
                    }
                }
                if (id.Name == "sorted")
                {
                    return(TranslateSorted(args));
                }
                if (id.Name == "enumerate")
                {
                    if (args.Length == 1)
                    {
                        var p = gensym.GenSymLocal("_p_", m.TypeRef("object"));
                        var i = gensym.GenSymLocal("_p_", m.TypeRef("int"));
                        return(m.ApplyMethod(
                                   args[0],
                                   "Select",
                                   m.Lambda(
                                       new[] { p, i },
                                       m.ApplyMethod(m.TypeRefExpr("Tuple"), "Create", i, p))));
                    }
                }
            }
            else
            {
                if (fn is CodeFieldReferenceExpression field)
                {
                    var specialTranslator = GetSpecialTranslator(field);
                    if (specialTranslator != null)
                    {
                        var special = specialTranslator(m, field, args);
                        if (special != null)
                        {
                            return(special);
                        }
                    }

                    if (field.FieldName == "iteritems")
                    {
                        if (args.Length == 0)
                        {
                            // iteritems is Python 2.x returning an iterable over
                            // a dictionary's key-value pairs. In C#, just return
                            // the dictionary (assumes that we're dealing with a dictionary!)
                        }
                        return(field.Expression);
                    }
                    else if (field.FieldName == "itervalues")
                    {
                        if (args.Length == 0)
                        {
                            return(m.Access(field.Expression, "Values"));
                        }
                    }
                    else if (field.FieldName == "iterkeys")
                    {
                        if (args.Length == 0)
                        {
                            return(m.Access(field.Expression, "Keys"));
                        }
                    }
                }
            }
            return(m.Appl(fn, args));
        }