ExpressionInterpreter.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Reflection;
  8. using System.Collections.Specialized;
  9. using System.Linq.Expressions;
  10. namespace System.Linq.jvm
  11. {
  12. class ExpressionInterpreter : ExpressionVisitor
  13. {
  14. LambdaExpression _exp;
  15. object[] _args;
  16. object _value = null;
  17. public object Value
  18. {
  19. get { return _value; }
  20. }
  21. public ExpressionInterpreter(object[] args)
  22. {
  23. _args = args;
  24. }
  25. public void Run(LambdaExpression exp)
  26. {
  27. _exp = exp;
  28. Visit(exp.Body);
  29. }
  30. protected override void Visit(Expression expression)
  31. {
  32. if (expression == null)
  33. {
  34. return;
  35. }
  36. if (expression.NodeType == ExpressionType.Power)
  37. {
  38. VisitBinary((BinaryExpression)expression);
  39. }
  40. else
  41. {
  42. base.Visit(expression);
  43. }
  44. }
  45. private void VisitCoalesce(BinaryExpression binary)
  46. {
  47. Visit(binary.Left);
  48. if (_value == null)
  49. {
  50. Visit(binary.Right);
  51. }
  52. }
  53. private void VisitAndAlso(BinaryExpression binary)
  54. {
  55. object right = null;
  56. object left = null;
  57. Visit(binary.Left);
  58. right = _value;
  59. if (right == null || ((bool)right))
  60. {
  61. Visit(binary.Right);
  62. left = _value;
  63. }
  64. _value = Math.And(right, left);
  65. }
  66. private void VisitOrElse(BinaryExpression binary)
  67. {
  68. object right = null;
  69. object left = null;
  70. Visit(binary.Left);
  71. right = _value;
  72. if (right == null || !((bool)right))
  73. {
  74. Visit(binary.Right);
  75. left = _value;
  76. }
  77. _value = Math.Or(right, left);
  78. }
  79. private void VisitCommonBinary(BinaryExpression binary)
  80. {
  81. try
  82. {
  83. Visit(binary.Left);
  84. object left = _value;
  85. Visit(binary.Right);
  86. object right = _value;
  87. if (binary.Method != null)
  88. {
  89. _value = binary.Method.Invoke(null, new object[] { left, right });
  90. return;
  91. }
  92. TypeCode tc = Type.GetTypeCode(binary.Type);
  93. switch (binary.NodeType)
  94. {
  95. case ExpressionType.ArrayIndex:
  96. _value = ((Array)left).GetValue((int)right);
  97. return;
  98. case ExpressionType.Equal:
  99. _value = left.Equals(right);
  100. return;
  101. case ExpressionType.NotEqual:
  102. _value = !left.Equals(right);
  103. return;
  104. case ExpressionType.LessThan:
  105. _value = (Comparer.Default.Compare(left, right) < 0);
  106. return;
  107. case ExpressionType.LessThanOrEqual:
  108. _value = (Comparer.Default.Compare(left, right) <= 0);
  109. return;
  110. case ExpressionType.GreaterThan:
  111. _value = (Comparer.Default.Compare(left, right) > 0);
  112. return;
  113. case ExpressionType.GreaterThanOrEqual:
  114. _value = (Comparer.Default.Compare(left, right) >= 0);
  115. return;
  116. case ExpressionType.RightShift:
  117. _value = Math.RightShift(left, Convert.ToInt32(right), tc);
  118. return;
  119. case ExpressionType.LeftShift:
  120. _value = Math.LeftShift(left, Convert.ToInt32(right), tc);
  121. return;
  122. default:
  123. _value = Math.Evaluate(left, right, binary.Type, binary.NodeType);
  124. break;
  125. }
  126. }
  127. catch (OverflowException)
  128. {
  129. throw;
  130. }
  131. catch (Exception e)
  132. {
  133. throw new NotImplementedException(
  134. string.Format(
  135. "Interpriter for BinaryExpression with NodeType {0} is not implimented",
  136. binary.NodeType),
  137. e);
  138. }
  139. }
  140. protected override void VisitBinary(BinaryExpression binary)
  141. {
  142. switch (binary.NodeType)
  143. {
  144. case ExpressionType.AndAlso:
  145. VisitAndAlso(binary);
  146. return;
  147. case ExpressionType.OrElse:
  148. VisitOrElse(binary);
  149. return;
  150. case ExpressionType.Coalesce:
  151. VisitCoalesce(binary);
  152. return;
  153. default:
  154. VisitCommonBinary(binary);
  155. break;
  156. }
  157. }
  158. protected override void VisitUnary(UnaryExpression unary)
  159. {
  160. Visit(unary.Operand);
  161. object o = _value;
  162. if (unary.Method != null)
  163. {
  164. _value = unary.Method.Invoke(null, new object[] { o });
  165. return;
  166. }
  167. switch (unary.NodeType)
  168. {
  169. case ExpressionType.TypeAs:
  170. if (!Math.IsType(unary.Type, o))
  171. {
  172. _value = null;
  173. }
  174. return;
  175. case ExpressionType.ArrayLength:
  176. _value = ((Array)o).Length;
  177. return;
  178. case ExpressionType.Negate:
  179. _value = Math.Negete(o, Type.GetTypeCode(unary.Type));
  180. return;
  181. case ExpressionType.NegateChecked:
  182. _value = Math.NegeteChecked(o, Type.GetTypeCode(unary.Type));
  183. return;
  184. case ExpressionType.Not:
  185. _value = ! Convert.ToBoolean(o);
  186. return;
  187. case ExpressionType.UnaryPlus:
  188. _value = o;
  189. return;
  190. case ExpressionType.Convert:
  191. _value = Math.ConvertToTypeUnchecked(o, unary.Type);
  192. return;
  193. case ExpressionType.ConvertChecked:
  194. _value = Math.ConvertToTypeChecked(o, unary.Type);
  195. return;
  196. }
  197. throw new NotImplementedException(
  198. string.Format(
  199. "Interpriter for UnaryExpression with NodeType {0} is not implimented",
  200. unary.NodeType));
  201. }
  202. protected override void VisitNew(NewExpression nex)
  203. {
  204. if (nex.Constructor == null)
  205. {
  206. _value = System.Activator.CreateInstance(nex.Type);
  207. }
  208. else
  209. {
  210. object[] parameters = VisitListExpressions(nex.Arguments);
  211. _value = nex.Constructor.Invoke(parameters);
  212. }
  213. }
  214. protected override void VisitTypeIs(TypeBinaryExpression type)
  215. {
  216. Visit(type.Expression);
  217. _value = Math.IsType(type.TypeOperand, _value);
  218. }
  219. private void VisitMemberInfo(MemberInfo mi)
  220. {
  221. object o = _value;
  222. switch (mi.MemberType)
  223. {
  224. case MemberTypes.Field:
  225. _value = ((FieldInfo)mi).GetValue(o);
  226. return;
  227. case MemberTypes.Property:
  228. _value = ((PropertyInfo)mi).GetValue(o, null);
  229. return;
  230. }
  231. throw new NotImplementedException(
  232. string.Format(
  233. "Interpriter for MemberInfo with MemberType {0} is not implimented",
  234. mi.MemberType));
  235. }
  236. protected override void VisitMemberAccess(MemberExpression member)
  237. {
  238. Visit(member.Expression);
  239. VisitMemberInfo(member.Member);
  240. }
  241. protected override void VisitNewArray(NewArrayExpression newArray)
  242. {
  243. switch (newArray.NodeType)
  244. {
  245. case ExpressionType.NewArrayInit:
  246. VisitNewArrayInit(newArray);
  247. return;
  248. case ExpressionType.NewArrayBounds:
  249. VisitNewArrayBounds(newArray);
  250. return;
  251. }
  252. throw new NotImplementedException(
  253. string.Format(
  254. "Interpriter for VisitNewArray with NodeType {0} is not implimented",
  255. newArray.NodeType));
  256. }
  257. private void VisitNewArrayBounds(NewArrayExpression newArray)
  258. {
  259. int[] lengths = new int[newArray.Expressions.Count];
  260. for (int i = 0; i < lengths.Length; i++)
  261. {
  262. Visit(newArray.Expressions[i]);
  263. lengths[i] = (int)_value;
  264. }
  265. _value = Array.CreateInstance(newArray.Type.GetElementType(), lengths);
  266. }
  267. private void VisitNewArrayInit(NewArrayExpression newArray)
  268. {
  269. Array arr = Array.CreateInstance(
  270. newArray.Type.GetElementType(),
  271. newArray.Expressions.Count);
  272. for (int i = 0; i < arr.Length; i++)
  273. {
  274. Visit(newArray.Expressions[i]);
  275. arr.SetValue(_value, i);
  276. }
  277. _value = arr;
  278. }
  279. protected override void VisitConditional(ConditionalExpression conditional)
  280. {
  281. Visit(conditional.Test);
  282. if ((bool)_value)
  283. {
  284. Visit(conditional.IfTrue);
  285. }
  286. else
  287. {
  288. Visit(conditional.IfFalse);
  289. }
  290. }
  291. protected override void VisitMethodCall(MethodCallExpression call)
  292. {
  293. if (call.Object != null)
  294. {
  295. Visit(call.Object);
  296. }
  297. object callObject = _value;
  298. object[] arguments = VisitListExpressions(call.Arguments);
  299. _value = call.Method.Invoke(callObject, arguments);
  300. }
  301. protected override void VisitParameter(ParameterExpression parameter)
  302. {
  303. for (int i = 0; i < _exp.Parameters.Count; i++)
  304. {
  305. if (_exp.Parameters[i].Name.Equals(parameter.Name))
  306. {
  307. _value = _args[i];
  308. return;
  309. }
  310. }
  311. _value = null;
  312. }
  313. protected override void VisitConstant(ConstantExpression constant)
  314. {
  315. _value = constant.Value;
  316. }
  317. protected override void VisitInvocation(InvocationExpression invocation)
  318. {
  319. Visit(invocation.Expression);
  320. object o = _value;
  321. object[] arguments = VisitListExpressions(invocation.Arguments);
  322. _value = ((Delegate)o).DynamicInvoke(arguments);
  323. }
  324. protected override void VisitMemberListBinding(MemberListBinding binding)
  325. {
  326. object o = _value;
  327. try
  328. {
  329. VisitMemberInfo(binding.Member);
  330. base.VisitMemberListBinding(binding);
  331. }
  332. finally
  333. {
  334. _value = o;
  335. }
  336. }
  337. protected override void VisitElementInitializer(ElementInit initializer)
  338. {
  339. object o = _value;
  340. try
  341. {
  342. object[] arguments =
  343. VisitListExpressions(initializer.Arguments);
  344. initializer.AddMethod.Invoke(o, arguments);
  345. }
  346. finally
  347. {
  348. _value = o;
  349. }
  350. }
  351. protected override void VisitMemberMemberBinding(MemberMemberBinding binding)
  352. {
  353. object o = _value;
  354. try
  355. {
  356. VisitMemberInfo(binding.Member);
  357. base.VisitMemberMemberBinding(binding);
  358. }
  359. finally
  360. {
  361. _value = o;
  362. }
  363. }
  364. protected override void VisitMemberAssignment(MemberAssignment assignment)
  365. {
  366. object o = _value;
  367. try
  368. {
  369. Visit(assignment.Expression);
  370. switch (assignment.Member.MemberType)
  371. {
  372. case MemberTypes.Field:
  373. ((FieldInfo)assignment.Member).SetValue(o, _value);
  374. return;
  375. case MemberTypes.Property:
  376. ((PropertyInfo)assignment.Member).SetValue(o, _value, null);
  377. return;
  378. }
  379. throw new NotImplementedException(
  380. string.Format(
  381. "Interpriter for MemberExpression with MemberType {0} is not implimented",
  382. assignment.Member.MemberType));
  383. }
  384. finally
  385. {
  386. _value = o;
  387. }
  388. }
  389. private object[] VisitListExpressions(ReadOnlyCollection<Expression> collection)
  390. {
  391. object o = _value;
  392. try
  393. {
  394. object[] results = new object[collection.Count];
  395. for (int i = 0; i < results.Length; i++)
  396. {
  397. Visit(collection[i]);
  398. results[i] = _value;
  399. }
  400. return results;
  401. }
  402. finally
  403. {
  404. _value = o;
  405. }
  406. }
  407. }
  408. }