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(); }
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(); }