PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/testing/bene/pymite-05/src/vm/list.c

http://octopususb.googlecode.com/
C | 347 lines | 211 code | 66 blank | 70 comment | 40 complexity | 5442bc2f2ebd26416fbaaa3081e23eb1 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.1, LGPL-2.0, CC-BY-SA-3.0
  1. /*
  2. * PyMite - A flyweight Python interpreter for 8-bit microcontrollers and more.
  3. * Copyright 2002 Dean Hall
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. #undef __FILE_ID__
  20. #define __FILE_ID__ 0x0B
  21. /**
  22. * List Object Type
  23. *
  24. * List object type operations.
  25. *
  26. * Log
  27. * ---
  28. *
  29. * 2007/01/17 #76: Print will differentiate on strings and print tuples
  30. * 2007/01/09 #75: Printing support (P.Adelt)
  31. * 2007/01/09 #75: implemented list_remove() and list_index() (P.Adelt)
  32. * 2006/08/29 #15 - All mem_*() funcs and pointers in the vm should use
  33. * unsigned not signed or void
  34. * 2002/04/22 First.
  35. */
  36. /***************************************************************
  37. * Includes
  38. **************************************************************/
  39. #include "pm.h"
  40. /***************************************************************
  41. * Functions
  42. **************************************************************/
  43. PmReturn_t
  44. list_append(pPmObj_t plist, pPmObj_t pobj)
  45. {
  46. PmReturn_t retval = PM_RET_STUB;
  47. C_ASSERT(plist != C_NULL);
  48. C_ASSERT(pobj != C_NULL);
  49. /* If plist is not a list, raise a TypeError exception */
  50. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  51. {
  52. PM_RAISE(retval, PM_RET_EX_TYPE);
  53. return retval;
  54. }
  55. /* Append object to list */
  56. retval = seglist_appendItem(((pPmList_t)plist)->val, pobj);
  57. PM_RETURN_IF_ERROR(retval);
  58. /* Increment list length */
  59. ((pPmList_t)plist)->length++;
  60. return retval;
  61. }
  62. PmReturn_t
  63. list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj)
  64. {
  65. PmReturn_t retval;
  66. /* If it's not a list, raise TypeError */
  67. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  68. {
  69. PM_RAISE(retval, PM_RET_EX_TYPE);
  70. return retval;
  71. }
  72. /* Adjust the index */
  73. if (index < 0)
  74. {
  75. index += ((pPmList_t)plist)->length;
  76. }
  77. /* Check the bounds of the index */
  78. if ((index < 0) || (index >= ((pPmList_t)plist)->length))
  79. {
  80. PM_RAISE(retval, PM_RET_EX_INDX);
  81. return retval;
  82. }
  83. /* Get item from seglist */
  84. retval = seglist_getItem(((pPmList_t)plist)->val, index, r_pobj);
  85. return retval;
  86. }
  87. PmReturn_t
  88. list_insert(pPmObj_t plist, int16_t index, pPmObj_t pobj)
  89. {
  90. PmReturn_t retval;
  91. int16_t len;
  92. C_ASSERT(plist != C_NULL);
  93. C_ASSERT(pobj != C_NULL);
  94. /* Raise a TypeError if plist is not a List */
  95. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  96. {
  97. retval = PM_RET_EX_TYPE;
  98. PM_RETURN_IF_ERROR(retval);
  99. }
  100. /* Adjust an out-of-bounds index value */
  101. len = ((pPmList_t)plist)->length;
  102. if (index < 0)
  103. {
  104. index += len;
  105. }
  106. if (index < 0)
  107. {
  108. index = 0;
  109. }
  110. if (index > len)
  111. {
  112. index = len;
  113. }
  114. /* Insert the item in the container */
  115. retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, index);
  116. PM_RETURN_IF_ERROR(retval);
  117. /* Increment list length */
  118. ((pPmList_t)plist)->length++;
  119. return retval;
  120. }
  121. PmReturn_t
  122. list_new(pPmObj_t *r_pobj)
  123. {
  124. PmReturn_t retval = PM_RET_OK;
  125. pPmList_t plist = C_NULL;
  126. /* Allocate a list */
  127. retval = heap_getChunk(sizeof(PmList_t), (uint8_t **)r_pobj);
  128. PM_RETURN_IF_ERROR(retval);
  129. /* Set list type, empty the contents */
  130. plist = (pPmList_t)*r_pobj;
  131. OBJ_SET_TYPE(*plist, OBJ_TYPE_LST);
  132. plist->length = 0;
  133. /* Create empty seglist */
  134. retval = seglist_new(&plist->val);
  135. return retval;
  136. }
  137. PmReturn_t
  138. list_copy(pPmObj_t pobj, pPmObj_t *r_pobj)
  139. {
  140. return list_replicate(pobj, 1, r_pobj);
  141. }
  142. PmReturn_t
  143. list_replicate(pPmObj_t psrclist, int16_t n, pPmObj_t *r_pnewlist)
  144. {
  145. PmReturn_t retval = PM_RET_OK;
  146. int16_t i = 0;
  147. int16_t j = 0;
  148. int16_t length = 0;
  149. pPmObj_t pitem = C_NULL;
  150. C_ASSERT(psrclist != C_NULL);
  151. C_ASSERT(r_pnewlist != C_NULL);
  152. /* If first arg is not a list, raise TypeError */
  153. if (OBJ_GET_TYPE(*psrclist) != OBJ_TYPE_LST)
  154. {
  155. PM_RAISE(retval, PM_RET_EX_TYPE);
  156. return retval;
  157. }
  158. length = ((pPmList_t)psrclist)->length;
  159. /* Allocate new list */
  160. retval = list_new(r_pnewlist);
  161. PM_RETURN_IF_ERROR(retval);
  162. /* Copy srclist the designated number of times */
  163. for (i = n; i > 0; i--)
  164. {
  165. /* Iterate over the length of srclist */
  166. for (j = 0; j < length; j++)
  167. {
  168. retval = list_getItem(psrclist, j, &pitem);
  169. PM_RETURN_IF_ERROR(retval);
  170. retval = list_append(*r_pnewlist, pitem);
  171. PM_RETURN_IF_ERROR(retval);
  172. }
  173. }
  174. return retval;
  175. }
  176. PmReturn_t
  177. list_setItem(pPmObj_t plist, int16_t index, pPmObj_t pobj)
  178. {
  179. PmReturn_t retval;
  180. /* If it's not a list, raise TypeError */
  181. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  182. {
  183. PM_RAISE(retval, PM_RET_EX_TYPE);
  184. return retval;
  185. }
  186. /* Adjust the index */
  187. if (index < 0)
  188. {
  189. index += ((pPmList_t)plist)->length;
  190. }
  191. /* Check the bounds of the index */
  192. if ((index < 0) || (index >= ((pPmList_t)plist)->length))
  193. {
  194. PM_RAISE(retval, PM_RET_EX_INDX);
  195. return retval;
  196. }
  197. /* Set the item */
  198. retval = seglist_setItem(((pPmList_t)plist)->val, pobj, index);
  199. return retval;
  200. }
  201. PmReturn_t
  202. list_remove(pPmObj_t plist, pPmObj_t item)
  203. {
  204. PmReturn_t retval = PM_RET_OK;
  205. uint16_t index;
  206. /* If it's not a list, raise TypeError */
  207. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  208. {
  209. PM_RAISE(retval, PM_RET_EX_TYPE);
  210. return retval;
  211. }
  212. /* Locate the item to remove */
  213. retval = list_index(plist, item, &index);
  214. PM_RETURN_IF_ERROR(retval);
  215. /* Remove the item and decrement the list length */
  216. retval = seglist_removeItem(((pPmList_t)plist)->val, index);
  217. ((pPmList_t)plist)->length--;
  218. return retval;
  219. }
  220. PmReturn_t
  221. list_index(pPmObj_t plist, pPmObj_t pitem, uint16_t *r_index)
  222. {
  223. PmReturn_t retval = PM_RET_OK;
  224. pSeglist_t pseglist;
  225. pPmObj_t pobj;
  226. uint16_t index;
  227. /* If it's not a list, raise TypeError */
  228. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  229. {
  230. PM_RAISE(retval, PM_RET_EX_TYPE);
  231. return retval;
  232. }
  233. pseglist = ((pPmList_t)plist)->val;
  234. /* Iterate over the list's contents */
  235. for (index = 0; index < pseglist->sl_length; index++)
  236. {
  237. retval = seglist_getItem(pseglist, index, &pobj);
  238. PM_RETURN_IF_ERROR(retval);
  239. /* If the list item matches the given item, return the index */
  240. if (obj_compare(pobj, pitem) == C_SAME)
  241. {
  242. *r_index = index;
  243. return PM_RET_OK;
  244. }
  245. }
  246. return PM_RET_EX_VAL;
  247. }
  248. #ifdef HAVE_PRINT
  249. PmReturn_t
  250. list_print(pPmObj_t plist)
  251. {
  252. PmReturn_t retval = PM_RET_OK;
  253. int16_t index;
  254. pSeglist_t vals;
  255. pPmObj_t pobj1;
  256. C_ASSERT(plist != C_NULL);
  257. /* If it's not a list, raise TypeError */
  258. if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
  259. {
  260. PM_RAISE(retval, PM_RET_EX_TYPE);
  261. return retval;
  262. }
  263. plat_putByte('[');
  264. vals = ((pPmList_t)plist)->val;
  265. /* Iterate over the list's contents */
  266. for (index = 0; index < ((pPmList_t)plist)->length; index++)
  267. {
  268. if (index != 0)
  269. {
  270. plat_putByte(',');
  271. plat_putByte(' ');
  272. }
  273. /* Print each item */
  274. retval = seglist_getItem(vals, index, &pobj1);
  275. PM_RETURN_IF_ERROR(retval);
  276. retval = obj_print(pobj1, 1);
  277. PM_RETURN_IF_ERROR(retval);
  278. }
  279. return plat_putByte(']');
  280. }
  281. #endif /* HAVE_PRINT */