Davi Souza / Mbed 2 deprecated pymite

Dependencies:   TSI mbed

Fork of pymite by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers list.c Source File

list.c

Go to the documentation of this file.
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 }