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

/lib/otp.net/Otp/Erlang/List.cs

https://github.com/gebi/jungerl
C# | 341 lines | 177 code | 39 blank | 125 comment | 47 complexity | 2417214292502e88b0a1c48d48f25898 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. /*``The contents of this file are subject to the Erlang Public License,
  2. * Version 1.1, (the "License"); you may not use this file except in
  3. * compliance with the License. You should have received a copy of the
  4. * Erlang Public License along with this software. If not, it can be
  5. * retrieved via the world wide web at http://www.erlang.org/.
  6. *
  7. * Software distributed under the License is distributed on an "AS IS"
  8. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  9. * the License for the specific language governing rights and limitations
  10. * under the License.
  11. *
  12. * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
  13. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
  14. * AB. All Rights Reserved.''
  15. *
  16. * Converted from Java to C# by Vlad Dumitrescu (vlad_Dumitrescu@hotmail.com)
  17. * Contribution: Serge Aleynikov (added pattern matching)
  18. */
  19. namespace Otp.Erlang
  20. {
  21. using System;
  22. /*
  23. * Provides a C# representation of Erlang lists. Lists are created
  24. * from zero or more arbitrary Erlang terms.
  25. *
  26. * <p> The arity of the list is the number of elements it contains.
  27. **/
  28. [Serializable]
  29. public class List:Erlang.Object
  30. {
  31. private Object[] elems = null;
  32. // todo: use a linked structure to make a proper list with append,
  33. // car, cdr etc methods. The current representation is essensially the
  34. // same as for tuples except that empty lists are allowed.
  35. // private Object car = null;
  36. // private Object cdr = null;
  37. // int arity;
  38. /*
  39. * Create an empty list.
  40. **/
  41. public List()
  42. {
  43. this.elems = null; // empty list
  44. }
  45. /*
  46. * Create a list of characters.
  47. *
  48. * @param str the characters from which to create the list.
  49. *
  50. public List(System.String str)
  51. {
  52. this.elems = new Object[] { new Erlang.String(str) };
  53. }
  54. * Create a list containing one element.
  55. *
  56. * @param elem the elememet to make the list from.
  57. *
  58. public List(Object elem)
  59. {
  60. this.elems = new Object[1];
  61. elems[0] = elem;
  62. }
  63. */
  64. /*
  65. * Create a list from an array of arbitrary Erlang terms.
  66. *
  67. * @param elems the array of terms from which to create the list.
  68. * @param count the number of terms to insert.
  69. */
  70. public List(Object[] elems): this(elems, 0, elems.Length)
  71. {
  72. }
  73. /*
  74. * Create a list from an array of arbitrary Erlang terms.
  75. *
  76. * @param elems the array of terms from which to create the list.
  77. * @param start the offset of the first term to insert.
  78. * @param count the number of terms to insert.
  79. */
  80. public List(Object[] elems, int start, int count)
  81. {
  82. if ((elems != null) && (count > 0))
  83. {
  84. this.elems = new Object[count];
  85. Array.Copy(elems, 0, this.elems, start, count);
  86. }
  87. }
  88. /*
  89. * Create a list from an array of arbitrary Erlang terms.
  90. *
  91. * @param elems the array of terms from which to create the list.
  92. **/
  93. public List(params System.Object[] elems)
  94. {
  95. if ((elems != null) && (elems.Length > 0))
  96. {
  97. this.elems = new Object[elems.Length];
  98. for (int i=0; i < elems.Length; i++)
  99. {
  100. System.Object o = elems[i];
  101. if (o is int) this.elems[i] = new Int((int)o);
  102. else if (o is string) this.elems[i] = new String((string)o);
  103. else if (o is float) this.elems[i] = new Double((float)o);
  104. else if (o is double) this.elems[i] = new Double((double)o);
  105. else if (o is Erlang.Object) this.elems[i] = (o as Erlang.Object);
  106. //else if (o is BigInteger) this.elems[i] = (BigInteger)o;
  107. else if (o is uint) this.elems[i] = new UInt((int)o);
  108. else if (o is short) this.elems[i] = new Short((short)o);
  109. else if (o is ushort) this.elems[i] = new UShort((short)o);
  110. else
  111. throw new System.ArgumentException("Unknown type of element[" + i + "]: " + o.GetType().ToString());
  112. }
  113. }
  114. }
  115. /*
  116. * Create a list from a stream containing an list encoded in Erlang
  117. * external format.
  118. *
  119. * @param buf the stream containing the encoded list.
  120. *
  121. * @exception DecodeException if the buffer does not
  122. * contain a valid external representation of an Erlang list.
  123. **/
  124. public List(OtpInputStream buf)
  125. {
  126. this.elems = null;
  127. int arity = buf.read_list_head();
  128. if (arity > 0)
  129. {
  130. this.elems = new Object[arity];
  131. for (int i = 0; i < arity; i++)
  132. {
  133. elems[i] = buf.read_any();
  134. }
  135. /*discard the terminating nil (empty list) */
  136. buf.read_nil();
  137. }
  138. }
  139. /*
  140. * Get the arity of the list.
  141. *
  142. * @return the number of elements contained in the list.
  143. **/
  144. public int arity()
  145. {
  146. return (elems == null) ? 0 : elems.Length;
  147. }
  148. /*
  149. * Get the specified element from the list.
  150. *
  151. * @param i the index of the requested element. List elements are
  152. * numbered as array elements, starting at 0.
  153. *
  154. * @return the requested element, of null if i is not a valid
  155. * element index.
  156. **/
  157. public Object elementAt(int i)
  158. {
  159. if ((i >= arity()) || (i < 0))
  160. return null;
  161. return elems[i];
  162. }
  163. /*
  164. * Get all the elements from the list as an array.
  165. *
  166. * @return an array containing all of the list's elements.
  167. **/
  168. public Object[] elements()
  169. {
  170. if (arity() == 0)
  171. return null;
  172. else
  173. {
  174. Object[] res = new Object[arity()];
  175. Array.Copy(this.elems, 0, res, 0, res.Length);
  176. return res;
  177. }
  178. }
  179. public Object this[int index]
  180. {
  181. get { return elementAt(index); }
  182. set { this.elems[index] = value; }
  183. }
  184. public int Length
  185. {
  186. get { return this.elems.Length; }
  187. }
  188. /*
  189. * Get the string representation of the list.
  190. *
  191. * @return the string representation of the list.
  192. **/
  193. public override System.String ToString()
  194. {
  195. System.Text.StringBuilder s = new System.Text.StringBuilder();
  196. int _arity = arity();
  197. s.Append("[");
  198. for (int i = 0; i < _arity; i++)
  199. {
  200. if (i > 0)
  201. s.Append(",");
  202. s.Append(elems[i].ToString());
  203. }
  204. s.Append("]");
  205. return s.ToString();
  206. }
  207. /*
  208. * Convert this list to the equivalent Erlang external
  209. * representation. Note that this method never encodes lists as
  210. * strings, even when it is possible to do so.
  211. *
  212. * @param buf An output stream to which the encoded list should be
  213. * written.
  214. *
  215. **/
  216. public override void encode(OtpOutputStream buf)
  217. {
  218. int _arity = arity();
  219. if (_arity > 0)
  220. {
  221. buf.write_list_head(_arity);
  222. for (int i = 0; i < _arity; i++)
  223. {
  224. buf.write_any(elems[i]);
  225. }
  226. }
  227. buf.write_nil();
  228. }
  229. /*
  230. * Determine if two lists are equal. Lists are equal if they have
  231. * the same arity and all of the elements are equal.
  232. *
  233. * @param o the list to compare to.
  234. *
  235. * @return true if the lists have the same arity and all the
  236. * elements are equal.
  237. **/
  238. public override bool Equals(System.Object o)
  239. {
  240. if (!(o is List))
  241. return false;
  242. List l = (List) o;
  243. int a = this.arity();
  244. if (a != l.arity())
  245. return false;
  246. for (int i = 0; i < a; i++)
  247. {
  248. if (!this.elems[i].Equals(l.elems[i]))
  249. return false;
  250. // early exit
  251. }
  252. return true;
  253. }
  254. public override int GetHashCode()
  255. {
  256. return 1;
  257. }
  258. public override System.Object clone()
  259. {
  260. List newList = (List) (base.clone());
  261. newList.elems = new Object[elems.Length];
  262. elems.CopyTo(newList.elems, 0);
  263. return newList;
  264. }
  265. public override bool subst(ref Erlang.Object a_term, VarBind binding)
  266. {
  267. System.Collections.Generic.List<Erlang.Object> result =
  268. new System.Collections.Generic.List<Erlang.Object>();
  269. bool changed = false;
  270. foreach (Erlang.Object term in this.elems)
  271. {
  272. Erlang.Object obj = null;
  273. if (term.subst(ref obj, binding))
  274. result.Add(obj);
  275. else
  276. {
  277. changed = true;
  278. result.Add(term);
  279. }
  280. }
  281. if (!changed)
  282. return false;
  283. a_term = new Erlang.List(result.ToArray());
  284. return true;
  285. }
  286. public override bool match(Erlang.Object pattern, VarBind binding)
  287. {
  288. if (pattern is Erlang.Var)
  289. pattern.match(this, binding);
  290. else if (!(pattern is Erlang.List))
  291. return false;
  292. Erlang.List tup = pattern as Erlang.List;
  293. if (arity() != tup.arity())
  294. return false;
  295. for (int i = 0; i < arity(); ++i)
  296. if (!elems[i].match(tup[i], binding))
  297. return false;
  298. return true;
  299. }
  300. }
  301. }