private ExprParamPair GenDefun(Defun stmt)
            {
                Contract.Requires <ArgumentNullException>(stmt != null);
                Contract.Ensures(Contract.Result <ExprParamPair>() != null);
                var gen = new DefunGen(this);

                return(gen.Generate(stmt));
            }
            // ===== ===== ===== ===== ===== method ===== ===== ===== ===== =====

            public ExprParamPair Generate(Defun stmt)
            {
                Contract.Requires <ArgumentNullException>(stmt != null);
                // prepare
                var funcType    = ExpressionHelper.GetFuncType(stmt.Params.Count);
                var sfxFuncType = typeof(SuffixFunc <>).MakeGenericType(funcType);
                var funcTarget  = Expression.Parameter(sfxFuncType, stmt.Name);
                var ps          = ParamList.FromEnum(stmt.Params.Select(p => Expression.Parameter(typeof(object), p.Name)));

                _parameters = new ParamList(funcTarget, ps);
                // generate block
                var gen   = new BlockGen(this);
                var block = gen.Generate(stmt.Block);
                // crean up
                var lambda     = Expression.Lambda(block, stmt.Name, ParamList.ToEnum(_parameters.Next));
                var ctorInfo   = sfxFuncType.GetConstructor(new[] { funcType, typeof(string[]) });
                var sfxs       = stmt.Params.Select(pair => pair.Suffix).ToArray();
                var createExpr = Expression.New(ctorInfo, lambda, Expression.Constant(sfxs));

                return(new ExprParamPair(Expression.Assign(funcTarget, createExpr), new ParamList(funcTarget, null)));
            }
 private ExprParamPair GenDefun(Defun stmt)
 {
     Contract.Requires<ArgumentNullException>(stmt != null);
     Contract.Ensures(Contract.Result<ExprParamPair>() != null);
     var gen = new DefunGen(this);
     return gen.Generate(stmt);
 }
 // ===== ===== ===== ===== ===== method ===== ===== ===== ===== =====
 public ExprParamPair Generate(Defun stmt)
 {
     Contract.Requires<ArgumentNullException>(stmt != null);
     // prepare
     var funcType = ExpressionHelper.GetFuncType(stmt.Params.Count);
     var sfxFuncType = typeof(SuffixFunc<>).MakeGenericType(funcType);
     var funcTarget = Expression.Parameter(sfxFuncType, stmt.Name);
     var ps = ParamList.FromEnum(stmt.Params.Select(p => Expression.Parameter(typeof(object), p.Name)));
     _parameters = new ParamList(funcTarget, ps);
     // generate block
     var gen = new BlockGen(this);
     var block = gen.Generate(stmt.Block);
     // crean up
     var lambda = Expression.Lambda(block, stmt.Name, ParamList.ToEnum(_parameters.Next));
     var ctorInfo = sfxFuncType.GetConstructor(new[] { funcType, typeof(string[]) });
     var sfxs = stmt.Params.Select(pair => pair.Suffix).ToArray();
     var createExpr = Expression.New(ctorInfo, lambda, Expression.Constant(sfxs));
     return new ExprParamPair(Expression.Assign(funcTarget, createExpr), new ParamList(funcTarget, null));
 }