Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
list.c
00001 /* 00002 # This file is Copyright 2003, 2006, 2007, 2009 Dean Hall. 00003 # 00004 # This file is part of the PyMite VM. 00005 # The PyMite VM is free software: you can redistribute it and/or modify 00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2. 00007 # 00008 # The PyMite VM is distributed in the hope that it will be useful, 00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2 00012 # is seen in the file COPYING in this directory. 00013 */ 00014 00015 00016 #undef __FILE_ID__ 00017 #define __FILE_ID__ 0x0B 00018 00019 00020 /** 00021 * \file 00022 * \brief List Object Type 00023 * 00024 * List object type operations. 00025 */ 00026 00027 00028 #include "pm.h" 00029 00030 00031 PmReturn_t 00032 list_append(pPmObj_t plist, pPmObj_t pobj) 00033 { 00034 PmReturn_t retval; 00035 00036 C_ASSERT(plist != C_NULL); 00037 C_ASSERT(pobj != C_NULL); 00038 00039 /* If plist is not a list, raise a TypeError exception */ 00040 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00041 { 00042 PM_RAISE(retval, PM_RET_EX_TYPE); 00043 return retval; 00044 } 00045 00046 /* Append object to list */ 00047 retval = seglist_appendItem(((pPmList_t)plist)->val, pobj); 00048 PM_RETURN_IF_ERROR(retval); 00049 00050 /* Increment list length */ 00051 ((pPmList_t)plist)->length++; 00052 00053 return retval; 00054 } 00055 00056 00057 PmReturn_t 00058 list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj) 00059 { 00060 PmReturn_t retval; 00061 00062 /* If it's not a list, raise TypeError */ 00063 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00064 { 00065 PM_RAISE(retval, PM_RET_EX_TYPE); 00066 return retval; 00067 } 00068 00069 /* Adjust the index */ 00070 if (index < 0) 00071 { 00072 index += ((pPmList_t)plist)->length; 00073 } 00074 00075 /* Check the bounds of the index */ 00076 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00077 { 00078 PM_RAISE(retval, PM_RET_EX_INDX); 00079 return retval; 00080 } 00081 00082 /* Get item from seglist */ 00083 retval = seglist_getItem(((pPmList_t)plist)->val, index, r_pobj); 00084 return retval; 00085 } 00086 00087 00088 PmReturn_t 00089 list_insert(pPmObj_t plist, int16_t index, pPmObj_t pobj) 00090 { 00091 PmReturn_t retval; 00092 int16_t len; 00093 00094 C_ASSERT(plist != C_NULL); 00095 C_ASSERT(pobj != C_NULL); 00096 00097 /* Raise a TypeError if plist is not a List */ 00098 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00099 { 00100 retval = PM_RET_EX_TYPE; 00101 PM_RETURN_IF_ERROR(retval); 00102 } 00103 00104 /* Adjust an out-of-bounds index value */ 00105 len = ((pPmList_t)plist)->length; 00106 if (index < 0) 00107 { 00108 index += len; 00109 } 00110 if (index < 0) 00111 { 00112 index = 0; 00113 } 00114 if (index > len) 00115 { 00116 index = len; 00117 } 00118 00119 /* Insert the item in the container */ 00120 retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, index); 00121 PM_RETURN_IF_ERROR(retval); 00122 00123 /* Increment list length */ 00124 ((pPmList_t)plist)->length++; 00125 return retval; 00126 } 00127 00128 00129 PmReturn_t 00130 list_new(pPmObj_t *r_pobj) 00131 { 00132 PmReturn_t retval = PM_RET_OK; 00133 pPmList_t plist = C_NULL; 00134 00135 /* Allocate a list */ 00136 retval = heap_getChunk(sizeof(PmList_t), (uint8_t **)r_pobj); 00137 PM_RETURN_IF_ERROR(retval); 00138 00139 /* Set list type, empty the contents */ 00140 plist = (pPmList_t)*r_pobj; 00141 OBJ_SET_TYPE(plist, OBJ_TYPE_LST); 00142 plist->length = 0; 00143 00144 /* Create empty seglist */ 00145 retval = seglist_new(&plist->val); 00146 return retval; 00147 } 00148 00149 00150 PmReturn_t 00151 list_copy(pPmObj_t pobj, pPmObj_t *r_pobj) 00152 { 00153 return list_replicate(pobj, 1, r_pobj); 00154 } 00155 00156 00157 PmReturn_t 00158 list_replicate(pPmObj_t psrclist, int16_t n, pPmObj_t *r_pnewlist) 00159 { 00160 PmReturn_t retval = PM_RET_OK; 00161 int16_t i = 0; 00162 int16_t j = 0; 00163 int16_t length = 0; 00164 pPmObj_t pitem = C_NULL; 00165 00166 C_ASSERT(psrclist != C_NULL); 00167 C_ASSERT(r_pnewlist != C_NULL); 00168 00169 /* If first arg is not a list, raise TypeError */ 00170 if (OBJ_GET_TYPE(psrclist) != OBJ_TYPE_LST) 00171 { 00172 PM_RAISE(retval, PM_RET_EX_TYPE); 00173 return retval; 00174 } 00175 length = ((pPmList_t)psrclist)->length; 00176 00177 /* Allocate new list */ 00178 retval = list_new(r_pnewlist); 00179 PM_RETURN_IF_ERROR(retval); 00180 00181 /* Copy srclist the designated number of times */ 00182 for (i = n; i > 0; i--) 00183 { 00184 /* Iterate over the length of srclist */ 00185 for (j = 0; j < length; j++) 00186 { 00187 retval = list_getItem(psrclist, j, &pitem); 00188 PM_RETURN_IF_ERROR(retval); 00189 retval = list_append(*r_pnewlist, pitem); 00190 PM_RETURN_IF_ERROR(retval); 00191 } 00192 } 00193 return retval; 00194 } 00195 00196 00197 PmReturn_t 00198 list_setItem(pPmObj_t plist, int16_t index, pPmObj_t pobj) 00199 { 00200 PmReturn_t retval; 00201 00202 /* If it's not a list, raise TypeError */ 00203 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00204 { 00205 PM_RAISE(retval, PM_RET_EX_TYPE); 00206 return retval; 00207 } 00208 00209 /* Adjust the index */ 00210 if (index < 0) 00211 { 00212 index += ((pPmList_t)plist)->length; 00213 } 00214 00215 /* Check the bounds of the index */ 00216 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00217 { 00218 PM_RAISE(retval, PM_RET_EX_INDX); 00219 return retval; 00220 } 00221 00222 /* Set the item */ 00223 retval = seglist_setItem(((pPmList_t)plist)->val, pobj, index); 00224 return retval; 00225 } 00226 00227 00228 PmReturn_t 00229 list_remove(pPmObj_t plist, pPmObj_t item) 00230 { 00231 PmReturn_t retval = PM_RET_OK; 00232 uint16_t index; 00233 00234 /* If it's not a list, raise TypeError */ 00235 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00236 { 00237 PM_RAISE(retval, PM_RET_EX_TYPE); 00238 return retval; 00239 } 00240 00241 /* Locate the item to remove */ 00242 retval = list_index(plist, item, &index); 00243 PM_RETURN_IF_ERROR(retval); 00244 00245 /* Remove the item and decrement the list length */ 00246 retval = seglist_removeItem(((pPmList_t)plist)->val, index); 00247 ((pPmList_t)plist)->length--; 00248 return retval; 00249 00250 } 00251 00252 00253 PmReturn_t 00254 list_index(pPmObj_t plist, pPmObj_t pitem, uint16_t *r_index) 00255 { 00256 PmReturn_t retval = PM_RET_OK; 00257 pSeglist_t pseglist; 00258 pPmObj_t pobj; 00259 uint16_t index; 00260 00261 /* If it's not a list, raise TypeError */ 00262 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00263 { 00264 PM_RAISE(retval, PM_RET_EX_TYPE); 00265 return retval; 00266 } 00267 00268 pseglist = ((pPmList_t)plist)->val; 00269 00270 /* Iterate over the list's contents */ 00271 for (index = 0; index < pseglist->sl_length; index++) 00272 { 00273 retval = seglist_getItem(pseglist, index, &pobj); 00274 PM_RETURN_IF_ERROR(retval); 00275 00276 /* If the list item matches the given item, return the index */ 00277 if (obj_compare(pobj, pitem) == C_SAME) 00278 { 00279 *r_index = index; 00280 return PM_RET_OK; 00281 } 00282 } 00283 00284 return PM_RET_EX_VAL; 00285 } 00286 00287 00288 PmReturn_t 00289 list_delItem(pPmObj_t plist, int16_t index) 00290 { 00291 PmReturn_t retval = PM_RET_OK; 00292 00293 /* If it's not a list, raise TypeError */ 00294 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00295 { 00296 PM_RAISE(retval, PM_RET_EX_TYPE); 00297 return retval; 00298 } 00299 00300 /* Adjust the index */ 00301 if (index < 0) 00302 { 00303 index += ((pPmList_t)plist)->length; 00304 } 00305 00306 /* Check the bounds of the index */ 00307 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00308 { 00309 PM_RAISE(retval, PM_RET_EX_INDX); 00310 return retval; 00311 } 00312 00313 /* Remove the item and decrement the list length */ 00314 retval = seglist_removeItem(((pPmList_t)plist)->val, index); 00315 ((pPmList_t)plist)->length--; 00316 return retval; 00317 } 00318 00319 00320 #ifdef HAVE_PRINT 00321 PmReturn_t 00322 list_print(pPmObj_t plist) 00323 { 00324 PmReturn_t retval = PM_RET_OK; 00325 int16_t index; 00326 pSeglist_t vals; 00327 pPmObj_t pobj1; 00328 00329 C_ASSERT(plist != C_NULL); 00330 00331 /* If it's not a list, raise TypeError */ 00332 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00333 { 00334 PM_RAISE(retval, PM_RET_EX_TYPE); 00335 return retval; 00336 } 00337 00338 plat_putByte('['); 00339 00340 vals = ((pPmList_t)plist)->val; 00341 00342 /* Iterate over the list's contents */ 00343 for (index = 0; index < ((pPmList_t)plist)->length; index++) 00344 { 00345 if (index != 0) 00346 { 00347 plat_putByte(','); 00348 plat_putByte(' '); 00349 } 00350 00351 /* Print each item */ 00352 retval = seglist_getItem(vals, index, &pobj1); 00353 PM_RETURN_IF_ERROR(retval); 00354 retval = obj_print(pobj1, 1); 00355 PM_RETURN_IF_ERROR(retval); 00356 } 00357 00358 return plat_putByte(']'); 00359 } 00360 #endif /* HAVE_PRINT */ 00361 00362 00363 PmReturn_t 00364 list_clear(pPmObj_t plist) 00365 { 00366 PmReturn_t retval = PM_RET_OK; 00367 00368 C_ASSERT(plist != C_NULL); 00369 00370 /* Raise TypeError if arg is not a dict */ 00371 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00372 { 00373 PM_RAISE(retval, PM_RET_EX_TYPE); 00374 return retval; 00375 } 00376 00377 /* clear length */ 00378 ((pPmList_t)plist)->length = 0; 00379 00380 /* clear the keys and values seglists if needed */ 00381 if (((pPmList_t)plist)->val != C_NULL) 00382 { 00383 retval = seglist_clear(((pPmList_t)plist)->val); 00384 } 00385 return retval; 00386 }
Generated on Tue Jul 12 2022 17:07:01 by
