Beispiel #1
0
        public CodeExpression VisitDictComprehension(DictComprehension dc)
        {
            //{ k:copy.copy(v) for k, v in path.info.iteritems() }
            //string sExp = "path.info.iteritems.ToDictionary(k => k, v => copy.copy(v))";

            var list = dc.source.collection.Accept(this);

            switch (dc.source.variable)
            {
            case ExpList varList:
            {
                //if (varList.Expressions.Count != 2)
                //    throw new InvalidOperationException("Variable list should contain one or two variables.");
                var args = varList.Expressions.Select((e, i) => Tuple.Create(e, string.Format($"Item{i + 1}")))
                           .ToDictionary(d => d.Item1, d => d.Item2);
                var tpl = gensym.GenSymAutomatic("_tup_", null, false);

                gensym.PushIdMappings(varList.Expressions.ToDictionary(e => e.ToString(), e => m.Access(tpl, args[e])));

                var kValue = dc.key.Accept(this);
                var vValue = dc.value.Accept(this);

                gensym.PopIdMappings();

                return(m.Appl(
                           m.MethodRef(list, "ToDictionary"),
                           m.Lambda(new CodeExpression[] { tpl }, kValue),
                           m.Lambda(new CodeExpression[] { tpl }, vValue)));
            }

            case Identifier id:
            {
                var kValue = dc.key.Accept(this);
                var vValue = dc.value.Accept(this);
                return(m.Appl(
                           m.MethodRef(list, "ToDictionary"),
                           m.Lambda(new CodeExpression[] { id.Accept(this) }, kValue),
                           m.Lambda(new CodeExpression[] { id.Accept(this) }, vValue)));
            }

            case PyTuple tuple:
            {
                if (tuple.values.Count != 2)
                {
                    //TODO: tuples, especially nested tuples, are hard.
                    return(m.Prim("!!!{" +
                                  dc.key.Accept(this) +
                                  ": " +
                                  dc.value.Accept(this)));
                }

                var enumvar = gensym.GenSymAutomatic("_de", null, false);
                gensym.PushIdMappings(new Dictionary <string, CodeExpression>
                    {
                        { tuple.values[0].ToString(), m.Access(enumvar, "Key") },
                        { tuple.values[1].ToString(), m.Access(enumvar, "Value") },
                    });

                var kValue = dc.key.Accept(this);
                var vValue = dc.value.Accept(this);

                gensym.PopIdMappings();

                return(m.Appl(
                           m.MethodRef(list, "ToDictionary"),
                           m.Lambda(new CodeExpression[] { enumvar }, kValue),
                           m.Lambda(new CodeExpression[] { enumvar }, vValue)));
            }
            }
            throw new NotImplementedException();
        }
Beispiel #2
0
        public CodeExpression VisitDictComprehension(DictComprehension dc)
        {
            //{ k:copy.copy(v) for k, v in path.info.iteritems() }
            //string sExp = "path.info.iteritems.ToDictionary(k => k, v => copy.copy(v))";

            var list    = dc.source.collection.Accept(this);
            var varList = dc.source.variable as ExpList;

            if (varList != null)
            {
                //if (varList.Expressions.Count != 2)
                //    throw new InvalidOperationException("Variable list should contain one or two variables.");
                var tyArgs        = Enumerable.Range(0, varList.Expressions.Count).Select(e => "object").ToArray();
                var tpl           = gensym.GenSymParameter("_tup_", m.TypeRef("Tuple", tyArgs));
                var anonymousCtor = new CodeObjectCreateExpression
                {
                    Initializer = new CodeObjectInitializer()
                };

                list = m.Appl(
                    m.MethodRef(list, "Select"),
                    m.Lambda(
                        new CodeExpression[] { tpl },
                        new CodeObjectInitializer
                {
                    MemberDeclarators = varList.Expressions.Select((e, i) => new MemberDeclarator
                    {
                        Name       = e.ToString(),
                        Expression = m.Access(tpl, string.Format("Item{0}", i + 1))
                    }).ToList()
                }));

                gensym.PushIdMappings(varList.Expressions.ToDictionary(e => e.ToString(), e => m.Access(tpl, e.ToString())));

                var kValue = dc.key.Accept(this);
                var vValue = dc.value.Accept(this);

                gensym.PopIdMappings();

                return(m.Appl(
                           m.MethodRef(list, "ToDictionary"),
                           m.Lambda(new CodeExpression[] { tpl }, kValue),
                           m.Lambda(new CodeExpression[] { tpl }, vValue)));
            }
            var id = dc.source.variable as Identifier;

            if (id != null)
            {
                var kValue = dc.key.Accept(this);
                var vValue = dc.value.Accept(this);
                return(m.Appl(
                           m.MethodRef(list, "ToDictionary"),
                           m.Lambda(new CodeExpression[] { id.Accept(this) }, kValue),
                           m.Lambda(new CodeExpression[] { id.Accept(this) }, vValue)));
            }
            var tuple = dc.source.variable as PyTuple;

            if (tuple != null)
            {
                //TODO: tuples, especially nested tuples, are hard.
                return(new CodePrimitiveExpression("!!!{" +
                                                   dc.key.Accept(this) +
                                                   ": " +
                                                   dc.value.Accept(this)));
            }

            throw new NotImplementedException();
        }