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