PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/System.Xronos/Language/FunctionHelper.cs

https://bitbucket.org/stefanrusek/xronos
C# | 61 lines | 54 code | 7 blank | 0 comment | 7 complexity | aaba6ceb9dafe47166df2e7b20401522 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Runtime.CompilerServices;
  6. using System.Xronos.Scripting.Binders;
  7. using Microsoft.Linq.Expressions;
  8. namespace System.Xronos.Language
  9. {
  10. public static class FunctionHelper
  11. {
  12. public static T Invoke<T>(object func, ISequence args)
  13. {
  14. var newArgs = new List<object>();
  15. while (args != null)
  16. {
  17. newArgs.Add(args.first());
  18. args = args.rest();
  19. }
  20. return Invoke<T>(func, newArgs.ToArray());
  21. }
  22. static List<Func<object, object[], object>> cache = new List<Func<object, object[], object>>();
  23. public static T Invoke<T>(object func, params object[] args)
  24. {
  25. var c = args.Length;
  26. Func<object, object[], object> functor;
  27. if (cache.Count <= c || (functor = cache[c]) == null)
  28. {
  29. while (cache.Count <= c)
  30. cache.Add(null);
  31. functor = cache[c] = Build(c);
  32. }
  33. return (T)functor(func, args);
  34. }
  35. private static Func<object, object[], object> Build(int argCount)
  36. {
  37. var ps = new ParameterExpression[2];
  38. ps[0] = Expression.Parameter(typeof(object));
  39. ps[1] = Expression.Parameter(typeof(object[]));
  40. var args = new List<Expression>();
  41. args.Add(ps[0]);
  42. for (int i = 0; i < argCount; i++)
  43. args.Add(Expression.ArrayIndex(ps[1], Expression.Constant(i)));
  44. var lambda = Expression.Lambda<Func<object, object[], object>>(
  45. Expression.Dynamic(BinderFactory.CachedInvoke(argCount), typeof(object), args),
  46. ps);
  47. return lambda.Compile();
  48. }
  49. public static object ThrowArity(object o)
  50. {
  51. throw new ArgumentException("Wrong number of args passed to: " + o.GetType().Name);
  52. }
  53. }
  54. }