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.
Fork of pymite by
list.c
00001 /* 00002 # This file is Copyright 2002 Dean Hall. 00003 # This file is part of the PyMite VM. 00004 # This file is licensed under the MIT License. 00005 # See the LICENSE file for details. 00006 */ 00007 00008 00009 #undef __FILE_ID__ 00010 #define __FILE_ID__ 0x0B 00011 00012 00013 /** 00014 * \file 00015 * \brief List Object Type 00016 * 00017 * List object type operations. 00018 */ 00019 00020 00021 #include "pm.h" 00022 00023 00024 PmReturn_t 00025 list_append(pPmObj_t plist, pPmObj_t pobj) 00026 { 00027 PmReturn_t retval; 00028 uint8_t objid; 00029 00030 C_ASSERT(plist != C_NULL); 00031 C_ASSERT(pobj != C_NULL); 00032 00033 /* If plist is not a list, raise a TypeError exception */ 00034 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00035 { 00036 PM_RAISE(retval, PM_RET_EX_TYPE); 00037 return retval; 00038 } 00039 00040 /* Create new seglist if needed */ 00041 if (((pPmList_t)plist)->length == 0) 00042 { 00043 retval = seglist_new(&((pPmList_t)plist)->val); 00044 PM_RETURN_IF_ERROR(retval); 00045 } 00046 00047 /* Append object to list */ 00048 heap_gcPushTempRoot((pPmObj_t)((pPmList_t)plist)->val, &objid); 00049 retval = seglist_appendItem(((pPmList_t)plist)->val, pobj); 00050 heap_gcPopTempRoot(objid); 00051 PM_RETURN_IF_ERROR(retval); 00052 00053 /* Increment list length */ 00054 ((pPmList_t)plist)->length++; 00055 00056 return retval; 00057 } 00058 00059 00060 PmReturn_t 00061 list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj) 00062 { 00063 PmReturn_t retval; 00064 00065 /* If it's not a list, raise TypeError */ 00066 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00067 { 00068 PM_RAISE(retval, PM_RET_EX_TYPE); 00069 return retval; 00070 } 00071 00072 /* Adjust the index */ 00073 if (index < 0) 00074 { 00075 index += ((pPmList_t)plist)->length; 00076 } 00077 00078 /* Check the bounds of the index */ 00079 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00080 { 00081 PM_RAISE(retval, PM_RET_EX_INDX); 00082 return retval; 00083 } 00084 00085 /* Get item from seglist */ 00086 retval = seglist_getItem(((pPmList_t)plist)->val, index, r_pobj); 00087 return retval; 00088 } 00089 00090 00091 PmReturn_t 00092 list_insert(pPmObj_t plist, int16_t index, pPmObj_t pobj) 00093 { 00094 PmReturn_t retval; 00095 int16_t len; 00096 uint8_t objid; 00097 00098 C_ASSERT(plist != C_NULL); 00099 C_ASSERT(pobj != C_NULL); 00100 00101 /* Raise a TypeError if plist is not a List */ 00102 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00103 { 00104 retval = PM_RET_EX_TYPE; 00105 PM_RETURN_IF_ERROR(retval); 00106 } 00107 00108 /* Adjust an out-of-bounds index value */ 00109 len = ((pPmList_t)plist)->length; 00110 if (index < 0) 00111 { 00112 index += len; 00113 } 00114 if (index < 0) 00115 { 00116 index = 0; 00117 } 00118 if (index > len) 00119 { 00120 index = len; 00121 } 00122 00123 /* Create new seglist if needed */ 00124 if (((pPmList_t)plist)->length == 0) 00125 { 00126 retval = seglist_new(&((pPmList_t)plist)->val); 00127 PM_RETURN_IF_ERROR(retval); 00128 } 00129 00130 /* Insert the item in the container */ 00131 heap_gcPushTempRoot((pPmObj_t)((pPmList_t)plist)->val, &objid); 00132 retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, index); 00133 heap_gcPopTempRoot(objid); 00134 PM_RETURN_IF_ERROR(retval); 00135 00136 /* Increment list length */ 00137 ((pPmList_t)plist)->length++; 00138 return retval; 00139 } 00140 00141 00142 PmReturn_t 00143 list_new(pPmObj_t *r_pobj) 00144 { 00145 PmReturn_t retval = PM_RET_OK; 00146 pPmList_t plist = C_NULL; 00147 00148 /* Allocate a list */ 00149 retval = heap_getChunk(sizeof(PmList_t), (uint8_t **)r_pobj); 00150 PM_RETURN_IF_ERROR(retval); 00151 00152 /* Set list type, empty the contents */ 00153 plist = (pPmList_t)*r_pobj; 00154 OBJ_SET_TYPE(plist, OBJ_TYPE_LST); 00155 plist->length = 0; 00156 plist->val = C_NULL; 00157 00158 return retval; 00159 } 00160 00161 00162 PmReturn_t 00163 list_copy(pPmObj_t pobj, pPmObj_t *r_pobj) 00164 { 00165 return list_replicate(pobj, 1, r_pobj); 00166 } 00167 00168 00169 PmReturn_t 00170 list_replicate(pPmObj_t psrclist, int16_t n, pPmObj_t *r_pnewlist) 00171 { 00172 PmReturn_t retval = PM_RET_OK; 00173 int16_t i = 0; 00174 int16_t j = 0; 00175 int16_t length = 0; 00176 pPmObj_t pitem = C_NULL; 00177 uint8_t objid; 00178 00179 C_ASSERT(psrclist != C_NULL); 00180 C_ASSERT(r_pnewlist != C_NULL); 00181 00182 /* If first arg is not a list, raise TypeError */ 00183 if (OBJ_GET_TYPE(psrclist) != OBJ_TYPE_LST) 00184 { 00185 PM_RAISE(retval, PM_RET_EX_TYPE); 00186 return retval; 00187 } 00188 length = ((pPmList_t)psrclist)->length; 00189 00190 /* Allocate new list */ 00191 retval = list_new(r_pnewlist); 00192 PM_RETURN_IF_ERROR(retval); 00193 00194 /* Copy srclist the designated number of times */ 00195 for (i = n; i > 0; i--) 00196 { 00197 /* Iterate over the length of srclist */ 00198 for (j = 0; j < length; j++) 00199 { 00200 retval = list_getItem(psrclist, j, &pitem); 00201 PM_RETURN_IF_ERROR(retval); 00202 heap_gcPushTempRoot(*r_pnewlist, &objid); 00203 retval = list_append(*r_pnewlist, pitem); 00204 heap_gcPopTempRoot(objid); 00205 PM_RETURN_IF_ERROR(retval); 00206 } 00207 } 00208 return retval; 00209 } 00210 00211 00212 PmReturn_t 00213 list_setItem(pPmObj_t plist, int16_t index, pPmObj_t pobj) 00214 { 00215 PmReturn_t retval; 00216 00217 /* If it's not a list, raise TypeError */ 00218 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00219 { 00220 PM_RAISE(retval, PM_RET_EX_TYPE); 00221 return retval; 00222 } 00223 00224 /* Adjust the index */ 00225 if (index < 0) 00226 { 00227 index += ((pPmList_t)plist)->length; 00228 } 00229 00230 /* Check the bounds of the index */ 00231 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00232 { 00233 PM_RAISE(retval, PM_RET_EX_INDX); 00234 return retval; 00235 } 00236 00237 /* Set the item */ 00238 retval = seglist_setItem(((pPmList_t)plist)->val, pobj, index); 00239 return retval; 00240 } 00241 00242 00243 PmReturn_t 00244 list_remove(pPmObj_t plist, pPmObj_t item) 00245 { 00246 PmReturn_t retval = PM_RET_OK; 00247 uint16_t index; 00248 00249 /* If it's not a list, raise TypeError */ 00250 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00251 { 00252 PM_RAISE(retval, PM_RET_EX_TYPE); 00253 return retval; 00254 } 00255 00256 /* Locate the item to remove */ 00257 retval = list_index(plist, item, &index); 00258 PM_RETURN_IF_ERROR(retval); 00259 00260 /* Remove the item and decrement the list length */ 00261 retval = seglist_removeItem(((pPmList_t)plist)->val, index); 00262 ((pPmList_t)plist)->length--; 00263 00264 /* Unlink seglist if there are no contents */ 00265 if (((pPmList_t)plist)->length == 0) 00266 { 00267 ((pPmList_t)plist)->val = C_NULL; 00268 } 00269 00270 return retval; 00271 } 00272 00273 00274 PmReturn_t 00275 list_index(pPmObj_t plist, pPmObj_t pitem, uint16_t *r_index) 00276 { 00277 PmReturn_t retval = PM_RET_OK; 00278 pSeglist_t pseglist; 00279 pPmObj_t pobj; 00280 uint16_t index; 00281 00282 /* If it's not a list, raise TypeError */ 00283 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00284 { 00285 PM_RAISE(retval, PM_RET_EX_TYPE); 00286 return retval; 00287 } 00288 00289 /* Raise a ValueError if the list is empty */ 00290 if (((pPmList_t)plist)->length == 0) 00291 { 00292 PM_RAISE(retval, PM_RET_EX_VAL); 00293 return retval; 00294 } 00295 00296 pseglist = ((pPmList_t)plist)->val; 00297 00298 /* Iterate over the list's contents */ 00299 for (index = 0; index < pseglist->sl_length; index++) 00300 { 00301 retval = seglist_getItem(pseglist, index, &pobj); 00302 PM_RETURN_IF_ERROR(retval); 00303 00304 /* If the list item matches the given item, return the index */ 00305 if (obj_compare(pobj, pitem) == C_SAME) 00306 { 00307 *r_index = index; 00308 return PM_RET_OK; 00309 } 00310 } 00311 00312 return PM_RET_EX_VAL; 00313 } 00314 00315 00316 PmReturn_t 00317 list_delItem(pPmObj_t plist, int16_t index) 00318 { 00319 PmReturn_t retval = PM_RET_OK; 00320 00321 /* If it's not a list, raise TypeError */ 00322 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00323 { 00324 PM_RAISE(retval, PM_RET_EX_TYPE); 00325 return retval; 00326 } 00327 00328 /* Adjust the index */ 00329 if (index < 0) 00330 { 00331 index += ((pPmList_t)plist)->length; 00332 } 00333 00334 /* Check the bounds of the index */ 00335 if ((index < 0) || (index >= ((pPmList_t)plist)->length)) 00336 { 00337 PM_RAISE(retval, PM_RET_EX_INDX); 00338 return retval; 00339 } 00340 00341 /* Remove the item and decrement the list length */ 00342 retval = seglist_removeItem(((pPmList_t)plist)->val, index); 00343 ((pPmList_t)plist)->length--; 00344 00345 /* Unlink seglist if there are no contents */ 00346 if (((pPmList_t)plist)->length == 0) 00347 { 00348 ((pPmList_t)plist)->val = C_NULL; 00349 } 00350 00351 return retval; 00352 } 00353 00354 00355 #ifdef HAVE_PRINT 00356 PmReturn_t 00357 list_print(pPmObj_t plist) 00358 { 00359 PmReturn_t retval = PM_RET_OK; 00360 int16_t index; 00361 pSeglist_t vals; 00362 pPmObj_t pobj1; 00363 00364 C_ASSERT(plist != C_NULL); 00365 00366 /* If it's not a list, raise TypeError */ 00367 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00368 { 00369 PM_RAISE(retval, PM_RET_EX_TYPE); 00370 return retval; 00371 } 00372 00373 plat_putByte('['); 00374 00375 vals = ((pPmList_t)plist)->val; 00376 00377 /* Iterate over the list's contents */ 00378 for (index = 0; index < ((pPmList_t)plist)->length; index++) 00379 { 00380 if (index != 0) 00381 { 00382 plat_putByte(','); 00383 plat_putByte(' '); 00384 } 00385 00386 /* Print each item */ 00387 retval = seglist_getItem(vals, index, &pobj1); 00388 PM_RETURN_IF_ERROR(retval); 00389 retval = obj_print(pobj1, C_FALSE, C_TRUE); 00390 PM_RETURN_IF_ERROR(retval); 00391 } 00392 00393 return plat_putByte(']'); 00394 } 00395 #endif /* HAVE_PRINT */ 00396 00397 00398 PmReturn_t 00399 list_clear(pPmObj_t plist) 00400 { 00401 PmReturn_t retval = PM_RET_OK; 00402 00403 C_ASSERT(plist != C_NULL); 00404 00405 /* Raise TypeError if arg is not a dict */ 00406 if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST) 00407 { 00408 PM_RAISE(retval, PM_RET_EX_TYPE); 00409 return retval; 00410 } 00411 00412 /* Clear length and unlink seglist */ 00413 ((pPmList_t)plist)->length = 0; 00414 ((pPmList_t)plist)->val = C_NULL; 00415 00416 return retval; 00417 }
Generated on Tue Jul 12 2022 21:25:46 by
1.7.2
