ExpressionInterpreter.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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. return;
  34. }
  35. if (expression.NodeType == ExpressionType.Power) {
  36. VisitBinary ((BinaryExpression) expression);
  37. }
  38. else {
  39. base.Visit (expression);
  40. }
  41. }
  42. private void VisitCoalesce(BinaryExpression binary)
  43. {
  44. Visit(binary.Left);
  45. if (_value == null)
  46. {
  47. Visit(binary.Right);
  48. }
  49. }
  50. private void VisitAndAlso(BinaryExpression binary)
  51. {
  52. object right = null;
  53. object left = null;
  54. Visit(binary.Left);
  55. right = _value;
  56. if (right == null || ((bool)right))
  57. {
  58. Visit(binary.Right);
  59. left = _value;
  60. }
  61. _value = Math.And(right, left);
  62. }
  63. private void VisitOrElse(BinaryExpression binary)
  64. {
  65. object right = null;
  66. object left = null;
  67. Visit(binary.Left);
  68. right = _value;
  69. if (right == null || !((bool)right))
  70. {
  71. Visit(binary.Right);
  72. left = _value;
  73. }
  74. _value = Math.Or(right, left);
  75. }
  76. private void VisitCommonBinary(BinaryExpression binary)
  77. {
  78. try
  79. {
  80. Visit(binary.Left);
  81. object left = _value;
  82. Visit(binary.Right);
  83. object right = _value;
  84. if (binary.Method != null)
  85. {
  86. _value = binary.Method.Invoke(null, new object[] { left, right });
  87. return;
  88. }
  89. TypeCode tc = Type.GetTypeCode(binary.Type);
  90. switch (binary.NodeType)
  91. {
  92. case ExpressionType.ArrayIndex:
  93. _value = ((Array)left).GetValue((int)right);
  94. return;
  95. case ExpressionType.Equal:
  96. if (typeof(ValueType).IsAssignableFrom(binary.Right.Type))
  97. _value = ValueType.Equals (left, right);
  98. else
  99. _value = (left == 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. if (unary.NodeType == ExpressionType.Quote)
  161. {
  162. _value = unary.Operand;
  163. return;
  164. }
  165. Visit(unary.Operand);
  166. object o = _value;
  167. if (unary.Method != null)
  168. {
  169. _value = unary.Method.Invoke(null, new object[] { o });
  170. return;
  171. }
  172. switch (unary.NodeType)
  173. {
  174. case ExpressionType.TypeAs:
  175. if (o == null || !Math.IsType(unary.Type, o))
  176. {
  177. _value = null;
  178. }
  179. return;
  180. case ExpressionType.ArrayLength:
  181. _value = ((Array)o).Length;
  182. return;
  183. case ExpressionType.Negate:
  184. _value = Math.Negete(o, Type.GetTypeCode(unary.Type));
  185. return;
  186. case ExpressionType.NegateChecked:
  187. _value = Math.NegeteChecked(o, Type.GetTypeCode(unary.Type));
  188. return;
  189. case ExpressionType.Not:
  190. if (unary.Type == typeof(bool))
  191. _value = ! Convert.ToBoolean(o);
  192. else
  193. _value = ~Convert.ToInt32(o);
  194. return;
  195. case ExpressionType.UnaryPlus:
  196. _value = o;
  197. return;
  198. case ExpressionType.Convert:
  199. _value = Math.ConvertToTypeUnchecked (o, unary.Operand.Type, unary.Type);
  200. return;
  201. case ExpressionType.ConvertChecked:
  202. _value = Math.ConvertToTypeChecked(o,unary.Operand.Type, unary.Type);
  203. return;
  204. }
  205. throw new NotImplementedException(
  206. string.Format(
  207. "Interpriter for UnaryExpression with NodeType {0} is not implimented",
  208. unary.NodeType));
  209. }
  210. protected override void VisitNew(NewExpression nex)
  211. {
  212. if (nex.Constructor == null)
  213. {
  214. _value = System.Activator.CreateInstance(nex.Type);
  215. }
  216. else
  217. {
  218. object[] parameters = VisitListExpressions(nex.Arguments);
  219. _value = nex.Constructor.Invoke(parameters);
  220. }
  221. }
  222. protected override void VisitTypeIs(TypeBinaryExpression type)
  223. {
  224. Visit(type.Expression);
  225. _value = Math.IsType(type.TypeOperand, _value);
  226. }
  227. private void VisitMemberInfo(MemberInfo mi)
  228. {
  229. object o = _value;
  230. switch (mi.MemberType)
  231. {
  232. case MemberTypes.Field:
  233. _value = ((FieldInfo)mi).GetValue(o);
  234. return;
  235. case MemberTypes.Property:
  236. _value = ((PropertyInfo)mi).GetValue(o, null);
  237. return;
  238. }
  239. throw new NotImplementedException(
  240. string.Format(
  241. "Interpriter for MemberInfo with MemberType {0} is not implimented",
  242. mi.MemberType));
  243. }
  244. protected override void VisitMemberAccess(MemberExpression member)
  245. {
  246. Visit(member.Expression);
  247. VisitMemberInfo(member.Member);
  248. }
  249. protected override void VisitNewArray(NewArrayExpression newArray)
  250. {
  251. switch (newArray.NodeType)
  252. {
  253. case ExpressionType.NewArrayInit:
  254. VisitNewArrayInit(newArray);
  255. return;
  256. case ExpressionType.NewArrayBounds:
  257. VisitNewArrayBounds(newArray);
  258. return;
  259. }
  260. throw new NotImplementedException(
  261. string.Format(
  262. "Interpriter for VisitNewArray with NodeType {0} is not implimented",
  263. newArray.NodeType));
  264. }
  265. private void VisitNewArrayBounds(NewArrayExpression newArray)
  266. {
  267. int[] lengths = new int[newArray.Expressions.Count];
  268. for (int i = 0; i < lengths.Length; i++)
  269. {
  270. Visit(newArray.Expressions[i]);
  271. lengths[i] = (int)_value;
  272. }
  273. _value = Array.CreateInstance(newArray.Type.GetElementType(), lengths);
  274. }
  275. private void VisitNewArrayInit(NewArrayExpression newArray)
  276. {
  277. Array arr = Array.CreateInstance(
  278. newArray.Type.GetElementType(),
  279. newArray.Expressions.Count);
  280. for (int i = 0; i < arr.Length; i++)
  281. {
  282. Visit(newArray.Expressions[i]);
  283. arr.SetValue(_value, i);
  284. }
  285. _value = arr;
  286. }
  287. protected override void VisitConditional(ConditionalExpression conditional)
  288. {
  289. Visit(conditional.Test);
  290. if ((bool)_value)
  291. {
  292. Visit(conditional.IfTrue);
  293. }
  294. else
  295. {
  296. Visit(conditional.IfFalse);
  297. }
  298. }
  299. protected override void VisitMethodCall(MethodCallExpression call)
  300. {
  301. if (call.Object != null)
  302. {
  303. Visit(call.Object);
  304. }
  305. object callObject = _value;
  306. object[] arguments = VisitListExpressions(call.Arguments);
  307. _value = call.Method.Invoke(callObject, arguments);
  308. }
  309. protected override void VisitParameter(ParameterExpression parameter)
  310. {
  311. for (int i = 0; i < _exp.Parameters.Count; i++)
  312. {
  313. if (_exp.Parameters[i].Name.Equals(parameter.Name))
  314. {
  315. _value = _args[i];
  316. return;
  317. }
  318. }
  319. _value = null;
  320. }
  321. protected override void VisitConstant(ConstantExpression constant)
  322. {
  323. _value = constant.Value;
  324. }
  325. protected override void VisitInvocation(InvocationExpression invocation)
  326. {
  327. Visit(invocation.Expression);
  328. object o = _value;
  329. object[] arguments = VisitListExpressions(invocation.Arguments);
  330. _value = ((Delegate)o).DynamicInvoke(arguments);
  331. }
  332. protected override void VisitMemberListBinding(MemberListBinding binding)
  333. {
  334. object o = _value;
  335. try
  336. {
  337. VisitMemberInfo(binding.Member);
  338. base.VisitMemberListBinding(binding);
  339. }
  340. finally
  341. {
  342. _value = o;
  343. }
  344. }
  345. protected override void VisitElementInitializer(ElementInit initializer)
  346. {
  347. object o = _value;
  348. try
  349. {
  350. object[] arguments =
  351. VisitListExpressions(initializer.Arguments);
  352. initializer.AddMethod.Invoke(o, arguments);
  353. }
  354. finally
  355. {
  356. _value = o;
  357. }
  358. }
  359. protected override void VisitMemberMemberBinding(MemberMemberBinding binding)
  360. {
  361. object o = _value;
  362. try
  363. {
  364. VisitMemberInfo(binding.Member);
  365. base.VisitMemberMemberBinding(binding);
  366. }
  367. finally
  368. {
  369. _value = o;
  370. }
  371. }
  372. protected override void VisitMemberAssignment(MemberAssignment assignment)
  373. {
  374. object o = _value;
  375. try
  376. {
  377. Visit(assignment.Expression);
  378. switch (assignment.Member.MemberType)
  379. {
  380. case MemberTypes.Field:
  381. ((FieldInfo)assignment.Member).SetValue(o, _value);
  382. return;
  383. case MemberTypes.Property:
  384. ((PropertyInfo)assignment.Member).SetValue(o, _value, null);
  385. return;
  386. }
  387. throw new NotImplementedException(
  388. string.Format(
  389. "Interpriter for MemberExpression with MemberType {0} is not implimented",
  390. assignment.Member.MemberType));
  391. }
  392. finally
  393. {
  394. _value = o;
  395. }
  396. }
  397. protected override void VisitLambda (LambdaExpression lambda) {
  398. _value = lambda.Compile ();
  399. }
  400. private object[] VisitListExpressions(ReadOnlyCollection<Expression> collection)
  401. {
  402. object o = _value;
  403. try
  404. {
  405. object[] results = new object[collection.Count];
  406. for (int i = 0; i < results.Length; i++)
  407. {
  408. Visit(collection[i]);
  409. results[i] = _value;
  410. }
  411. return results;
  412. }
  413. finally
  414. {
  415. _value = o;
  416. }
  417. }
  418. }
  419. }