protected override Type ResolveInternal(Context ctx, bool mustReturn) { if (Expressions.Count == 0) { Error(CompilerMessages.TupleNoArgs); } if (Expressions.Count > 8) { Error(CompilerMessages.TupleTooManyArgs); } var types = new List <Type>(); foreach (var curr in Expressions) { var type = curr.Resolve(ctx); ctx.CheckTypedExpression(curr, type); types.Add(type); } _types = types.ToArray(); return(FunctionalHelper.CreateTupleType(_types)); }
/// <summary> /// Creates a pure wrapper for function with 2 and more arguments. /// </summary> private void createPureWrapperMany(MethodEntity wrapper, string pureName) { var args = wrapper.GetArgumentTypes(Context); var fieldName = string.Format(EntityNames.PureMethodCacheNameTemplate, wrapper.Name); var tupleType = FunctionalHelper.CreateTupleType(args); var fieldType = typeof(Dictionary <,>).MakeGenericType(tupleType, wrapper.ReturnType); CreateField(fieldName, fieldType, true); var argGetters = wrapper.Arguments.Select(a => (NodeBase)Expr.Get(a)).ToArray(); var tupleName = "<args>"; wrapper.Body = Expr.Block( ScopeKind.FunctionRoot, // $tmp = new Tuple<...> $arg1 $arg2 ... Expr.Let(tupleName, Expr.New(tupleType, argGetters)), // if ($dict == null) $dict = new Dictionary<$tupleType, $valueType> () Expr.If( Expr.Equal( Expr.GetMember(EntityNames.MainTypeName, fieldName), Expr.Null() ), Expr.Block( Expr.SetMember( EntityNames.MainTypeName, fieldName, Expr.New(fieldType) ) ) ), // if(not $dict.ContainsKey key) $dict.Add ($internal arg) Expr.If( Expr.Not( Expr.Invoke( Expr.GetMember(EntityNames.MainTypeName, fieldName), "ContainsKey", Expr.Get(tupleName) ) ), Expr.Block( Expr.Invoke( Expr.GetMember(EntityNames.MainTypeName, fieldName), "Add", Expr.Get(tupleName), Expr.Invoke(EntityNames.MainTypeName, pureName, argGetters) ) ) ), // $dict[arg] Expr.GetIdx( Expr.GetMember(EntityNames.MainTypeName, fieldName), Expr.Get(tupleName) ) ); }