/System.Xronos/Language/FunctionHelper.cs
C# | 61 lines | 54 code | 7 blank | 0 comment | 7 complexity | aaba6ceb9dafe47166df2e7b20401522 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Microsoft.Runtime.CompilerServices;
- using System.Xronos.Scripting.Binders;
- using Microsoft.Linq.Expressions;
-
- namespace System.Xronos.Language
- {
- public static class FunctionHelper
- {
- public static T Invoke<T>(object func, ISequence args)
- {
- var newArgs = new List<object>();
- while (args != null)
- {
- newArgs.Add(args.first());
- args = args.rest();
- }
- return Invoke<T>(func, newArgs.ToArray());
- }
-
- static List<Func<object, object[], object>> cache = new List<Func<object, object[], object>>();
- public static T Invoke<T>(object func, params object[] args)
- {
- var c = args.Length;
- Func<object, object[], object> functor;
- if (cache.Count <= c || (functor = cache[c]) == null)
- {
- while (cache.Count <= c)
- cache.Add(null);
- functor = cache[c] = Build(c);
- }
- return (T)functor(func, args);
- }
-
- private static Func<object, object[], object> Build(int argCount)
- {
- var ps = new ParameterExpression[2];
- ps[0] = Expression.Parameter(typeof(object));
- ps[1] = Expression.Parameter(typeof(object[]));
-
- var args = new List<Expression>();
- args.Add(ps[0]);
- for (int i = 0; i < argCount; i++)
- args.Add(Expression.ArrayIndex(ps[1], Expression.Constant(i)));
-
- var lambda = Expression.Lambda<Func<object, object[], object>>(
- Expression.Dynamic(BinderFactory.CachedInvoke(argCount), typeof(object), args),
- ps);
-
- return lambda.Compile();
- }
-
- public static object ThrowArity(object o)
- {
- throw new ArgumentException("Wrong number of args passed to: " + o.GetType().Name);
- }
- }
- }