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

/System.Xronos/Language/RT.cs

https://bitbucket.org/stefanrusek/xronos
C# | 394 lines | 314 code | 57 blank | 23 comment | 61 complexity | e89c1eef69eab9ac5698d8503e17cb5c MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) 2008 Stefan Rusek and Benjamin Pollack
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. *
  23. * ***************************************************************************/
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Linq;
  27. using System.Text;
  28. using System.Collections;
  29. using System.Xronos.Language.Threading;
  30. using Microsoft.Scripting.Actions;
  31. using System.Xronos.Scripting.Binders;
  32. using Microsoft.Runtime.CompilerServices;
  33. using Microsoft.Scripting.Math;
  34. namespace System.Xronos.Language
  35. {
  36. public static class RT
  37. {
  38. public static readonly object[] EmptyArray = new object[0];
  39. public static readonly object True = true;
  40. public static readonly object False = false;
  41. public static readonly Symbol Clojure = Symbol.Create("clojure");
  42. public static readonly Symbol Xronos = Symbol.Create("xronos");
  43. public static readonly Keyword Tag = Keyword.Intern(null, "tag");
  44. public static readonly Keyword Filename = Keyword.Intern(null, "filename");
  45. public static readonly Keyword Line = Keyword.Intern(null, "line");
  46. public static readonly Keyword LineEnd = Keyword.Intern(null, "lineend");
  47. public static readonly Keyword Char = Keyword.Intern(null, "char");
  48. public static readonly Keyword CharEnd = Keyword.Intern(null, "charend");
  49. public static readonly object[] DefaultImports = new object[]{
  50. Symbol.Create("Boolean"), typeof(Boolean),
  51. Symbol.Create("Byte"), typeof(Byte),
  52. Symbol.Create("Character"), typeof(Char),
  53. Symbol.Create("Type"), typeof(Type),
  54. Symbol.Create("Class"), typeof(Type),
  55. Symbol.Create("Compiler"), typeof(Compiler),
  56. Symbol.Create("Double"), typeof(Double),
  57. Symbol.Create("Enum"), typeof(Enum),
  58. Symbol.Create("Float"), typeof(Single),
  59. Symbol.Create("Integer"), typeof(int),
  60. Symbol.Create("Long"), typeof(long),
  61. Symbol.Create("Math"), typeof(Math),
  62. Symbol.Create("Object"), typeof(Object),
  63. Symbol.Create("Short"), typeof(short),
  64. Symbol.Create("String"), typeof(String),
  65. Symbol.Create("StringBuilder"), typeof(StringBuilder),
  66. Symbol.Create("Thread"), typeof(System.Threading.Thread),
  67. Symbol.Create("Throwable"), typeof(Exception),
  68. Symbol.Create("Void"), typeof(void),
  69. Symbol.Create("Cloneable"), typeof(ICloneable),
  70. Symbol.Create("Comparable"), typeof(IComparable),
  71. Symbol.Create("Iterable"), typeof(IEnumerable),
  72. Symbol.Create("ArithmeticException"), typeof(ArithmeticException),
  73. Symbol.Create("ArrayIndexOutOfBoundsException"), typeof(IndexOutOfRangeException),
  74. Symbol.Create("ClassCastException"), typeof(InvalidCastException),
  75. Symbol.Create("ClassNotFoundException"), typeof(TypeLoadException),
  76. Symbol.Create("Exception"), typeof(Exception),
  77. Symbol.Create("IndexOutOfBoundsException"), typeof(IndexOutOfRangeException),
  78. Symbol.Create("InterruptedException"), typeof(System.Threading.ThreadAbortException),
  79. Symbol.Create("NullPointerException"), typeof(NullReferenceException),
  80. Symbol.Create("NumberFormatException"), typeof(FormatException),
  81. Symbol.Create("RuntimeException"), typeof(Exception),
  82. Symbol.Create("SecurityException"), typeof(System.Security.SecurityException),
  83. Symbol.Create("StringIndexOutOfBoundsException"), typeof(IndexOutOfRangeException),
  84. Symbol.Create("TypeNotPresentException"), typeof(TypeLoadException),
  85. Symbol.Create("UnsupportedOperationException"), typeof(NotSupportedException),
  86. Symbol.Create("IllegalAccessError"), typeof(InvalidOperationException),
  87. Symbol.Create("OutOfMemoryError"), typeof(OutOfMemoryException),
  88. Symbol.Create("StackOverflowError"), typeof(StackOverflowException),
  89. Symbol.Create("UnknownError"), typeof(Exception),
  90. Symbol.Create("VerifyError"), typeof(InvalidProgramException)};
  91. public static ISequence Cons(object first, object orest)
  92. {
  93. ISequence rest = seq(orest);
  94. if (rest != null)
  95. return rest.cons(first);
  96. return (ISequence)PersistentList.Empty.cons(first);
  97. }
  98. public static object NewAtom(object value)
  99. {
  100. return new AtomicReference<object>(value);
  101. }
  102. public static ISequence Concat(ISequence seqofseqs)
  103. {
  104. var result = EnumeratorSequence.Create(InternalConcat(seq(seqofseqs)));
  105. if (result == null)
  106. return null;
  107. return result;
  108. }
  109. static IEnumerable InternalConcat(ISequence seq)
  110. {
  111. for (; seq != null; seq = seq.rest())
  112. {
  113. var inner = RT.seq(seq.first());
  114. if (inner != null)
  115. for (; inner != null; inner = inner.rest())
  116. yield return inner.first();
  117. }
  118. }
  119. internal static IPersistentList List(params object[] rest)
  120. {
  121. return ToList(rest);
  122. }
  123. internal static IPersistentList ToList(object[] rest)
  124. {
  125. return PersistentList.Create(rest);
  126. }
  127. public static IPersistentList ToList(ISequence seq)
  128. {
  129. return PersistentList.Create(RT.seq(seq));
  130. }
  131. public static IPersistentVector ToVector(ISequence seq)
  132. {
  133. return PersistentVector.Create(RT.seq(seq));
  134. }
  135. public static IPersistentMap ToMap(ISequence seq)
  136. {
  137. return PersistentArrayMap.Create(RT.seq(seq));
  138. }
  139. public static string Str(object oseq)
  140. {
  141. var sb = new StringBuilder();
  142. for (var seq = RT.seq(oseq); seq != null; seq = seq.rest())
  143. sb.Append(seq.first());
  144. return sb.ToString();
  145. }
  146. internal static IPersistentVector ToVector(object[] rest)
  147. {
  148. return PersistentVector.Create(rest);
  149. }
  150. internal static IPersistentList ListStar(IList list)
  151. {
  152. return PersistentList.Create(list);
  153. }
  154. public static int Count(object obj)
  155. {
  156. var coll = obj as ICollection;
  157. if (coll != null)
  158. return coll.Count;
  159. return CountSequence(obj);
  160. }
  161. internal static int CountSequence(object obj)
  162. {
  163. var sequence = RT.seq(obj);
  164. int c = 0;
  165. while (sequence != null)
  166. {
  167. c++; sequence = sequence.rest();
  168. }
  169. return c;
  170. }
  171. static CallSite<Func<CallSite, object, object, object>> getCallSite = CallSite<Func<CallSite, object, object, object>>.Create(BinderFactory.Call(null, "get_Item", 1));
  172. static object InternalGet(object hash, object key, Func<object> notFound)
  173. {
  174. try
  175. {
  176. return getCallSite.Target.Invoke(getCallSite, hash, key);
  177. }
  178. catch (KeyNotFoundException)
  179. {
  180. return notFound();
  181. }
  182. catch (IndexOutOfRangeException)
  183. {
  184. return notFound();
  185. }
  186. }
  187. public static object Get(object hash, object key)
  188. {
  189. var map = hash as IAssociative;
  190. if (map != null)
  191. return map.valAt(key);
  192. return InternalGet(hash, key, () => null);
  193. }
  194. public static object Get(object hash, object key, object notFound)
  195. {
  196. var map = hash as IAssociative;
  197. if (map != null)
  198. return map.valAt(key, notFound);
  199. return InternalGet(hash, key, () => notFound);
  200. }
  201. public static object first(object o)
  202. {
  203. var s = seq(o);
  204. if (s == null)
  205. return null;
  206. return s.first();
  207. }
  208. public static ISequence rest(object o)
  209. {
  210. var s = seq(o);
  211. if (s == null)
  212. return null;
  213. return s.rest();
  214. }
  215. public static ISequence seq(object o)
  216. {
  217. if (o == null)
  218. return null;
  219. var gen = o as ISequential;
  220. if (gen != null)
  221. return gen.seq();
  222. var result = o as ISequence;
  223. if (result != null)
  224. return result;
  225. var enu = o as IEnumerable;
  226. if (enu != null)
  227. return EnumeratorSequence.Create(enu);
  228. return null;
  229. }
  230. public static object reduce(object fn, object coll)
  231. {
  232. var reduce = coll as IReduce;
  233. if (reduce != null)
  234. return reduce.reduce(fn);
  235. var seq = RT.seq(coll);
  236. if (seq == null)
  237. return FunctionHelper.Invoke<object>(fn);
  238. object result = seq.first();
  239. seq = seq.rest();
  240. do
  241. {
  242. result = FunctionHelper.Invoke<object>(fn, result, seq.first());
  243. seq = seq.rest();
  244. } while (seq != null);
  245. return result;
  246. }
  247. public static object reduce(object fn, object result, object coll)
  248. {
  249. var reduce = coll as IReduce;
  250. if (reduce != null)
  251. return reduce.reduce(fn, result);
  252. var seq = RT.seq(coll);
  253. while (seq != null)
  254. {
  255. result = FunctionHelper.Invoke<object>(fn, result, seq.first());
  256. seq = seq.rest();
  257. }
  258. return result;
  259. }
  260. public static IPersistentMap meta(object o)
  261. {
  262. var xo = o as XronosObject;
  263. if (xo != null)
  264. return xo.meta();
  265. return null;
  266. }
  267. public static object withMeta(object o, object meta)
  268. {
  269. var xo = o as XronosObject;
  270. var im = meta as IPersistentMap;
  271. if (xo != null && im != null)
  272. return xo.withMeta(im);
  273. return o;
  274. }
  275. internal static int CombineHash(int a, int b)
  276. {
  277. return a ^ b;
  278. }
  279. internal static IPersistentMap Map(params object[] args)
  280. {
  281. if (args.Length == 2)
  282. return PersistentArrayMap.Create(args);
  283. return PersistentHashMap.Create(args);
  284. }
  285. public static object NormalizeNumber(object o)
  286. {
  287. var s = Convert.ToDouble(o).ToString();
  288. long l;
  289. if (!long.TryParse(s, out l))
  290. {
  291. var d = double.Parse(s);
  292. if ((float)d == d)
  293. return (float)d;
  294. }
  295. if (short.MinValue <= l && l <= short.MaxValue)
  296. return (short)l;
  297. if (int.MinValue <= l && l <= int.MaxValue)
  298. return (int)l;
  299. return l;
  300. }
  301. public static byte ToByte(object o)
  302. {
  303. return Convert.ToByte(o);
  304. }
  305. public static short ToShort(object o)
  306. {
  307. return Convert.ToInt16(o);
  308. }
  309. public static int ToInt(object o)
  310. {
  311. return Convert.ToInt32(o);
  312. }
  313. public static long ToLong(object o)
  314. {
  315. return Convert.ToInt64(o);
  316. }
  317. public static float ToFloat(object o)
  318. {
  319. return Convert.ToSingle(o);
  320. }
  321. public static double ToDouble(object o)
  322. {
  323. return Convert.ToDouble(o);
  324. }
  325. public static char ToChar(object o)
  326. {
  327. return Convert.ToChar(o);
  328. }
  329. public static bool ToBoolean(object o)
  330. {
  331. if (o == null)
  332. return false;
  333. bool? r = o as bool?;
  334. return !r.HasValue || r.Value != false;
  335. }
  336. }
  337. }