Beispiel #1
0
        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));
        }
Beispiel #2
0
        /// <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)
                    )

                );
        }