private CodeVariableReferenceExpression GenSymLocalTuple() { return(gensym.GenSymLocal("_tup_", new CodeTypeReference(typeof(object)))); }
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)); }