Embed:
(wiki syntax)
Show/hide line numbers
list.c
Go to the documentation of this file.
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
1.7.2