PageRenderTime 73ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Boo.Lang/Builtins.cs

http://github.com/bamboo/boo
C# | 395 lines | 318 code | 46 blank | 31 comment | 45 complexity | 0c69c3964551546a2cecc727bc079833 MD5 | raw file
Possible License(s): GPL-2.0
  1. #region license
  2. // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without modification,
  6. // are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Rodrigo B. de Oliveira nor the names of its
  14. // contributors may be used to endorse or promote products derived from this
  15. // software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  21. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23. // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  25. // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #endregion
  28. using System;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.IO;
  32. using System.Text;
  33. using System.Reflection;
  34. using Boo.Lang.Runtime;
  35. namespace Boo.Lang
  36. {
  37. /// <summary>
  38. /// boo language builtin functions.
  39. /// </summary>
  40. public class Builtins
  41. {
  42. public class duck
  43. {
  44. }
  45. public static System.Version BooVersion
  46. {
  47. get
  48. {
  49. return new System.Version("0.9.7.0");
  50. }
  51. }
  52. public static void print(object o)
  53. {
  54. Console.WriteLine(o);
  55. }
  56. public static string gets()
  57. {
  58. return Console.ReadLine();
  59. }
  60. public static string prompt(string message)
  61. {
  62. Console.Write(message);
  63. return Console.ReadLine();
  64. }
  65. public static string join(IEnumerable enumerable, string separator)
  66. {
  67. var sb = new StringBuilder();
  68. var enumerator = enumerable.GetEnumerator();
  69. using (enumerator as IDisposable)
  70. {
  71. if (enumerator.MoveNext())
  72. {
  73. sb.Append(enumerator.Current);
  74. while (enumerator.MoveNext())
  75. {
  76. sb.Append(separator);
  77. sb.Append(enumerator.Current);
  78. }
  79. }
  80. }
  81. return sb.ToString();
  82. }
  83. public static string join(IEnumerable enumerable, char separator)
  84. {
  85. return join(enumerable, separator.ToString());
  86. }
  87. public static string join(IEnumerable enumerable)
  88. {
  89. return join(enumerable, " ");
  90. }
  91. public static IEnumerable map(object enumerable, ICallable function)
  92. {
  93. if (null == enumerable) throw new ArgumentNullException("enumerable");
  94. if (null == function) throw new ArgumentNullException("function");
  95. object[] args = new object[1];
  96. foreach (object item in iterator(enumerable))
  97. {
  98. args[0] = item;
  99. yield return function.Call(args);
  100. }
  101. }
  102. public static object[] array(IEnumerable enumerable)
  103. {
  104. return new List(enumerable).ToArray();
  105. }
  106. //fast path, that implementation detail does not really need to be API
  107. private static Array ArrayFromCollection(Type elementType, ICollection collection)
  108. {
  109. if (null == elementType)
  110. throw new ArgumentNullException("elementType");
  111. if (null == collection)
  112. throw new ArgumentNullException("collection");
  113. Array array = Array.CreateInstance(elementType, collection.Count);
  114. if (RuntimeServices.IsPromotableNumeric(Type.GetTypeCode(elementType)))
  115. {
  116. int i=0;
  117. foreach (object item in collection)
  118. {
  119. object value = RuntimeServices.CheckNumericPromotion(item).ToType(elementType, null);
  120. array.SetValue(value, i);
  121. ++i;
  122. }
  123. }
  124. else
  125. {
  126. collection.CopyTo(array, 0);
  127. }
  128. return array;
  129. }
  130. [TypeInferenceRule(TypeInferenceRules.ArrayOfTypeReferencedByFirstArgument)]
  131. public static Array array(Type elementType, IEnumerable enumerable)
  132. {
  133. if (null == elementType)
  134. throw new ArgumentNullException("elementType");
  135. if (null == enumerable)
  136. throw new ArgumentNullException("enumerable");
  137. #pragma warning disable 618 //obsolete
  138. ICollection collection = enumerable as ICollection;
  139. if (null != collection) //fast path
  140. return ArrayFromCollection(elementType, collection);
  141. #pragma warning restore 618
  142. List l = null;
  143. if (RuntimeServices.IsPromotableNumeric(Type.GetTypeCode(elementType)))
  144. {
  145. l = new List();
  146. foreach (object item in enumerable)
  147. {
  148. object value = RuntimeServices.CheckNumericPromotion(item).ToType(elementType, null);
  149. l.Add(value);
  150. }
  151. }
  152. else
  153. {
  154. l = new List(enumerable);
  155. }
  156. return l.ToArray(elementType);
  157. }
  158. [TypeInferenceRule(TypeInferenceRules.ArrayOfTypeReferencedByFirstArgument)]
  159. public static Array array(Type elementType, int length)
  160. {
  161. if (length < 0)
  162. throw new ArgumentException("`length' cannot be negative", "length");
  163. return matrix(elementType, length);
  164. }
  165. public static Array matrix(Type elementType, params int[] lengths)
  166. {
  167. if (null == elementType)
  168. throw new ArgumentNullException("elementType");
  169. if (null == lengths || 0 == lengths.Length)
  170. throw new ArgumentException("A matrix must have at least one dimension", "lengths");
  171. return Array.CreateInstance(elementType, lengths);
  172. }
  173. #region generic array/matrix builtins (v0.9.2+)
  174. public static T[] array<T>(int length)
  175. {
  176. throw new NotSupportedException("Operation should have been optimized away by the compiler!");
  177. }
  178. public static T[,] matrix<T>(int length0, int length1)
  179. {
  180. throw new NotSupportedException("Operation should have been optimized away by the compiler!");
  181. }
  182. public static T[,,] matrix<T>(int length0, int length1, int length2)
  183. {
  184. throw new NotSupportedException("Operation should have been optimized away by the compiler!");
  185. }
  186. public static T[,,,] matrix<T>(int length0, int length1, int length2, int length3)
  187. {
  188. throw new NotSupportedException("Operation should have been optimized away by the compiler!");
  189. }
  190. #endregion
  191. public static IEnumerable iterator(object enumerable)
  192. {
  193. return RuntimeServices.GetEnumerable(enumerable);
  194. }
  195. #if !NO_SYSTEM_PROCESS
  196. public static System.Diagnostics.Process shellp(string filename, string arguments)
  197. {
  198. var p = new System.Diagnostics.Process();
  199. p.StartInfo.Arguments = arguments;
  200. p.StartInfo.CreateNoWindow = true;
  201. p.StartInfo.UseShellExecute = false;
  202. p.StartInfo.RedirectStandardOutput = true;
  203. p.StartInfo.RedirectStandardInput = true;
  204. p.StartInfo.RedirectStandardError = true;
  205. p.StartInfo.FileName = filename;
  206. p.Start();
  207. return p;
  208. }
  209. public static string shell(string filename, string arguments)
  210. {
  211. var p = shellp(filename, arguments);
  212. var output = p.StandardOutput.ReadToEnd();
  213. p.WaitForExit();
  214. return output;
  215. }
  216. #endif
  217. public static IEnumerable<object[]> enumerate(object enumerable)
  218. {
  219. int i = 0;
  220. foreach (object item in iterator(enumerable))
  221. {
  222. yield return new object[] { i++, item };
  223. }
  224. }
  225. public static IEnumerable<int> range(int max)
  226. {
  227. if (max < 0) /* added for coherence with behavior of compiler-optimized
  228. * for-in-range() loops, should compiler loops automatically
  229. * inverse iteration in this case? */
  230. {
  231. throw new ArgumentOutOfRangeException("max < 0");
  232. }
  233. return range(0, max);
  234. }
  235. public static IEnumerable<int> range(int begin, int end)
  236. {
  237. if (begin < end)
  238. {
  239. for (int i = begin; i < end; ++i) yield return i;
  240. }
  241. else if (begin > end)
  242. {
  243. for (int i = begin; i > end; --i) yield return i;
  244. }
  245. }
  246. public static IEnumerable<int> range(int begin, int end, int step)
  247. {
  248. if (0 ==step)
  249. {
  250. throw new ArgumentOutOfRangeException("step == 0");
  251. }
  252. if (step < 0)
  253. {
  254. if (begin < end)
  255. {
  256. throw new ArgumentOutOfRangeException("begin < end && step < 0");
  257. }
  258. for (int i = begin; i > end; i += step) yield return i;
  259. }
  260. else
  261. {
  262. if (begin > end)
  263. {
  264. throw new ArgumentOutOfRangeException("begin > end && step > 0");
  265. }
  266. for (int i = begin; i < end; i += step) yield return i;
  267. }
  268. }
  269. public static IEnumerable reversed(object enumerable)
  270. {
  271. return new List(iterator(enumerable)).Reversed;
  272. }
  273. public static ZipEnumerator zip(params object[] enumerables)
  274. {
  275. IEnumerator[] enumerators = new IEnumerator[enumerables.Length];
  276. for (int i=0; i<enumerables.Length; ++i)
  277. {
  278. enumerators[i] = GetEnumerator(enumerables[i]);
  279. }
  280. return new ZipEnumerator(enumerators);
  281. }
  282. public static IEnumerable<object> cat(params object[] args)
  283. {
  284. foreach (object e in args)
  285. {
  286. foreach (object item in iterator(e))
  287. {
  288. yield return item;
  289. }
  290. }
  291. }
  292. [EnumeratorItemType(typeof(object[]))]
  293. public class ZipEnumerator : IEnumerator, IEnumerable, IDisposable
  294. {
  295. IEnumerator[] _enumerators;
  296. internal ZipEnumerator(params IEnumerator[] enumerators)
  297. {
  298. _enumerators = enumerators;
  299. }
  300. public void Dispose()
  301. {
  302. for (int i=0; i<_enumerators.Length; ++i)
  303. {
  304. IDisposable d = _enumerators[i] as IDisposable;
  305. if (d != null)
  306. d.Dispose();
  307. }
  308. }
  309. public void Reset()
  310. {
  311. for (int i=0; i<_enumerators.Length; ++i)
  312. {
  313. _enumerators[i].Reset();
  314. }
  315. }
  316. public bool MoveNext()
  317. {
  318. for (int i=0; i<_enumerators.Length; ++i)
  319. {
  320. if (!_enumerators[i].MoveNext())
  321. {
  322. return false;
  323. }
  324. }
  325. return true;
  326. }
  327. public object Current
  328. {
  329. get
  330. {
  331. object[] current = new object[_enumerators.Length];
  332. for (int i=0; i<current.Length; ++i)
  333. {
  334. current[i] = _enumerators[i].Current;
  335. }
  336. return current;
  337. }
  338. }
  339. public IEnumerator GetEnumerator()
  340. {
  341. return this;
  342. }
  343. }
  344. private static IEnumerator GetEnumerator(object enumerable)
  345. {
  346. return RuntimeServices.GetEnumerable(enumerable).GetEnumerator();
  347. }
  348. }
  349. }