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.
dict.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__ 0x02 00018 00019 00020 /** 00021 * \file 00022 * \brief Dict Object Type 00023 * 00024 * Dict object type operations. 00025 */ 00026 00027 00028 #include "pm.h" 00029 00030 00031 PmReturn_t 00032 dict_new(pPmObj_t *r_pdict) 00033 { 00034 PmReturn_t retval = PM_RET_OK; 00035 pPmDict_t pdict = C_NULL; 00036 uint8_t *pchunk; 00037 00038 /* Allocate a dict */ 00039 retval = heap_getChunk(sizeof(PmDict_t), &pchunk); 00040 PM_RETURN_IF_ERROR(retval); 00041 00042 /* Init dict fields */ 00043 pdict = (pPmDict_t)pchunk; 00044 OBJ_SET_TYPE(pdict, OBJ_TYPE_DIC); 00045 pdict->length = 0; 00046 pdict->d_keys = C_NULL; 00047 pdict->d_vals = C_NULL; 00048 00049 *r_pdict = (pPmObj_t)pchunk; 00050 return retval; 00051 } 00052 00053 00054 PmReturn_t 00055 dict_clear(pPmObj_t pdict) 00056 { 00057 PmReturn_t retval = PM_RET_OK; 00058 00059 C_ASSERT(pdict != C_NULL); 00060 00061 /* Raise TypeError if arg is not a dict */ 00062 if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) 00063 { 00064 PM_RAISE(retval, PM_RET_EX_TYPE); 00065 return retval; 00066 } 00067 00068 /* clear length */ 00069 ((pPmDict_t)pdict)->length = 0; 00070 00071 /* Free the keys and values seglists if needed */ 00072 if (((pPmDict_t)pdict)->d_keys != C_NULL) 00073 { 00074 PM_RETURN_IF_ERROR(seglist_clear(((pPmDict_t)pdict)->d_keys)); 00075 PM_RETURN_IF_ERROR(heap_freeChunk((pPmObj_t) 00076 ((pPmDict_t)pdict)->d_keys)); 00077 ((pPmDict_t)pdict)->d_keys = C_NULL; 00078 } 00079 if (((pPmDict_t)pdict)->d_vals != C_NULL) 00080 { 00081 PM_RETURN_IF_ERROR(seglist_clear(((pPmDict_t)pdict)->d_vals)); 00082 retval = heap_freeChunk((pPmObj_t)((pPmDict_t)pdict)->d_vals); 00083 ((pPmDict_t)pdict)->d_vals = C_NULL; 00084 } 00085 return retval; 00086 } 00087 00088 00089 /* 00090 * Sets a value in the dict using the given key. 00091 * 00092 * Scans dict for the key. If key val found, replace old 00093 * with new val. If no key found, add key/val pair to dict. 00094 */ 00095 PmReturn_t 00096 dict_setItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t pval) 00097 { 00098 PmReturn_t retval = PM_RET_OK; 00099 int16_t indx; 00100 00101 C_ASSERT(pdict != C_NULL); 00102 C_ASSERT(pkey != C_NULL); 00103 C_ASSERT(pval != C_NULL); 00104 00105 /* If it's not a dict, raise TypeError */ 00106 if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) 00107 { 00108 PM_RAISE(retval, PM_RET_EX_TYPE); 00109 return retval; 00110 } 00111 00112 /* #112: Force Dict keys to be of hashable type */ 00113 /* If key is not hashable, raise TypeError */ 00114 if (OBJ_GET_TYPE(pkey) > OBJ_TYPE_HASHABLE_MAX) 00115 { 00116 PM_RAISE(retval, PM_RET_EX_TYPE); 00117 return retval; 00118 } 00119 00120 /* #147: Change boolean keys to integers */ 00121 if (pkey == PM_TRUE) 00122 { 00123 pkey = PM_ONE; 00124 } 00125 else if (pkey == PM_FALSE) 00126 { 00127 pkey = PM_ZERO; 00128 } 00129 00130 /* 00131 * #115: If this is the first key/value pair to be added to the Dict, 00132 * allocate the key and value seglists that hold those items 00133 */ 00134 if (((pPmDict_t)pdict)->length == 0) 00135 { 00136 retval = seglist_new(&((pPmDict_t)pdict)->d_keys); 00137 PM_RETURN_IF_ERROR(retval); 00138 retval = seglist_new(&((pPmDict_t)pdict)->d_vals); 00139 PM_RETURN_IF_ERROR(retval); 00140 } 00141 else 00142 { 00143 /* Check for matching key */ 00144 indx = 0; 00145 retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx); 00146 00147 /* If found a matching key, replace val obj */ 00148 if (retval == PM_RET_OK) 00149 { 00150 retval = seglist_setItem(((pPmDict_t)pdict)->d_vals, pval, indx); 00151 return retval; 00152 } 00153 } 00154 00155 /* Otherwise, insert the key,val pair */ 00156 retval = seglist_insertItem(((pPmDict_t)pdict)->d_keys, pkey, 0); 00157 PM_RETURN_IF_ERROR(retval); 00158 retval = seglist_insertItem(((pPmDict_t)pdict)->d_vals, pval, 0); 00159 ((pPmDict_t)pdict)->length++; 00160 00161 return retval; 00162 } 00163 00164 00165 PmReturn_t 00166 dict_getItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t *r_pobj) 00167 { 00168 PmReturn_t retval = PM_RET_OK; 00169 int16_t indx = 0; 00170 00171 /* C_ASSERT(pdict != C_NULL);*/ 00172 00173 /* if it's not a dict, raise TypeError */ 00174 if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) 00175 { 00176 PM_RAISE(retval, PM_RET_EX_TYPE); 00177 return retval; 00178 } 00179 00180 /* if dict is empty, raise KeyError */ 00181 if (((pPmDict_t)pdict)->length <= 0) 00182 { 00183 PM_RAISE(retval, PM_RET_EX_KEY); 00184 return retval; 00185 } 00186 00187 /* #147: Change boolean keys to integers */ 00188 if (pkey == PM_TRUE) 00189 { 00190 pkey = PM_ONE; 00191 } 00192 else if (pkey == PM_FALSE) 00193 { 00194 pkey = PM_ZERO; 00195 } 00196 00197 /* check for matching key */ 00198 retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx); 00199 /* if key not found, raise KeyError */ 00200 if (retval == PM_RET_NO) 00201 { 00202 PM_RAISE(retval, PM_RET_EX_KEY); 00203 } 00204 /* return any other error */ 00205 PM_RETURN_IF_ERROR(retval); 00206 00207 /* key was found, get obj from vals */ 00208 retval = seglist_getItem(((pPmDict_t)pdict)->d_vals, indx, r_pobj); 00209 return retval; 00210 } 00211 00212 00213 #ifdef HAVE_DEL 00214 PmReturn_t 00215 dict_delItem(pPmObj_t pdict, pPmObj_t pkey) 00216 { 00217 PmReturn_t retval = PM_RET_OK; 00218 int16_t indx = 0; 00219 00220 C_ASSERT(pdict != C_NULL); 00221 00222 /* Check for matching key */ 00223 retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx); 00224 00225 /* Raise KeyError if key is not found */ 00226 if (retval == PM_RET_NO) 00227 { 00228 PM_RAISE(retval, PM_RET_EX_KEY); 00229 } 00230 00231 /* Return any other error */ 00232 PM_RETURN_IF_ERROR(retval); 00233 00234 /* Remove the key and value */ 00235 retval = seglist_removeItem(((pPmDict_t)pdict)->d_keys, indx); 00236 PM_RETURN_IF_ERROR(retval); 00237 retval = seglist_removeItem(((pPmDict_t)pdict)->d_vals, indx); 00238 00239 /* Reduce the item count */ 00240 ((pPmDict_t)pdict)->length--; 00241 00242 return retval; 00243 } 00244 #endif /* HAVE_DEL */ 00245 00246 00247 #ifdef HAVE_PRINT 00248 PmReturn_t 00249 dict_print(pPmObj_t pdict) 00250 { 00251 PmReturn_t retval = PM_RET_OK; 00252 int16_t index; 00253 pSeglist_t keys, 00254 vals; 00255 pPmObj_t pobj1; 00256 00257 C_ASSERT(pdict != C_NULL); 00258 00259 /* if it's not a dict, raise TypeError */ 00260 if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) 00261 { 00262 PM_RAISE(retval, PM_RET_EX_TYPE); 00263 return retval; 00264 } 00265 00266 plat_putByte('{'); 00267 00268 keys = ((pPmDict_t)pdict)->d_keys; 00269 vals = ((pPmDict_t)pdict)->d_vals; 00270 00271 /* if dict is empty, raise KeyError */ 00272 for (index = 0; index < ((pPmDict_t)pdict)->length; index++) 00273 { 00274 if (index != 0) 00275 { 00276 plat_putByte(','); 00277 plat_putByte(' '); 00278 } 00279 retval = seglist_getItem(keys, index, &pobj1); 00280 PM_RETURN_IF_ERROR(retval); 00281 retval = obj_print(pobj1, 1); 00282 PM_RETURN_IF_ERROR(retval); 00283 00284 plat_putByte(':'); 00285 retval = seglist_getItem(vals, index, &pobj1); 00286 PM_RETURN_IF_ERROR(retval); 00287 retval = obj_print(pobj1, 1); 00288 PM_RETURN_IF_ERROR(retval); 00289 } 00290 00291 return plat_putByte('}'); 00292 } 00293 #endif /* HAVE_PRINT */ 00294 00295 PmReturn_t 00296 dict_update(pPmObj_t pdestdict, pPmObj_t psourcedict) 00297 { 00298 PmReturn_t retval = PM_RET_OK; 00299 int16_t i; 00300 pPmObj_t pkey; 00301 pPmObj_t pval; 00302 00303 C_ASSERT(pdestdict != C_NULL); 00304 C_ASSERT(psourcedict != C_NULL); 00305 00306 /* If it's not a dict, raise TypeError */ 00307 if (OBJ_GET_TYPE(pdestdict) != OBJ_TYPE_DIC) 00308 { 00309 PM_RAISE(retval, PM_RET_EX_TYPE); 00310 return retval; 00311 } 00312 00313 /* If it's not a dict, raise TypeError */ 00314 if (OBJ_GET_TYPE(psourcedict) != OBJ_TYPE_DIC) 00315 { 00316 PM_RAISE(retval, PM_RET_EX_TYPE); 00317 return retval; 00318 } 00319 00320 /* Iterate over the add-on dict */ 00321 for (i = 0; i < ((pPmDict_t)psourcedict)->length; i++) 00322 { 00323 /* Get the key,val from the add-on dict */ 00324 retval = seglist_getItem(((pPmDict_t)psourcedict)->d_keys, i, &pkey); 00325 PM_RETURN_IF_ERROR(retval); 00326 retval = seglist_getItem(((pPmDict_t)psourcedict)->d_vals, i, &pval); 00327 PM_RETURN_IF_ERROR(retval); 00328 00329 /* Set the key,val to the destination dict */ 00330 retval = dict_setItem(pdestdict, pkey, pval); 00331 PM_RETURN_IF_ERROR(retval); 00332 } 00333 00334 return retval; 00335 }
Generated on Tue Jul 12 2022 17:07:01 by
1.7.2